bd62bceca0284b233761d22f7e542428d747afbe
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-4.14 / 707-dpaa-ethernet-support-layerscape.patch
1 From 40b001913c4131b7532beacc13c811a9e39f3758 Mon Sep 17 00:00:00 2001
2 From: Biwen Li <biwen.li@nxp.com>
3 Date: Tue, 30 Oct 2018 18:26:08 +0800
4 Subject: [PATCH 13/40] dpaa-ethernet: support layerscape
5 This is an integrated patch of dpaa-ethernet for
6 layerscape
7
8 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
9 Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
10 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
11 Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
14 Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
15 Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
16 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
17 Signed-off-by: Iordache Florinel-R70177 <florinel.iordache@nxp.com>
18 Signed-off-by: Jake Moroni <mail@jakemoroni.com>
19 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
20 Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
21 Signed-off-by: Radu Bulie <radu-andrei.bulie@nxp.com>
22 Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
23 Signed-off-by: Vicentiu Galanopulo <vicentiu.galanopulo@nxp.com>
24 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
25 Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
26 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
27 Signed-off-by: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
28 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
29 Signed-off-by: Biwen Li <biwen.li@nxp.com>
30 ---
31 .../net/ethernet/freescale/dpaa/dpaa_eth.c | 399 +-
32 .../ethernet/freescale/dpaa/dpaa_ethtool.c | 2 +-
33 drivers/net/ethernet/freescale/fman/Kconfig | 1 -
34 drivers/net/ethernet/freescale/fman/Makefile | 12 +-
35 .../net/ethernet/freescale/fman/fman_dtsec.c | 19 +
36 .../net/ethernet/freescale/fman/fman_dtsec.h | 1 +
37 .../net/ethernet/freescale/fman/fman_memac.c | 32 +-
38 .../net/ethernet/freescale/fman/fman_memac.h | 1 +
39 .../net/ethernet/freescale/fman/fman_port.c | 2 +
40 .../net/ethernet/freescale/fman/fman_tgec.c | 33 +-
41 .../net/ethernet/freescale/fman/fman_tgec.h | 1 +
42 drivers/net/ethernet/freescale/fman/mac.c | 149 +-
43 drivers/net/ethernet/freescale/fman/mac.h | 8 +-
44 .../net/ethernet/freescale/sdk_dpaa/Kconfig | 195 +
45 .../net/ethernet/freescale/sdk_dpaa/Makefile | 46 +
46 .../ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++
47 .../ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 +
48 .../freescale/sdk_dpaa/dpaa_debugfs.c | 180 +
49 .../freescale/sdk_dpaa/dpaa_debugfs.h | 43 +
50 .../ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1223 +++
51 .../ethernet/freescale/sdk_dpaa/dpaa_eth.h | 691 ++
52 .../freescale/sdk_dpaa/dpaa_eth_base.c | 205 +
53 .../freescale/sdk_dpaa/dpaa_eth_base.h | 49 +
54 .../freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2099 +++++
55 .../freescale/sdk_dpaa/dpaa_eth_ceetm.h | 241 +
56 .../freescale/sdk_dpaa/dpaa_eth_common.c | 1776 ++++
57 .../freescale/sdk_dpaa/dpaa_eth_common.h | 226 +
58 .../freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 +
59 .../ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1201 +++
60 .../freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +
61 .../freescale/sdk_dpaa/dpaa_eth_trace.h | 144 +
62 .../freescale/sdk_dpaa/dpaa_ethtool.c | 542 ++
63 .../ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 291 +
64 .../net/ethernet/freescale/sdk_dpaa/mac-api.c | 931 ++
65 drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 489 ++
66 drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 135 +
67 .../freescale/sdk_dpaa/offline_port.c | 848 ++
68 .../freescale/sdk_dpaa/offline_port.h | 59 +
69 .../net/ethernet/freescale/sdk_fman/Kconfig | 153 +
70 .../net/ethernet/freescale/sdk_fman/Makefile | 11 +
71 .../sdk_fman/Peripherals/FM/HC/Makefile | 15 +
72 .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 +++
73 .../sdk_fman/Peripherals/FM/MAC/Makefile | 28 +
74 .../sdk_fman/Peripherals/FM/MAC/dtsec.c | 1504 ++++
75 .../sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 +
76 .../Peripherals/FM/MAC/dtsec_mii_acc.c | 97 +
77 .../Peripherals/FM/MAC/dtsec_mii_acc.h | 42 +
78 .../sdk_fman/Peripherals/FM/MAC/fm_mac.c | 674 ++
79 .../sdk_fman/Peripherals/FM/MAC/fm_mac.h | 226 +
80 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 +
81 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 +
82 .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 847 ++
83 .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 165 +
84 .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 532 ++
85 .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 215 +
86 .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 +
87 .../sdk_fman/Peripherals/FM/MAC/memac.c | 1153 +++
88 .../sdk_fman/Peripherals/FM/MAC/memac.h | 110 +
89 .../Peripherals/FM/MAC/memac_mii_acc.c | 78 +
90 .../Peripherals/FM/MAC/memac_mii_acc.h | 73 +
91 .../sdk_fman/Peripherals/FM/MAC/tgec.c | 1017 +++
92 .../sdk_fman/Peripherals/FM/MAC/tgec.h | 151 +
93 .../Peripherals/FM/MAC/tgec_mii_acc.c | 139 +
94 .../Peripherals/FM/MAC/tgec_mii_acc.h | 80 +
95 .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 +
96 .../Peripherals/FM/MACSEC/fm_macsec.c | 237 +
97 .../Peripherals/FM/MACSEC/fm_macsec.h | 203 +
98 .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 +
99 .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++
100 .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++
101 .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 ++
102 .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 +
103 .../sdk_fman/Peripherals/FM/Makefile | 23 +
104 .../sdk_fman/Peripherals/FM/Pcd/Makefile | 26 +
105 .../sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 +
106 .../sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 +++++++++++++++++
107 .../sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 +
108 .../sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++
109 .../sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 +
110 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++
111 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++
112 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 +++++
113 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++
114 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 +
115 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 ++++
116 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 +
117 .../sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 +
118 .../sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 +
119 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++
120 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 +
121 .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 890 ++
122 .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 +
123 .../sdk_fman/Peripherals/FM/Port/Makefile | 15 +
124 .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6436 ++++++++++++++
125 .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++
126 .../Peripherals/FM/Port/fm_port_dsar.h | 494 ++
127 .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++
128 .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1570 ++++
129 .../sdk_fman/Peripherals/FM/Rtc/Makefile | 15 +
130 .../sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++
131 .../sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 +
132 .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 +
133 .../sdk_fman/Peripherals/FM/SP/Makefile | 15 +
134 .../sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++
135 .../sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 +
136 .../sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 +
137 .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++
138 .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++
139 .../sdk_fman/Peripherals/FM/fm_ipc.h | 465 +
140 .../sdk_fman/Peripherals/FM/fm_muram.c | 174 +
141 .../freescale/sdk_fman/Peripherals/FM/fman.c | 1400 +++
142 .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 +++
143 .../sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 +
144 .../Peripherals/FM/inc/fm_sp_common.h | 117 +
145 .../ethernet/freescale/sdk_fman/etc/Makefile | 12 +
146 .../ethernet/freescale/sdk_fman/etc/error.c | 95 +
147 .../ethernet/freescale/sdk_fman/etc/list.c | 71 +
148 .../ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++
149 .../net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++
150 .../net/ethernet/freescale/sdk_fman/etc/mm.h | 105 +
151 .../ethernet/freescale/sdk_fman/etc/sprint.c | 81 +
152 .../freescale/sdk_fman/fmanv3h_dflags.h | 57 +
153 .../freescale/sdk_fman/fmanv3l_dflags.h | 56 +
154 .../inc/Peripherals/crc_mac_addr_ext.h | 364 +
155 .../sdk_fman/inc/Peripherals/dpaa_ext.h | 210 +
156 .../sdk_fman/inc/Peripherals/fm_ext.h | 1731 ++++
157 .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 887 ++
158 .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 +++
159 .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 +
160 .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 +++++++++
161 .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 ++++++
162 .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++
163 .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 +
164 .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 +
165 .../freescale/sdk_fman/inc/core_ext.h | 90 +
166 .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 +
167 .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++
168 .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 +
169 .../freescale/sdk_fman/inc/ddr_std_ext.h | 77 +
170 .../freescale/sdk_fman/inc/debug_ext.h | 233 +
171 .../freescale/sdk_fman/inc/endian_ext.h | 447 +
172 .../freescale/sdk_fman/inc/enet_ext.h | 205 +
173 .../freescale/sdk_fman/inc/error_ext.h | 529 ++
174 .../freescale/sdk_fman/inc/etc/list_ext.h | 358 +
175 .../freescale/sdk_fman/inc/etc/mem_ext.h | 318 +
176 .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 +
177 .../freescale/sdk_fman/inc/etc/mm_ext.h | 310 +
178 .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 +
179 .../inc/flib/common/arch/ppc_access.h | 37 +
180 .../sdk_fman/inc/flib/common/general.h | 52 +
181 .../freescale/sdk_fman/inc/flib/fman_common.h | 78 +
182 .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 +
183 .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 ++
184 .../sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++
185 .../inc/flib/fsl_fman_dtsec_mii_acc.h | 107 +
186 .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++
187 .../sdk_fman/inc/flib/fsl_fman_memac.h | 434 +
188 .../inc/flib/fsl_fman_memac_mii_acc.h | 78 +
189 .../sdk_fman/inc/flib/fsl_fman_port.h | 593 ++
190 .../sdk_fman/inc/flib/fsl_fman_prs.h | 102 +
191 .../sdk_fman/inc/flib/fsl_fman_rtc.h | 449 +
192 .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 +
193 .../sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++
194 .../FMANV3H/dpaa_integration_ext.h | 291 +
195 .../inc/integrations/FMANV3H/part_ext.h | 71 +
196 .../FMANV3H/part_integration_ext.h | 304 +
197 .../FMANV3L/dpaa_integration_ext.h | 293 +
198 .../inc/integrations/FMANV3L/part_ext.h | 59 +
199 .../FMANV3L/part_integration_ext.h | 304 +
200 .../LS1043/dpaa_integration_ext.h | 291 +
201 .../inc/integrations/LS1043/part_ext.h | 64 +
202 .../LS1043/part_integration_ext.h | 185 +
203 .../integrations/P1023/dpaa_integration_ext.h | 213 +
204 .../inc/integrations/P1023/part_ext.h | 82 +
205 .../integrations/P1023/part_integration_ext.h | 635 ++
206 .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 +
207 .../integrations/P3040_P4080_P5020/part_ext.h | 83 +
208 .../P3040_P4080_P5020/part_integration_ext.h | 336 +
209 .../freescale/sdk_fman/inc/math_ext.h | 100 +
210 .../freescale/sdk_fman/inc/ncsw_ext.h | 435 +
211 .../ethernet/freescale/sdk_fman/inc/net_ext.h | 430 +
212 .../ethernet/freescale/sdk_fman/inc/std_ext.h | 48 +
213 .../freescale/sdk_fman/inc/stdarg_ext.h | 49 +
214 .../freescale/sdk_fman/inc/stdlib_ext.h | 162 +
215 .../freescale/sdk_fman/inc/string_ext.h | 56 +
216 .../freescale/sdk_fman/inc/types_ext.h | 62 +
217 .../freescale/sdk_fman/inc/xx_common.h | 56 +
218 .../ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++
219 .../freescale/sdk_fman/ls1043_dflags.h | 56 +
220 .../freescale/sdk_fman/ncsw_config.mk | 53 +
221 .../freescale/sdk_fman/p1023_dflags.h | 65 +
222 .../sdk_fman/p3040_4080_5020_dflags.h | 62 +
223 .../ethernet/freescale/sdk_fman/src/Makefile | 11 +
224 .../sdk_fman/src/inc/system/sys_ext.h | 118 +
225 .../sdk_fman/src/inc/system/sys_io_ext.h | 46 +
226 .../freescale/sdk_fman/src/inc/types_linux.h | 208 +
227 .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 +
228 .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 130 +
229 .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 +
230 .../src/inc/wrapper/lnxwrp_fsl_fman.h | 921 ++
231 .../freescale/sdk_fman/src/inc/xx/xx.h | 50 +
232 .../freescale/sdk_fman/src/system/Makefile | 10 +
233 .../freescale/sdk_fman/src/system/sys_io.c | 171 +
234 .../freescale/sdk_fman/src/wrapper/Makefile | 19 +
235 .../sdk_fman/src/wrapper/fman_test.c | 1665 ++++
236 .../sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 +++++++
237 .../sdk_fman/src/wrapper/lnxwrp_fm.h | 294 +
238 .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1512 ++++
239 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4854 +++++++++++
240 .../src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 +++
241 .../src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++
242 .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 +
243 .../src/wrapper/lnxwrp_resources_ut.c | 191 +
244 .../src/wrapper/lnxwrp_resources_ut.h | 144 +
245 .../src/wrapper/lnxwrp_resources_ut.make | 28 +
246 .../sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 +
247 .../sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 +
248 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 ++++
249 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 +
250 .../src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 +++
251 .../src/wrapper/lnxwrp_sysfs_fm_port.h | 56 +
252 .../freescale/sdk_fman/src/xx/Makefile | 18 +
253 .../sdk_fman/src/xx/module_strings.c | 46 +
254 .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 ++
255 .../freescale/sdk_fman/src/xx/xx_linux.c | 918 ++
256 drivers/staging/fsl_qbman/Kconfig | 228 +
257 drivers/staging/fsl_qbman/Makefile | 28 +
258 drivers/staging/fsl_qbman/bman_config.c | 720 ++
259 drivers/staging/fsl_qbman/bman_debugfs.c | 119 +
260 drivers/staging/fsl_qbman/bman_driver.c | 559 ++
261 drivers/staging/fsl_qbman/bman_high.c | 1145 +++
262 drivers/staging/fsl_qbman/bman_low.h | 565 ++
263 drivers/staging/fsl_qbman/bman_private.h | 166 +
264 drivers/staging/fsl_qbman/bman_test.c | 56 +
265 drivers/staging/fsl_qbman/bman_test.h | 44 +
266 drivers/staging/fsl_qbman/bman_test_high.c | 183 +
267 drivers/staging/fsl_qbman/bman_test_thresh.c | 196 +
268 drivers/staging/fsl_qbman/dpa_alloc.c | 706 ++
269 drivers/staging/fsl_qbman/dpa_sys.h | 259 +
270 drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 +
271 drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 +
272 drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 +
273 drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 +
274 drivers/staging/fsl_qbman/fsl_usdpaa.c | 2008 +++++
275 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 +
276 drivers/staging/fsl_qbman/qbman_driver.c | 88 +
277 drivers/staging/fsl_qbman/qman_config.c | 1224 +++
278 drivers/staging/fsl_qbman/qman_debugfs.c | 1594 ++++
279 drivers/staging/fsl_qbman/qman_driver.c | 961 +++
280 drivers/staging/fsl_qbman/qman_high.c | 5652 ++++++++++++
281 drivers/staging/fsl_qbman/qman_low.h | 1445 ++++
282 drivers/staging/fsl_qbman/qman_private.h | 398 +
283 drivers/staging/fsl_qbman/qman_test.c | 57 +
284 drivers/staging/fsl_qbman/qman_test.h | 45 +
285 drivers/staging/fsl_qbman/qman_test_high.c | 216 +
286 .../staging/fsl_qbman/qman_test_hotpotato.c | 502 ++
287 drivers/staging/fsl_qbman/qman_utility.c | 129 +
288 include/linux/fsl/svr.h | 97 +
289 include/linux/fsl_bman.h | 532 ++
290 include/linux/fsl_qman.h | 3900 +++++++++
291 include/linux/fsl_usdpaa.h | 372 +
292 include/linux/netdev_features.h | 2 +
293 include/uapi/linux/fmd/Kbuild | 5 +
294 include/uapi/linux/fmd/Peripherals/Kbuild | 4 +
295 .../uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++
296 .../linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 +++++++
297 .../linux/fmd/Peripherals/fm_port_ioctls.h | 973 +++
298 .../linux/fmd/Peripherals/fm_test_ioctls.h | 208 +
299 include/uapi/linux/fmd/integrations/Kbuild | 1 +
300 .../fmd/integrations/integration_ioctls.h | 56 +
301 include/uapi/linux/fmd/ioctls.h | 96 +
302 include/uapi/linux/fmd/net_ioctls.h | 430 +
303 net/sched/sch_generic.c | 7 +
304 273 files changed, 153944 insertions(+), 229 deletions(-)
305 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
306 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile
307 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
308 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
309 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
310 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
311 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
312 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
313 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
314 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
315 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
316 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
317 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
318 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
319 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
320 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
321 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
322 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
323 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
324 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
325 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
326 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c
327 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h
328 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
329 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
330 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig
331 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile
332 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
333 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
334 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
335 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
336 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
337 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
338 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
339 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
340 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
341 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
342 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
343 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
344 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
345 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
346 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
347 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
348 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
349 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
350 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
351 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
352 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
353 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
354 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
355 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
356 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
357 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
358 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
359 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
360 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
361 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
362 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
363 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
364 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
365 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
366 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
367 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
368 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
369 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
370 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
371 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
372 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
373 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
374 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
375 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
376 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
377 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
378 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
379 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
380 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
381 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
382 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
383 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
384 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
385 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
386 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
387 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
388 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
389 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
390 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
391 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
392 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
393 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
394 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
395 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
396 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
397 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
398 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
399 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
400 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
401 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
402 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
403 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
404 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
405 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
406 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
407 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c
408 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c
409 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
410 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
411 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
412 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
413 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
414 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
415 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
416 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
417 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
418 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
419 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
420 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
421 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
422 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
423 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
424 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
425 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
426 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
427 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
428 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
429 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
430 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
431 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
432 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
433 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
434 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
435 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
436 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
437 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
438 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
439 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
440 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
441 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
442 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
443 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
444 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
445 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
446 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
447 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
448 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
449 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
450 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
451 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
452 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
453 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
454 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
455 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
456 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
457 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
458 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
459 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
460 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
461 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
462 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
463 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
464 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
465 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
466 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
467 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
468 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
469 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
470 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
471 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
472 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
473 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
474 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
475 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
476 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
477 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
478 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
479 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
480 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
481 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
482 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
483 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
484 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile
485 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
486 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
487 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
488 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
489 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
490 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
491 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
492 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
493 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
494 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
495 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
496 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
497 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
498 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
499 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
500 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
501 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
502 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
503 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
504 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
505 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
506 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
507 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
508 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
509 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
510 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
511 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
512 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
513 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
514 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
515 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
516 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
517 create mode 100644 drivers/staging/fsl_qbman/Kconfig
518 create mode 100644 drivers/staging/fsl_qbman/Makefile
519 create mode 100644 drivers/staging/fsl_qbman/bman_config.c
520 create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c
521 create mode 100644 drivers/staging/fsl_qbman/bman_driver.c
522 create mode 100644 drivers/staging/fsl_qbman/bman_high.c
523 create mode 100644 drivers/staging/fsl_qbman/bman_low.h
524 create mode 100644 drivers/staging/fsl_qbman/bman_private.h
525 create mode 100644 drivers/staging/fsl_qbman/bman_test.c
526 create mode 100644 drivers/staging/fsl_qbman/bman_test.h
527 create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c
528 create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c
529 create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c
530 create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h
531 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h
532 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h
533 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h
534 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h
535 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c
536 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
537 create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c
538 create mode 100644 drivers/staging/fsl_qbman/qman_config.c
539 create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c
540 create mode 100644 drivers/staging/fsl_qbman/qman_driver.c
541 create mode 100644 drivers/staging/fsl_qbman/qman_high.c
542 create mode 100644 drivers/staging/fsl_qbman/qman_low.h
543 create mode 100644 drivers/staging/fsl_qbman/qman_private.h
544 create mode 100644 drivers/staging/fsl_qbman/qman_test.c
545 create mode 100644 drivers/staging/fsl_qbman/qman_test.h
546 create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c
547 create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c
548 create mode 100644 drivers/staging/fsl_qbman/qman_utility.c
549 create mode 100644 include/linux/fsl/svr.h
550 create mode 100644 include/linux/fsl_bman.h
551 create mode 100644 include/linux/fsl_qman.h
552 create mode 100644 include/linux/fsl_usdpaa.h
553 create mode 100644 include/uapi/linux/fmd/Kbuild
554 create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild
555 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h
556 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
557 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
558 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
559 create mode 100644 include/uapi/linux/fmd/integrations/Kbuild
560 create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h
561 create mode 100644 include/uapi/linux/fmd/ioctls.h
562 create mode 100644 include/uapi/linux/fmd/net_ioctls.h
563
564 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
565 +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
566 @@ -53,6 +53,9 @@
567 #include <linux/sort.h>
568 #include <soc/fsl/bman.h>
569 #include <soc/fsl/qman.h>
570 +#if !defined(CONFIG_PPC) && defined(CONFIG_SOC_BUS)
571 +#include <linux/sys_soc.h> /* soc_device_match */
572 +#endif
573
574 #include "fman.h"
575 #include "fman_port.h"
576 @@ -73,6 +76,10 @@ static u16 tx_timeout = 1000;
577 module_param(tx_timeout, ushort, 0444);
578 MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
579
580 +#ifndef CONFIG_PPC
581 +bool dpaa_errata_a010022;
582 +#endif
583 +
584 #define FM_FD_STAT_RX_ERRORS \
585 (FM_FD_ERR_DMA | FM_FD_ERR_PHYSICAL | \
586 FM_FD_ERR_SIZE | FM_FD_ERR_CLS_DISCARD | \
587 @@ -388,34 +395,19 @@ out:
588
589 static struct mac_device *dpaa_mac_dev_get(struct platform_device *pdev)
590 {
591 - struct platform_device *of_dev;
592 struct dpaa_eth_data *eth_data;
593 - struct device *dpaa_dev, *dev;
594 - struct device_node *mac_node;
595 + struct device *dpaa_dev;
596 struct mac_device *mac_dev;
597
598 dpaa_dev = &pdev->dev;
599 eth_data = dpaa_dev->platform_data;
600 - if (!eth_data)
601 + if (!eth_data) {
602 + dev_err(dpaa_dev, "eth_data missing\n");
603 return ERR_PTR(-ENODEV);
604 -
605 - mac_node = eth_data->mac_node;
606 -
607 - of_dev = of_find_device_by_node(mac_node);
608 - if (!of_dev) {
609 - dev_err(dpaa_dev, "of_find_device_by_node(%pOF) failed\n",
610 - mac_node);
611 - of_node_put(mac_node);
612 - return ERR_PTR(-EINVAL);
613 }
614 - of_node_put(mac_node);
615 -
616 - dev = &of_dev->dev;
617 -
618 - mac_dev = dev_get_drvdata(dev);
619 + mac_dev = eth_data->mac_dev;
620 if (!mac_dev) {
621 - dev_err(dpaa_dev, "dev_get_drvdata(%s) failed\n",
622 - dev_name(dev));
623 + dev_err(dpaa_dev, "mac_dev missing\n");
624 return ERR_PTR(-EINVAL);
625 }
626
627 @@ -472,6 +464,16 @@ static void dpaa_set_rx_mode(struct net_
628 err);
629 }
630
631 + if (!!(net_dev->flags & IFF_ALLMULTI) != priv->mac_dev->allmulti) {
632 + priv->mac_dev->allmulti = !priv->mac_dev->allmulti;
633 + err = priv->mac_dev->set_allmulti(priv->mac_dev->fman_mac,
634 + priv->mac_dev->allmulti);
635 + if (err < 0)
636 + netif_err(priv, drv, net_dev,
637 + "mac_dev->set_allmulti() = %d\n",
638 + err);
639 + }
640 +
641 err = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
642 if (err < 0)
643 netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n",
644 @@ -1500,7 +1502,19 @@ static int dpaa_bp_add_8_bufs(const stru
645 u8 i;
646
647 for (i = 0; i < 8; i++) {
648 +#ifndef CONFIG_PPC
649 + if (dpaa_errata_a010022) {
650 + struct page *page = alloc_page(GFP_KERNEL);
651 +
652 + if (unlikely(!page))
653 + goto release_previous_buffs;
654 + new_buf = page_address(page);
655 + } else {
656 + new_buf = netdev_alloc_frag(dpaa_bp->raw_size);
657 + }
658 +#else
659 new_buf = netdev_alloc_frag(dpaa_bp->raw_size);
660 +#endif
661 if (unlikely(!new_buf)) {
662 dev_err(dev, "netdev_alloc_frag() failed, size %zu\n",
663 dpaa_bp->raw_size);
664 @@ -1645,9 +1659,13 @@ static struct sk_buff *dpaa_cleanup_tx_f
665 dma_unmap_page(dev, qm_sg_addr(&sgt[i]),
666 qm_sg_entry_get_len(&sgt[i]), dma_dir);
667 }
668 -
669 - /* Free the page frag that we allocated on Tx */
670 - skb_free_frag(phys_to_virt(addr));
671 +#ifndef CONFIG_PPC
672 + if (dpaa_errata_a010022)
673 + put_page(virt_to_page(sgt));
674 + else
675 +#endif
676 + /* Free the page frag that we allocated on Tx */
677 + skb_free_frag(phys_to_virt(addr));
678 } else {
679 dma_unmap_single(dev, addr,
680 skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
681 @@ -1739,6 +1757,7 @@ static struct sk_buff *sg_fd_to_skb(cons
682
683 /* Iterate through the SGT entries and add data buffers to the skb */
684 sgt = vaddr + fd_off;
685 + skb = NULL;
686 for (i = 0; i < DPAA_SGT_MAX_ENTRIES; i++) {
687 /* Extension bit is not supported */
688 WARN_ON(qm_sg_entry_is_ext(&sgt[i]));
689 @@ -1756,7 +1775,7 @@ static struct sk_buff *sg_fd_to_skb(cons
690 count_ptr = this_cpu_ptr(dpaa_bp->percpu_count);
691 dma_unmap_single(dpaa_bp->dev, sg_addr, dpaa_bp->size,
692 DMA_FROM_DEVICE);
693 - if (i == 0) {
694 + if (!skb) {
695 sz = dpaa_bp->size +
696 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
697 skb = build_skb(sg_vaddr, sz);
698 @@ -1909,16 +1928,28 @@ static int skb_to_sg_fd(struct dpaa_priv
699 size_t frag_len;
700 void *sgt_buf;
701
702 - /* get a page frag to store the SGTable */
703 - sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE);
704 - sgt_buf = netdev_alloc_frag(sz);
705 - if (unlikely(!sgt_buf)) {
706 - netdev_err(net_dev, "netdev_alloc_frag() failed for size %d\n",
707 - sz);
708 - return -ENOMEM;
709 +#ifndef CONFIG_PPC
710 + if (unlikely(dpaa_errata_a010022)) {
711 + struct page *page = alloc_page(GFP_ATOMIC);
712 + if (unlikely(!page))
713 + return -ENOMEM;
714 + sgt_buf = page_address(page);
715 + } else {
716 +#endif
717 + /* get a page frag to store the SGTable */
718 + sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE);
719 + sgt_buf = netdev_alloc_frag(sz);
720 + if (unlikely(!sgt_buf)) {
721 + netdev_err(net_dev,
722 + "netdev_alloc_frag() failed for size %d\n",
723 + sz);
724 + return -ENOMEM;
725 + }
726 +#ifndef CONFIG_PPC
727 }
728 +#endif
729
730 - /* Enable L3/L4 hardware checksum computation.
731 + /* Enable L3/L4 hardware checksum computation.
732 *
733 * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
734 * need to write into the skb.
735 @@ -2036,6 +2067,122 @@ static inline int dpaa_xmit(struct dpaa_
736 return 0;
737 }
738
739 +#ifndef CONFIG_PPC
740 +/* On LS1043A SoC there is a known erratum ERR010022 that results in split DMA
741 + * transfers in the FMan under certain conditions. This, combined with a fixed
742 + * size FIFO of ongoing DMA transfers that may overflow when a split occurs,
743 + * results in the FMan stalling DMA transfers under high traffic. To avoid the
744 + * problem, one needs to prevent the DMA transfer splits to occur by preparing
745 + * the buffers
746 + */
747 +
748 +#define DPAA_A010022_HEADROOM 256
749 +#define CROSS_4K_BOUND(start, size) \
750 + (((start) + (size)) > (((start) + 0x1000) & ~0xFFF))
751 +
752 +static bool dpaa_errata_a010022_has_dma_issue(struct sk_buff *skb,
753 + struct dpaa_priv *priv)
754 +{
755 + int nr_frags, i = 0;
756 + skb_frag_t *frag;
757 +
758 + /* Transfers that do not start at 16B aligned addresses will be split;
759 + * Transfers that cross a 4K page boundary will also be split
760 + */
761 +
762 + /* Check if the frame data is aligned to 16 bytes */
763 + if ((uintptr_t)skb->data % DPAA_FD_DATA_ALIGNMENT)
764 + return true;
765 +
766 + /* Check if the headroom crosses a boundary */
767 + if (CROSS_4K_BOUND((uintptr_t)skb->head, skb_headroom(skb)))
768 + return true;
769 +
770 + /* Check if the non-paged data crosses a boundary */
771 + if (CROSS_4K_BOUND((uintptr_t)skb->data, skb_headlen(skb)))
772 + return true;
773 +
774 + nr_frags = skb_shinfo(skb)->nr_frags;
775 +
776 + while (i < nr_frags) {
777 + frag = &skb_shinfo(skb)->frags[i];
778 +
779 + /* Check if a paged fragment crosses a boundary from its
780 + * offset to its end.
781 + */
782 + if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->size))
783 + return true;
784 +
785 + i++;
786 + }
787 +
788 + return false;
789 +}
790 +
791 +static struct sk_buff *dpaa_errata_a010022_prevent(struct sk_buff *skb,
792 + struct dpaa_priv *priv)
793 +{
794 + int trans_offset = skb_transport_offset(skb);
795 + int net_offset = skb_network_offset(skb);
796 + int nsize, npage_order, headroom;
797 + struct sk_buff *nskb = NULL;
798 + struct page *npage;
799 + void *npage_addr;
800 +
801 + if (!dpaa_errata_a010022_has_dma_issue(skb, priv))
802 + return skb;
803 +
804 + /* For the new skb we only need the old one's data (both non-paged and
805 + * paged). We can skip the old tailroom.
806 + *
807 + * The headroom also needs to fit our private info (64 bytes) but we
808 + * reserve 256 bytes instead in order to guarantee that the data is
809 + * aligned to 256.
810 + */
811 + headroom = DPAA_A010022_HEADROOM;
812 + nsize = headroom + skb->len +
813 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
814 +
815 + /* Reserve enough memory to accommodate Jumbo frames */
816 + npage_order = (nsize - 1) / PAGE_SIZE;
817 + npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order);
818 + if (unlikely(!npage)) {
819 + WARN_ONCE(1, "Memory allocation failure\n");
820 + return NULL;
821 + }
822 + npage_addr = page_address(npage);
823 +
824 + nskb = build_skb(npage_addr, nsize);
825 + if (unlikely(!nskb))
826 + goto err;
827 +
828 + /* Code borrowed and adapted from skb_copy() */
829 + skb_reserve(nskb, headroom);
830 + skb_put(nskb, skb->len);
831 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
832 + WARN_ONCE(1, "skb parsing failure\n");
833 + goto err;
834 + }
835 + copy_skb_header(nskb, skb);
836 +
837 + /* We move the headroom when we align it so we have to reset the
838 + * network and transport header offsets relative to the new data
839 + * pointer. The checksum offload relies on these offsets.
840 + */
841 + skb_set_network_header(nskb, net_offset);
842 + skb_set_transport_header(nskb, trans_offset);
843 +
844 + dev_kfree_skb(skb);
845 + return nskb;
846 +
847 +err:
848 + if (nskb)
849 + dev_kfree_skb(nskb);
850 + put_page(npage);
851 + return NULL;
852 +}
853 +#endif
854 +
855 static int dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
856 {
857 const int queue_mapping = skb_get_queue_mapping(skb);
858 @@ -2069,19 +2216,32 @@ static int dpaa_start_xmit(struct sk_buf
859 /* MAX_SKB_FRAGS is equal or larger than our dpaa_SGT_MAX_ENTRIES;
860 * make sure we don't feed FMan with more fragments than it supports.
861 */
862 - if (nonlinear &&
863 - likely(skb_shinfo(skb)->nr_frags < DPAA_SGT_MAX_ENTRIES)) {
864 - /* Just create a S/G fd based on the skb */
865 - err = skb_to_sg_fd(priv, skb, &fd);
866 - percpu_priv->tx_frag_skbuffs++;
867 - } else {
868 + if (unlikely(nonlinear &&
869 + (skb_shinfo(skb)->nr_frags >= DPAA_SGT_MAX_ENTRIES))) {
870 /* If the egress skb contains more fragments than we support
871 * we have no choice but to linearize it ourselves.
872 */
873 - if (unlikely(nonlinear) && __skb_linearize(skb))
874 + if (__skb_linearize(skb))
875 + goto enomem;
876 +
877 + nonlinear = skb_is_nonlinear(skb);
878 + }
879 +
880 +#ifndef CONFIG_PPC
881 + if (unlikely(dpaa_errata_a010022)) {
882 + skb = dpaa_errata_a010022_prevent(skb, priv);
883 + if (!skb)
884 goto enomem;
885 + nonlinear = skb_is_nonlinear(skb);
886 + }
887 +#endif
888
889 - /* Finally, create a contig FD from this skb */
890 + if (nonlinear) {
891 + /* Just create a S/G fd based on the skb */
892 + err = skb_to_sg_fd(priv, skb, &fd);
893 + percpu_priv->tx_frag_skbuffs++;
894 + } else {
895 + /* Create a contig FD from this skb */
896 err = skb_to_contig_fd(priv, skb, &fd, &offset);
897 }
898 if (unlikely(err < 0))
899 @@ -2218,14 +2378,8 @@ static enum qman_cb_dqrr_result rx_error
900 if (dpaa_eth_napi_schedule(percpu_priv, portal))
901 return qman_cb_dqrr_stop;
902
903 - if (dpaa_eth_refill_bpools(priv))
904 - /* Unable to refill the buffer pool due to insufficient
905 - * system memory. Just release the frame back into the pool,
906 - * otherwise we'll soon end up with an empty buffer pool.
907 - */
908 - dpaa_fd_release(net_dev, &dq->fd);
909 - else
910 - dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
911 + dpaa_eth_refill_bpools(priv);
912 + dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
913
914 return qman_cb_dqrr_consume;
915 }
916 @@ -2439,6 +2593,44 @@ static void dpaa_eth_napi_disable(struct
917 }
918 }
919
920 +static void dpaa_adjust_link(struct net_device *net_dev)
921 +{
922 + struct mac_device *mac_dev;
923 + struct dpaa_priv *priv;
924 +
925 + priv = netdev_priv(net_dev);
926 + mac_dev = priv->mac_dev;
927 + mac_dev->adjust_link(mac_dev);
928 +}
929 +
930 +static int dpaa_phy_init(struct net_device *net_dev)
931 +{
932 + struct mac_device *mac_dev;
933 + struct phy_device *phy_dev;
934 + struct dpaa_priv *priv;
935 +
936 + priv = netdev_priv(net_dev);
937 + mac_dev = priv->mac_dev;
938 +
939 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
940 + &dpaa_adjust_link, 0,
941 + mac_dev->phy_if);
942 + if (!phy_dev) {
943 + netif_err(priv, ifup, net_dev, "init_phy() failed\n");
944 + return -ENODEV;
945 + }
946 +
947 + /* Remove any features not supported by the controller */
948 + phy_dev->supported &= mac_dev->if_support;
949 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
950 + phy_dev->advertising = phy_dev->supported;
951 +
952 + mac_dev->phy_dev = phy_dev;
953 + net_dev->phydev = phy_dev;
954 +
955 + return 0;
956 +}
957 +
958 static int dpaa_open(struct net_device *net_dev)
959 {
960 struct mac_device *mac_dev;
961 @@ -2449,12 +2641,9 @@ static int dpaa_open(struct net_device *
962 mac_dev = priv->mac_dev;
963 dpaa_eth_napi_enable(priv);
964
965 - net_dev->phydev = mac_dev->init_phy(net_dev, priv->mac_dev);
966 - if (!net_dev->phydev) {
967 - netif_err(priv, ifup, net_dev, "init_phy() failed\n");
968 - err = -ENODEV;
969 + err = dpaa_phy_init(net_dev);
970 + if (err)
971 goto phy_init_failed;
972 - }
973
974 for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
975 err = fman_port_enable(mac_dev->port[i]);
976 @@ -2653,7 +2842,6 @@ static inline u16 dpaa_get_headroom(stru
977 static int dpaa_eth_probe(struct platform_device *pdev)
978 {
979 struct dpaa_bp *dpaa_bps[DPAA_BPS_NUM] = {NULL};
980 - struct dpaa_percpu_priv *percpu_priv;
981 struct net_device *net_dev = NULL;
982 struct dpaa_fq *dpaa_fq, *tmp;
983 struct dpaa_priv *priv = NULL;
984 @@ -2662,7 +2850,13 @@ static int dpaa_eth_probe(struct platfor
985 int err = 0, i, channel;
986 struct device *dev;
987
988 - dev = &pdev->dev;
989 + /* device used for DMA mapping */
990 + dev = pdev->dev.parent;
991 + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
992 + if (err) {
993 + dev_err(dev, "dma_coerce_mask_and_coherent() failed\n");
994 + return err;
995 + }
996
997 /* Allocate this early, so we can store relevant information in
998 * the private area
999 @@ -2670,7 +2864,7 @@ static int dpaa_eth_probe(struct platfor
1000 net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TXQ_NUM);
1001 if (!net_dev) {
1002 dev_err(dev, "alloc_etherdev_mq() failed\n");
1003 - goto alloc_etherdev_mq_failed;
1004 + return -ENOMEM;
1005 }
1006
1007 /* Do this here, so we can be verbose early */
1008 @@ -2686,7 +2880,7 @@ static int dpaa_eth_probe(struct platfor
1009 if (IS_ERR(mac_dev)) {
1010 dev_err(dev, "dpaa_mac_dev_get() failed\n");
1011 err = PTR_ERR(mac_dev);
1012 - goto mac_probe_failed;
1013 + goto free_netdev;
1014 }
1015
1016 /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
1017 @@ -2704,21 +2898,13 @@ static int dpaa_eth_probe(struct platfor
1018 priv->buf_layout[RX].priv_data_size = DPAA_RX_PRIV_DATA_SIZE; /* Rx */
1019 priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */
1020
1021 - /* device used for DMA mapping */
1022 - set_dma_ops(dev, get_dma_ops(&pdev->dev));
1023 - err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
1024 - if (err) {
1025 - dev_err(dev, "dma_coerce_mask_and_coherent() failed\n");
1026 - goto dev_mask_failed;
1027 - }
1028 -
1029 /* bp init */
1030 for (i = 0; i < DPAA_BPS_NUM; i++) {
1031 - int err;
1032 -
1033 dpaa_bps[i] = dpaa_bp_alloc(dev);
1034 - if (IS_ERR(dpaa_bps[i]))
1035 - return PTR_ERR(dpaa_bps[i]);
1036 + if (IS_ERR(dpaa_bps[i])) {
1037 + err = PTR_ERR(dpaa_bps[i]);
1038 + goto free_dpaa_bps;
1039 + }
1040 /* the raw size of the buffers used for reception */
1041 dpaa_bps[i]->raw_size = bpool_buffer_raw_size(i, DPAA_BPS_NUM);
1042 /* avoid runtime computations by keeping the usable size here */
1043 @@ -2726,11 +2912,8 @@ static int dpaa_eth_probe(struct platfor
1044 dpaa_bps[i]->dev = dev;
1045
1046 err = dpaa_bp_alloc_pool(dpaa_bps[i]);
1047 - if (err < 0) {
1048 - dpaa_bps_free(priv);
1049 - priv->dpaa_bps[i] = NULL;
1050 - goto bp_create_failed;
1051 - }
1052 + if (err < 0)
1053 + goto free_dpaa_bps;
1054 priv->dpaa_bps[i] = dpaa_bps[i];
1055 }
1056
1057 @@ -2741,7 +2924,7 @@ static int dpaa_eth_probe(struct platfor
1058 err = dpaa_alloc_all_fqs(dev, &priv->dpaa_fq_list, &port_fqs);
1059 if (err < 0) {
1060 dev_err(dev, "dpaa_alloc_all_fqs() failed\n");
1061 - goto fq_probe_failed;
1062 + goto free_dpaa_bps;
1063 }
1064
1065 priv->mac_dev = mac_dev;
1066 @@ -2750,12 +2933,12 @@ static int dpaa_eth_probe(struct platfor
1067 if (channel < 0) {
1068 dev_err(dev, "dpaa_get_channel() failed\n");
1069 err = channel;
1070 - goto get_channel_failed;
1071 + goto free_dpaa_bps;
1072 }
1073
1074 priv->channel = (u16)channel;
1075
1076 - /* Start a thread that will walk the CPUs with affine portals
1077 + /* Walk the CPUs with affine portals
1078 * and add this pool channel to each's dequeue mask.
1079 */
1080 dpaa_eth_add_channel(priv->channel);
1081 @@ -2770,20 +2953,20 @@ static int dpaa_eth_probe(struct platfor
1082 err = dpaa_eth_cgr_init(priv);
1083 if (err < 0) {
1084 dev_err(dev, "Error initializing CGR\n");
1085 - goto tx_cgr_init_failed;
1086 + goto free_dpaa_bps;
1087 }
1088
1089 err = dpaa_ingress_cgr_init(priv);
1090 if (err < 0) {
1091 dev_err(dev, "Error initializing ingress CGR\n");
1092 - goto rx_cgr_init_failed;
1093 + goto delete_egress_cgr;
1094 }
1095
1096 /* Add the FQs to the interface, and make them active */
1097 list_for_each_entry_safe(dpaa_fq, tmp, &priv->dpaa_fq_list, list) {
1098 err = dpaa_fq_init(dpaa_fq, false);
1099 if (err < 0)
1100 - goto fq_alloc_failed;
1101 + goto free_dpaa_fqs;
1102 }
1103
1104 priv->tx_headroom = dpaa_get_headroom(&priv->buf_layout[TX]);
1105 @@ -2793,7 +2976,7 @@ static int dpaa_eth_probe(struct platfor
1106 err = dpaa_eth_init_ports(mac_dev, dpaa_bps, DPAA_BPS_NUM, &port_fqs,
1107 &priv->buf_layout[0], dev);
1108 if (err)
1109 - goto init_ports_failed;
1110 + goto free_dpaa_fqs;
1111
1112 /* Rx traffic distribution based on keygen hashing defaults to on */
1113 priv->keygen_in_use = true;
1114 @@ -2802,11 +2985,7 @@ static int dpaa_eth_probe(struct platfor
1115 if (!priv->percpu_priv) {
1116 dev_err(dev, "devm_alloc_percpu() failed\n");
1117 err = -ENOMEM;
1118 - goto alloc_percpu_failed;
1119 - }
1120 - for_each_possible_cpu(i) {
1121 - percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
1122 - memset(percpu_priv, 0, sizeof(*percpu_priv));
1123 + goto free_dpaa_fqs;
1124 }
1125
1126 priv->num_tc = 1;
1127 @@ -2815,11 +2994,11 @@ static int dpaa_eth_probe(struct platfor
1128 /* Initialize NAPI */
1129 err = dpaa_napi_add(net_dev);
1130 if (err < 0)
1131 - goto napi_add_failed;
1132 + goto delete_dpaa_napi;
1133
1134 err = dpaa_netdev_init(net_dev, &dpaa_ops, tx_timeout);
1135 if (err < 0)
1136 - goto netdev_init_failed;
1137 + goto delete_dpaa_napi;
1138
1139 dpaa_eth_sysfs_init(&net_dev->dev);
1140
1141 @@ -2828,32 +3007,21 @@ static int dpaa_eth_probe(struct platfor
1142
1143 return 0;
1144
1145 -netdev_init_failed:
1146 -napi_add_failed:
1147 +delete_dpaa_napi:
1148 dpaa_napi_del(net_dev);
1149 -alloc_percpu_failed:
1150 -init_ports_failed:
1151 +free_dpaa_fqs:
1152 dpaa_fq_free(dev, &priv->dpaa_fq_list);
1153 -fq_alloc_failed:
1154 qman_delete_cgr_safe(&priv->ingress_cgr);
1155 qman_release_cgrid(priv->ingress_cgr.cgrid);
1156 -rx_cgr_init_failed:
1157 +delete_egress_cgr:
1158 qman_delete_cgr_safe(&priv->cgr_data.cgr);
1159 qman_release_cgrid(priv->cgr_data.cgr.cgrid);
1160 -tx_cgr_init_failed:
1161 -get_channel_failed:
1162 +free_dpaa_bps:
1163 dpaa_bps_free(priv);
1164 -bp_create_failed:
1165 -fq_probe_failed:
1166 -dev_mask_failed:
1167 -mac_probe_failed:
1168 +free_netdev:
1169 dev_set_drvdata(dev, NULL);
1170 free_netdev(net_dev);
1171 -alloc_etherdev_mq_failed:
1172 - for (i = 0; i < DPAA_BPS_NUM && dpaa_bps[i]; i++) {
1173 - if (atomic_read(&dpaa_bps[i]->refs) == 0)
1174 - devm_kfree(dev, dpaa_bps[i]);
1175 - }
1176 +
1177 return err;
1178 }
1179
1180 @@ -2890,6 +3058,23 @@ static int dpaa_remove(struct platform_d
1181 return err;
1182 }
1183
1184 +#ifndef CONFIG_PPC
1185 +static bool __init soc_has_errata_a010022(void)
1186 +{
1187 +#ifdef CONFIG_SOC_BUS
1188 + const struct soc_device_attribute soc_msi_matches[] = {
1189 + { .family = "QorIQ LS1043A",
1190 + .data = NULL },
1191 + { },
1192 + };
1193 +
1194 + if (!soc_device_match(soc_msi_matches))
1195 + return false;
1196 +#endif
1197 + return true; /* cannot identify SoC or errata applies */
1198 +}
1199 +#endif
1200 +
1201 static const struct platform_device_id dpaa_devtype[] = {
1202 {
1203 .name = "dpaa-ethernet",
1204 @@ -2914,6 +3099,10 @@ static int __init dpaa_load(void)
1205
1206 pr_debug("FSL DPAA Ethernet driver\n");
1207
1208 +#ifndef CONFIG_PPC
1209 + /* Detect if the current SoC requires the DMA transfer alignment workaround */
1210 + dpaa_errata_a010022 = soc_has_errata_a010022();
1211 +#endif
1212 /* initialize dpaa_eth mirror values */
1213 dpaa_rx_extra_headroom = fman_get_rx_extra_headroom();
1214 dpaa_max_frm = fman_get_max_frm();
1215 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
1216 +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
1217 @@ -344,7 +344,7 @@ static void dpaa_get_ethtool_stats(struc
1218
1219 /* gather congestion related counters */
1220 cg_num = 0;
1221 - cg_status = 0;
1222 + cg_status = false;
1223 cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
1224 if (qman_query_cgr_congested(&priv->cgr_data.cgr, &cg_status) == 0) {
1225 cg_num = priv->cgr_data.cgr_congested_count;
1226 --- a/drivers/net/ethernet/freescale/fman/Kconfig
1227 +++ b/drivers/net/ethernet/freescale/fman/Kconfig
1228 @@ -2,7 +2,6 @@ config FSL_FMAN
1229 tristate "FMan support"
1230 depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
1231 select GENERIC_ALLOCATOR
1232 - depends on HAS_DMA
1233 select PHYLIB
1234 default n
1235 help
1236 --- a/drivers/net/ethernet/freescale/fman/Makefile
1237 +++ b/drivers/net/ethernet/freescale/fman/Makefile
1238 @@ -1,10 +1,10 @@
1239 # SPDX-License-Identifier: GPL-2.0
1240 subdir-ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/fman
1241
1242 -obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
1243 -obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
1244 -obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
1245 +obj-$(CONFIG_FSL_FMAN) += fsl_dpaa_fman.o
1246 +obj-$(CONFIG_FSL_FMAN) += fsl_dpaa_fman_port.o
1247 +obj-$(CONFIG_FSL_FMAN) += fsl_dpaa_mac.o
1248
1249 -fsl_fman-objs := fman_muram.o fman.o fman_sp.o fman_keygen.o
1250 -fsl_fman_port-objs := fman_port.o
1251 -fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
1252 +fsl_dpaa_fman-objs := fman_muram.o fman.o fman_sp.o fman_keygen.o
1253 +fsl_dpaa_fman_port-objs := fman_port.o
1254 +fsl_dpaa_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
1255 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
1256 +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
1257 @@ -1117,6 +1117,25 @@ int dtsec_add_hash_mac_address(struct fm
1258 return 0;
1259 }
1260
1261 +int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
1262 +{
1263 + u32 tmp;
1264 + struct dtsec_regs __iomem *regs = dtsec->regs;
1265 +
1266 + if (!is_init_done(dtsec->dtsec_drv_param))
1267 + return -EINVAL;
1268 +
1269 + tmp = ioread32be(&regs->rctrl);
1270 + if (enable)
1271 + tmp |= RCTRL_MPROM;
1272 + else
1273 + tmp &= ~RCTRL_MPROM;
1274 +
1275 + iowrite32be(tmp, &regs->rctrl);
1276 +
1277 + return 0;
1278 +}
1279 +
1280 int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
1281 {
1282 struct dtsec_regs __iomem *regs = dtsec->regs;
1283 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.h
1284 +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
1285 @@ -55,5 +55,6 @@ int dtsec_set_exception(struct fman_mac
1286 int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
1287 int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
1288 int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
1289 +int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
1290
1291 #endif /* __DTSEC_H */
1292 --- a/drivers/net/ethernet/freescale/fman/fman_memac.c
1293 +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
1294 @@ -350,6 +350,7 @@ struct fman_mac {
1295 struct fman_rev_info fm_rev_info;
1296 bool basex_if;
1297 struct phy_device *pcsphy;
1298 + bool allmulti_enabled;
1299 };
1300
1301 static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr,
1302 @@ -940,6 +941,29 @@ int memac_add_hash_mac_address(struct fm
1303 return 0;
1304 }
1305
1306 +int memac_set_allmulti(struct fman_mac *memac, bool enable)
1307 +{
1308 + u32 entry;
1309 + struct memac_regs __iomem *regs = memac->regs;
1310 +
1311 + if (!is_init_done(memac->memac_drv_param))
1312 + return -EINVAL;
1313 +
1314 + if (enable) {
1315 + for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
1316 + iowrite32be(entry | HASH_CTRL_MCAST_EN,
1317 + &regs->hashtable_ctrl);
1318 + } else {
1319 + for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
1320 + iowrite32be(entry & ~HASH_CTRL_MCAST_EN,
1321 + &regs->hashtable_ctrl);
1322 + }
1323 +
1324 + memac->allmulti_enabled = enable;
1325 +
1326 + return 0;
1327 +}
1328 +
1329 int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
1330 {
1331 struct memac_regs __iomem *regs = memac->regs;
1332 @@ -963,8 +987,12 @@ int memac_del_hash_mac_address(struct fm
1333 break;
1334 }
1335 }
1336 - if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
1337 - iowrite32be(hash & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
1338 +
1339 + if (!memac->allmulti_enabled) {
1340 + if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
1341 + iowrite32be(hash & ~HASH_CTRL_MCAST_EN,
1342 + &regs->hashtable_ctrl);
1343 + }
1344
1345 return 0;
1346 }
1347 --- a/drivers/net/ethernet/freescale/fman/fman_memac.h
1348 +++ b/drivers/net/ethernet/freescale/fman/fman_memac.h
1349 @@ -57,5 +57,6 @@ int memac_set_exception(struct fman_mac
1350 enum fman_mac_exceptions exception, bool enable);
1351 int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
1352 int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
1353 +int memac_set_allmulti(struct fman_mac *memac, bool enable);
1354
1355 #endif /* __MEMAC_H */
1356 --- a/drivers/net/ethernet/freescale/fman/fman_port.c
1357 +++ b/drivers/net/ethernet/freescale/fman/fman_port.c
1358 @@ -1347,8 +1347,10 @@ int fman_port_config(struct fman_port *p
1359 switch (port->port_type) {
1360 case FMAN_PORT_TYPE_RX:
1361 set_rx_dflt_cfg(port, params);
1362 + /* fall through */
1363 case FMAN_PORT_TYPE_TX:
1364 set_tx_dflt_cfg(port, params, &port->dts_params);
1365 + /* fall through */
1366 default:
1367 set_dflt_cfg(port, params);
1368 }
1369 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
1370 +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
1371 @@ -217,6 +217,7 @@ struct fman_mac {
1372 struct tgec_cfg *cfg;
1373 void *fm;
1374 struct fman_rev_info fm_rev_info;
1375 + bool allmulti_enabled;
1376 };
1377
1378 static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr)
1379 @@ -564,6 +565,29 @@ int tgec_add_hash_mac_address(struct fma
1380 return 0;
1381 }
1382
1383 +int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
1384 +{
1385 + u32 entry;
1386 + struct tgec_regs __iomem *regs = tgec->regs;
1387 +
1388 + if (!is_init_done(tgec->cfg))
1389 + return -EINVAL;
1390 +
1391 + if (enable) {
1392 + for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
1393 + iowrite32be(entry | TGEC_HASH_MCAST_EN,
1394 + &regs->hashtable_ctrl);
1395 + } else {
1396 + for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
1397 + iowrite32be(entry & ~TGEC_HASH_MCAST_EN,
1398 + &regs->hashtable_ctrl);
1399 + }
1400 +
1401 + tgec->allmulti_enabled = enable;
1402 +
1403 + return 0;
1404 +}
1405 +
1406 int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
1407 {
1408 struct tgec_regs __iomem *regs = tgec->regs;
1409 @@ -591,9 +615,12 @@ int tgec_del_hash_mac_address(struct fma
1410 break;
1411 }
1412 }
1413 - if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
1414 - iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
1415 - &regs->hashtable_ctrl);
1416 +
1417 + if (!tgec->allmulti_enabled) {
1418 + if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
1419 + iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
1420 + &regs->hashtable_ctrl);
1421 + }
1422
1423 return 0;
1424 }
1425 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.h
1426 +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.h
1427 @@ -51,5 +51,6 @@ int tgec_set_exception(struct fman_mac *
1428 int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
1429 int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
1430 int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
1431 +int tgec_set_allmulti(struct fman_mac *tgec, bool enable);
1432
1433 #endif /* __TGEC_H */
1434 --- a/drivers/net/ethernet/freescale/fman/mac.c
1435 +++ b/drivers/net/ethernet/freescale/fman/mac.c
1436 @@ -57,9 +57,7 @@ struct mac_priv_s {
1437 struct device *dev;
1438 void __iomem *vaddr;
1439 u8 cell_index;
1440 - phy_interface_t phy_if;
1441 struct fman *fman;
1442 - struct device_node *phy_node;
1443 struct device_node *internal_phy_node;
1444 /* List of multicast addresses */
1445 struct list_head mc_addr_list;
1446 @@ -106,7 +104,7 @@ static void set_fman_mac_params(struct m
1447 resource_size(mac_dev->res));
1448 memcpy(&params->addr, mac_dev->addr, sizeof(mac_dev->addr));
1449 params->max_speed = priv->max_speed;
1450 - params->phy_if = priv->phy_if;
1451 + params->phy_if = mac_dev->phy_if;
1452 params->basex_if = false;
1453 params->mac_id = priv->cell_index;
1454 params->fm = (void *)priv->fman;
1455 @@ -419,15 +417,12 @@ void fman_get_pause_cfg(struct mac_devic
1456 }
1457 EXPORT_SYMBOL(fman_get_pause_cfg);
1458
1459 -static void adjust_link_void(struct net_device *net_dev)
1460 +static void adjust_link_void(struct mac_device *mac_dev)
1461 {
1462 }
1463
1464 -static void adjust_link_dtsec(struct net_device *net_dev)
1465 +static void adjust_link_dtsec(struct mac_device *mac_dev)
1466 {
1467 - struct device *dev = net_dev->dev.parent;
1468 - struct dpaa_eth_data *eth_data = dev->platform_data;
1469 - struct mac_device *mac_dev = eth_data->mac_dev;
1470 struct phy_device *phy_dev = mac_dev->phy_dev;
1471 struct fman_mac *fman_mac;
1472 bool rx_pause, tx_pause;
1473 @@ -444,14 +439,12 @@ static void adjust_link_dtsec(struct net
1474 fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
1475 err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
1476 if (err < 0)
1477 - netdev_err(net_dev, "fman_set_mac_active_pause() = %d\n", err);
1478 + dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
1479 + err);
1480 }
1481
1482 -static void adjust_link_memac(struct net_device *net_dev)
1483 +static void adjust_link_memac(struct mac_device *mac_dev)
1484 {
1485 - struct device *dev = net_dev->dev.parent;
1486 - struct dpaa_eth_data *eth_data = dev->platform_data;
1487 - struct mac_device *mac_dev = eth_data->mac_dev;
1488 struct phy_device *phy_dev = mac_dev->phy_dev;
1489 struct fman_mac *fman_mac;
1490 bool rx_pause, tx_pause;
1491 @@ -463,60 +456,12 @@ static void adjust_link_memac(struct net
1492 fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
1493 err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
1494 if (err < 0)
1495 - netdev_err(net_dev, "fman_set_mac_active_pause() = %d\n", err);
1496 -}
1497 -
1498 -/* Initializes driver's PHY state, and attaches to the PHY.
1499 - * Returns 0 on success.
1500 - */
1501 -static struct phy_device *init_phy(struct net_device *net_dev,
1502 - struct mac_device *mac_dev,
1503 - void (*adj_lnk)(struct net_device *))
1504 -{
1505 - struct phy_device *phy_dev;
1506 - struct mac_priv_s *priv = mac_dev->priv;
1507 -
1508 - phy_dev = of_phy_connect(net_dev, priv->phy_node, adj_lnk, 0,
1509 - priv->phy_if);
1510 - if (!phy_dev) {
1511 - netdev_err(net_dev, "Could not connect to PHY\n");
1512 - return NULL;
1513 - }
1514 -
1515 - /* Remove any features not supported by the controller */
1516 - phy_dev->supported &= mac_dev->if_support;
1517 - /* Enable the symmetric and asymmetric PAUSE frame advertisements,
1518 - * as most of the PHY drivers do not enable them by default.
1519 - */
1520 - phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
1521 - phy_dev->advertising = phy_dev->supported;
1522 -
1523 - mac_dev->phy_dev = phy_dev;
1524 -
1525 - return phy_dev;
1526 -}
1527 -
1528 -static struct phy_device *dtsec_init_phy(struct net_device *net_dev,
1529 - struct mac_device *mac_dev)
1530 -{
1531 - return init_phy(net_dev, mac_dev, &adjust_link_dtsec);
1532 -}
1533 -
1534 -static struct phy_device *tgec_init_phy(struct net_device *net_dev,
1535 - struct mac_device *mac_dev)
1536 -{
1537 - return init_phy(net_dev, mac_dev, adjust_link_void);
1538 -}
1539 -
1540 -static struct phy_device *memac_init_phy(struct net_device *net_dev,
1541 - struct mac_device *mac_dev)
1542 -{
1543 - return init_phy(net_dev, mac_dev, &adjust_link_memac);
1544 + dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
1545 + err);
1546 }
1547
1548 static void setup_dtsec(struct mac_device *mac_dev)
1549 {
1550 - mac_dev->init_phy = dtsec_init_phy;
1551 mac_dev->init = dtsec_initialization;
1552 mac_dev->set_promisc = dtsec_set_promiscuous;
1553 mac_dev->change_addr = dtsec_modify_mac_address;
1554 @@ -525,17 +470,17 @@ static void setup_dtsec(struct mac_devic
1555 mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
1556 mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
1557 mac_dev->set_exception = dtsec_set_exception;
1558 + mac_dev->set_allmulti = dtsec_set_allmulti;
1559 mac_dev->set_multi = set_multi;
1560 mac_dev->start = start;
1561 mac_dev->stop = stop;
1562 -
1563 + mac_dev->adjust_link = adjust_link_dtsec;
1564 mac_dev->priv->enable = dtsec_enable;
1565 mac_dev->priv->disable = dtsec_disable;
1566 }
1567
1568 static void setup_tgec(struct mac_device *mac_dev)
1569 {
1570 - mac_dev->init_phy = tgec_init_phy;
1571 mac_dev->init = tgec_initialization;
1572 mac_dev->set_promisc = tgec_set_promiscuous;
1573 mac_dev->change_addr = tgec_modify_mac_address;
1574 @@ -544,17 +489,17 @@ static void setup_tgec(struct mac_device
1575 mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
1576 mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
1577 mac_dev->set_exception = tgec_set_exception;
1578 + mac_dev->set_allmulti = tgec_set_allmulti;
1579 mac_dev->set_multi = set_multi;
1580 mac_dev->start = start;
1581 mac_dev->stop = stop;
1582 -
1583 + mac_dev->adjust_link = adjust_link_void;
1584 mac_dev->priv->enable = tgec_enable;
1585 mac_dev->priv->disable = tgec_disable;
1586 }
1587
1588 static void setup_memac(struct mac_device *mac_dev)
1589 {
1590 - mac_dev->init_phy = memac_init_phy;
1591 mac_dev->init = memac_initialization;
1592 mac_dev->set_promisc = memac_set_promiscuous;
1593 mac_dev->change_addr = memac_modify_mac_address;
1594 @@ -563,10 +508,11 @@ static void setup_memac(struct mac_devic
1595 mac_dev->set_tx_pause = memac_set_tx_pause_frames;
1596 mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
1597 mac_dev->set_exception = memac_set_exception;
1598 + mac_dev->set_allmulti = memac_set_allmulti;
1599 mac_dev->set_multi = set_multi;
1600 mac_dev->start = start;
1601 mac_dev->stop = stop;
1602 -
1603 + mac_dev->adjust_link = adjust_link_memac;
1604 mac_dev->priv->enable = memac_enable;
1605 mac_dev->priv->disable = memac_disable;
1606 }
1607 @@ -599,8 +545,7 @@ static const u16 phy2speed[] = {
1608 };
1609
1610 static struct platform_device *dpaa_eth_add_device(int fman_id,
1611 - struct mac_device *mac_dev,
1612 - struct device_node *node)
1613 + struct mac_device *mac_dev)
1614 {
1615 struct platform_device *pdev;
1616 struct dpaa_eth_data data;
1617 @@ -613,19 +558,15 @@ static struct platform_device *dpaa_eth_
1618 data.mac_dev = mac_dev;
1619 data.mac_hw_id = priv->cell_index;
1620 data.fman_hw_id = fman_id;
1621 - data.mac_node = node;
1622
1623 mutex_lock(&eth_lock);
1624 -
1625 pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt);
1626 if (!pdev) {
1627 ret = -ENOMEM;
1628 goto no_mem;
1629 }
1630
1631 - pdev->dev.of_node = node;
1632 pdev->dev.parent = priv->dev;
1633 - set_dma_ops(&pdev->dev, get_dma_ops(priv->dev));
1634
1635 ret = platform_device_add_data(pdev, &data, sizeof(data));
1636 if (ret)
1637 @@ -676,7 +617,6 @@ static int mac_probe(struct platform_dev
1638 mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
1639 if (!mac_dev) {
1640 err = -ENOMEM;
1641 - dev_err(dev, "devm_kzalloc() = %d\n", err);
1642 goto _return;
1643 }
1644 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1645 @@ -706,9 +646,6 @@ static int mac_probe(struct platform_dev
1646 goto _return;
1647 }
1648
1649 - /* Register mac_dev */
1650 - dev_set_drvdata(dev, mac_dev);
1651 -
1652 INIT_LIST_HEAD(&priv->mc_addr_list);
1653
1654 /* Get the FM node */
1655 @@ -717,7 +654,7 @@ static int mac_probe(struct platform_dev
1656 dev_err(dev, "of_get_parent(%pOF) failed\n",
1657 mac_node);
1658 err = -EINVAL;
1659 - goto _return_dev_set_drvdata;
1660 + goto _return_of_get_parent;
1661 }
1662
1663 of_dev = of_find_device_by_node(dev_node);
1664 @@ -751,7 +688,7 @@ static int mac_probe(struct platform_dev
1665 if (err < 0) {
1666 dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
1667 mac_node, err);
1668 - goto _return_dev_set_drvdata;
1669 + goto _return_of_get_parent;
1670 }
1671
1672 mac_dev->res = __devm_request_region(dev,
1673 @@ -761,7 +698,7 @@ static int mac_probe(struct platform_dev
1674 if (!mac_dev->res) {
1675 dev_err(dev, "__devm_request_mem_region(mac) failed\n");
1676 err = -EBUSY;
1677 - goto _return_dev_set_drvdata;
1678 + goto _return_of_get_parent;
1679 }
1680
1681 priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
1682 @@ -769,16 +706,12 @@ static int mac_probe(struct platform_dev
1683 if (!priv->vaddr) {
1684 dev_err(dev, "devm_ioremap() failed\n");
1685 err = -EIO;
1686 - goto _return_dev_set_drvdata;
1687 + goto _return_of_get_parent;
1688 }
1689
1690 if (!of_device_is_available(mac_node)) {
1691 - devm_iounmap(dev, priv->vaddr);
1692 - __devm_release_region(dev, fman_get_mem_region(priv->fman),
1693 - res.start, res.end + 1 - res.start);
1694 - devm_kfree(dev, mac_dev);
1695 - dev_set_drvdata(dev, NULL);
1696 - return -ENODEV;
1697 + err = -ENODEV;
1698 + goto _return_of_get_parent;
1699 }
1700
1701 /* Get the cell-index */
1702 @@ -786,7 +719,7 @@ static int mac_probe(struct platform_dev
1703 if (err) {
1704 dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
1705 err = -EINVAL;
1706 - goto _return_dev_set_drvdata;
1707 + goto _return_of_get_parent;
1708 }
1709 priv->cell_index = (u8)val;
1710
1711 @@ -795,7 +728,7 @@ static int mac_probe(struct platform_dev
1712 if (!mac_addr) {
1713 dev_err(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
1714 err = -EINVAL;
1715 - goto _return_dev_set_drvdata;
1716 + goto _return_of_get_parent;
1717 }
1718 memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
1719
1720 @@ -805,14 +738,14 @@ static int mac_probe(struct platform_dev
1721 dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
1722 mac_node);
1723 err = nph;
1724 - goto _return_dev_set_drvdata;
1725 + goto _return_of_get_parent;
1726 }
1727
1728 if (nph != ARRAY_SIZE(mac_dev->port)) {
1729 dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
1730 mac_node);
1731 err = -EINVAL;
1732 - goto _return_dev_set_drvdata;
1733 + goto _return_of_get_parent;
1734 }
1735
1736 for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
1737 @@ -851,13 +784,13 @@ static int mac_probe(struct platform_dev
1738 mac_node);
1739 phy_if = PHY_INTERFACE_MODE_SGMII;
1740 }
1741 - priv->phy_if = phy_if;
1742 + mac_dev->phy_if = phy_if;
1743
1744 - priv->speed = phy2speed[priv->phy_if];
1745 + priv->speed = phy2speed[mac_dev->phy_if];
1746 priv->max_speed = priv->speed;
1747 mac_dev->if_support = DTSEC_SUPPORTED;
1748 /* We don't support half-duplex in SGMII mode */
1749 - if (priv->phy_if == PHY_INTERFACE_MODE_SGMII)
1750 + if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
1751 mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
1752 SUPPORTED_100baseT_Half);
1753
1754 @@ -866,30 +799,31 @@ static int mac_probe(struct platform_dev
1755 mac_dev->if_support |= SUPPORTED_1000baseT_Full;
1756
1757 /* The 10G interface only supports one mode */
1758 - if (priv->phy_if == PHY_INTERFACE_MODE_XGMII)
1759 + if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
1760 mac_dev->if_support = SUPPORTED_10000baseT_Full;
1761
1762 /* Get the rest of the PHY information */
1763 - priv->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
1764 - if (!priv->phy_node && of_phy_is_fixed_link(mac_node)) {
1765 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
1766 + if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
1767 struct phy_device *phy;
1768
1769 err = of_phy_register_fixed_link(mac_node);
1770 if (err)
1771 - goto _return_dev_set_drvdata;
1772 + goto _return_of_get_parent;
1773
1774 priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
1775 GFP_KERNEL);
1776 if (!priv->fixed_link) {
1777 err = -ENOMEM;
1778 - goto _return_dev_set_drvdata;
1779 + goto _return_of_get_parent;
1780 }
1781
1782 - priv->phy_node = of_node_get(mac_node);
1783 - phy = of_phy_find_device(priv->phy_node);
1784 + mac_dev->phy_node = of_node_get(mac_node);
1785 + phy = of_phy_find_device(mac_dev->phy_node);
1786 if (!phy) {
1787 err = -EINVAL;
1788 - goto _return_dev_set_drvdata;
1789 + of_node_put(mac_dev->phy_node);
1790 + goto _return_of_get_parent;
1791 }
1792
1793 priv->fixed_link->link = phy->link;
1794 @@ -904,8 +838,8 @@ static int mac_probe(struct platform_dev
1795 err = mac_dev->init(mac_dev);
1796 if (err < 0) {
1797 dev_err(dev, "mac_dev->init() = %d\n", err);
1798 - of_node_put(priv->phy_node);
1799 - goto _return_dev_set_drvdata;
1800 + of_node_put(mac_dev->phy_node);
1801 + goto _return_of_get_parent;
1802 }
1803
1804 /* pause frame autonegotiation enabled */
1805 @@ -926,7 +860,7 @@ static int mac_probe(struct platform_dev
1806 mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
1807 mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
1808
1809 - priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev, mac_node);
1810 + priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
1811 if (IS_ERR(priv->eth_dev)) {
1812 dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
1813 priv->cell_index);
1814 @@ -937,9 +871,8 @@ static int mac_probe(struct platform_dev
1815
1816 _return_of_node_put:
1817 of_node_put(dev_node);
1818 -_return_dev_set_drvdata:
1819 +_return_of_get_parent:
1820 kfree(priv->fixed_link);
1821 - dev_set_drvdata(dev, NULL);
1822 _return:
1823 return err;
1824 }
1825 --- a/drivers/net/ethernet/freescale/fman/mac.h
1826 +++ b/drivers/net/ethernet/freescale/fman/mac.h
1827 @@ -50,6 +50,8 @@ struct mac_device {
1828 struct fman_port *port[2];
1829 u32 if_support;
1830 struct phy_device *phy_dev;
1831 + phy_interface_t phy_if;
1832 + struct device_node *phy_node;
1833
1834 bool autoneg_pause;
1835 bool rx_pause_req;
1836 @@ -57,14 +59,15 @@ struct mac_device {
1837 bool rx_pause_active;
1838 bool tx_pause_active;
1839 bool promisc;
1840 + bool allmulti;
1841
1842 - struct phy_device *(*init_phy)(struct net_device *net_dev,
1843 - struct mac_device *mac_dev);
1844 int (*init)(struct mac_device *mac_dev);
1845 int (*start)(struct mac_device *mac_dev);
1846 int (*stop)(struct mac_device *mac_dev);
1847 + void (*adjust_link)(struct mac_device *mac_dev);
1848 int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
1849 int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr);
1850 + int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
1851 int (*set_multi)(struct net_device *net_dev,
1852 struct mac_device *mac_dev);
1853 int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
1854 @@ -82,7 +85,6 @@ struct mac_device {
1855 };
1856
1857 struct dpaa_eth_data {
1858 - struct device_node *mac_node;
1859 struct mac_device *mac_dev;
1860 int mac_hw_id;
1861 int fman_hw_id;
1862 --- /dev/null
1863 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
1864 @@ -0,0 +1,195 @@
1865 +menuconfig FSL_SDK_DPAA_ETH
1866 + tristate "DPAA Ethernet"
1867 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
1868 + select PHYLIB
1869 + help
1870 + Data Path Acceleration Architecture Ethernet driver,
1871 + supporting the Freescale QorIQ chips.
1872 + Depends on Freescale Buffer Manager and Queue Manager
1873 + driver and Frame Manager Driver.
1874 +
1875 +if FSL_SDK_DPAA_ETH
1876 +
1877 +config FSL_DPAA_HOOKS
1878 + bool "DPAA Ethernet driver hooks"
1879 +
1880 +config FSL_DPAA_CEETM
1881 + bool "DPAA CEETM QoS"
1882 + depends on NET_SCHED
1883 + default n
1884 + help
1885 + Enable QoS offloading support through the CEETM hardware block.
1886 +
1887 +config FSL_DPAA_CEETM_CCS_THRESHOLD_1G
1888 + hex "CEETM egress congestion threshold on 1G ports"
1889 + depends on FSL_DPAA_CEETM
1890 + range 0x1000 0x10000000
1891 + default "0x000a0000"
1892 + help
1893 + The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports.
1894 + The threshold needs to be configured keeping in mind the following factors:
1895 + - A threshold too large will buffer frames for a long time in the TX queues,
1896 + when a small shaping rate is configured. This will cause buffer pool depletion
1897 + or out of memory errors. This in turn will cause frame loss on RX;
1898 + - A threshold too small will cause unnecessary frame loss by entering
1899 + congestion too often.
1900 +
1901 +config FSL_DPAA_CEETM_CCS_THRESHOLD_10G
1902 + hex "CEETM egress congestion threshold on 10G ports"
1903 + depends on FSL_DPAA_CEETM
1904 + range 0x1000 0x20000000
1905 + default "0x00640000"
1906 + help
1907 + The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports.
1908 + See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details.
1909 +
1910 +config FSL_DPAA_OFFLINE_PORTS
1911 + bool "Offline Ports support"
1912 + depends on FSL_SDK_DPAA_ETH
1913 + default y
1914 + help
1915 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
1916 + most of the functionality of the regular, online ports, except they receive their
1917 + frames from a core or an accelerator on the SoC, via QMan frame queues,
1918 + rather than directly from the network.
1919 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
1920 + any online FMan port. They deliver the processed frames to frame queues, according
1921 + to the applied PCD configurations.
1922 +
1923 + Choosing this feature will not impact the functionality and/or performance of the system,
1924 + so it is safe to have it.
1925 +
1926 +config FSL_DPAA_ADVANCED_DRIVERS
1927 + bool "Advanced DPAA Ethernet drivers"
1928 + depends on FSL_SDK_DPAA_ETH
1929 + default y
1930 + help
1931 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
1932 + is needed to support advanced scenarios. Select this to also build the advanced
1933 + drivers.
1934 +
1935 +config FSL_DPAA_ETH_JUMBO_FRAME
1936 + bool "Optimize for jumbo frames"
1937 + default n
1938 + help
1939 + Optimize the DPAA Ethernet driver throughput for large frames
1940 + termination traffic (e.g. 4K and above).
1941 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
1942 + is set to 9600 bytes.
1943 + Using this option in combination with small frames increases
1944 + significantly the driver's memory footprint and may even deplete
1945 + the system memory. Also, the skb truesize is altered and messages
1946 + from the stack that warn against this are bypassed.
1947 +
1948 +config FSL_DPAA_TS
1949 + bool "Linux compliant timestamping"
1950 + depends on FSL_SDK_DPAA_ETH
1951 + default n
1952 + help
1953 + Enable Linux API compliant timestamping support.
1954 +
1955 +config FSL_DPAA_1588
1956 + bool "IEEE 1588-compliant timestamping"
1957 + depends on FSL_SDK_DPAA_ETH
1958 + select FSL_DPAA_TS
1959 + default n
1960 + help
1961 + Enable IEEE1588 support code.
1962 +
1963 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
1964 + bool "Use driver's Tx queue selection mechanism"
1965 + default y
1966 + depends on FSL_SDK_DPAA_ETH
1967 + help
1968 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
1969 + of the egress FQ. That will override the XPS support for this netdevice.
1970 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
1971 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
1972 + and use the standard XPS support instead.
1973 +
1974 +config FSL_DPAA_ETH_MAX_BUF_COUNT
1975 + int "Maximum nuber of buffers in private bpool"
1976 + depends on FSL_SDK_DPAA_ETH
1977 + range 64 2048
1978 + default "128"
1979 + help
1980 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
1981 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
1982 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
1983 +
1984 +config FSL_DPAA_ETH_REFILL_THRESHOLD
1985 + int "Private bpool refill threshold"
1986 + depends on FSL_SDK_DPAA_ETH
1987 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
1988 + default "80"
1989 + help
1990 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
1991 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
1992 + modify this value unless one has very specific performance reasons.
1993 +
1994 +config FSL_DPAA_CS_THRESHOLD_1G
1995 + hex "Egress congestion threshold on 1G ports"
1996 + depends on FSL_SDK_DPAA_ETH
1997 + range 0x1000 0x10000000
1998 + default "0x06000000"
1999 + help
2000 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
2001 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
2002 + (e.g. by sending UDP datagrams at "while(1) speed"),
2003 + and the larger the frame size, the more acute the problem.
2004 + So we have to find a balance between these factors:
2005 + - avoiding the device staying congested for a prolonged time (risking
2006 + the netdev watchdog to fire - see also the tx_timeout module param);
2007 + - affecting performance of protocols such as TCP, which otherwise
2008 + behave well under the congestion notification mechanism;
2009 + - preventing the Tx cores from tightly-looping (as if the congestion
2010 + threshold was too low to be effective);
2011 + - running out of memory if the CS threshold is set too high.
2012 +
2013 +config FSL_DPAA_CS_THRESHOLD_10G
2014 + hex "Egress congestion threshold on 10G ports"
2015 + depends on FSL_SDK_DPAA_ETH
2016 + range 0x1000 0x20000000
2017 + default "0x10000000"
2018 + help
2019 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
2020 +
2021 +config FSL_DPAA_INGRESS_CS_THRESHOLD
2022 + hex "Ingress congestion threshold on FMan ports"
2023 + depends on FSL_SDK_DPAA_ETH
2024 + default "0x10000000"
2025 + help
2026 + The size in bytes of the ingress tail-drop threshold on FMan ports.
2027 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
2028 +
2029 +config FSL_DPAA_ETH_DEBUGFS
2030 + bool "DPAA Ethernet debugfs interface"
2031 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
2032 + default y
2033 + help
2034 + This option compiles debugfs code for the DPAA Ethernet driver.
2035 +
2036 +config FSL_DPAA_ETH_DEBUG
2037 + bool "DPAA Ethernet Debug Support"
2038 + depends on FSL_SDK_DPAA_ETH
2039 + default n
2040 + help
2041 + This option compiles debug code for the DPAA Ethernet driver.
2042 +
2043 +config FSL_DPAA_DBG_LOOP
2044 + bool "DPAA Ethernet Debug loopback"
2045 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2046 + default n
2047 + help
2048 + This option allows to divert all received traffic on a certain interface A towards a
2049 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
2050 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
2051 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
2052 + change the loop setting for interface 4 and divert all received traffic to interface 5
2053 + write Tx interface number in the receive interface debugfs file:
2054 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
2055 + 4->-1
2056 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
2057 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
2058 + 4->5
2059 +endif # FSL_SDK_DPAA_ETH
2060 --- /dev/null
2061 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
2062 @@ -0,0 +1,46 @@
2063 +#
2064 +# Makefile for the Freescale Ethernet controllers
2065 +#
2066 +ccflags-y += -DVERSION=\"\"
2067 +#
2068 +# Include netcomm SW specific definitions
2069 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
2070 +
2071 +ccflags-y += -I$(NET_DPA)
2072 +
2073 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
2074 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
2075 +
2076 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
2077 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
2078 +fsl_dpa-objs += dpaa_debugfs.o
2079 +endif
2080 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
2081 +fsl_dpa-objs += dpaa_1588.o
2082 +endif
2083 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
2084 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
2085 +fsl_dpa-objs += dpaa_eth_ceetm.o
2086 +endif
2087 +
2088 +fsl_mac-objs += mac.o mac-api.o
2089 +
2090 +# Advanced drivers
2091 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
2092 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
2093 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
2094 +
2095 +fsl_advanced-objs += dpaa_eth_base.o
2096 +# suport for multiple drivers per kernel module comes in kernel 3.14
2097 +# so we are forced to generate several modules for the advanced drivers
2098 +fsl_proxy-objs += dpaa_eth_proxy.o
2099 +
2100 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
2101 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
2102 +
2103 +fsl_oh-objs += offline_port.o
2104 +endif
2105 +endif
2106 +
2107 +# Needed by the tracing framework
2108 +CFLAGS_dpaa_eth.o := -I$(src)
2109 --- /dev/null
2110 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
2111 @@ -0,0 +1,580 @@
2112 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
2113 + * Copyright (C) 2009 IXXAT Automation, GmbH
2114 + *
2115 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
2116 + *
2117 + * This program is free software; you can redistribute it and/or modify
2118 + * it under the terms of the GNU General Public License as published by
2119 + * the Free Software Foundation; either version 2 of the License, or
2120 + * (at your option) any later version.
2121 + *
2122 + * This program is distributed in the hope that it will be useful,
2123 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2124 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2125 + * GNU General Public License for more details.
2126 + *
2127 + * You should have received a copy of the GNU General Public License along
2128 + * with this program; if not, write to the Free Software Foundation, Inc.,
2129 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2130 + *
2131 + */
2132 +#include <linux/io.h>
2133 +#include <linux/device.h>
2134 +#include <linux/fs.h>
2135 +#include <linux/vmalloc.h>
2136 +#include <linux/spinlock.h>
2137 +#include <linux/ip.h>
2138 +#include <linux/ipv6.h>
2139 +#include <linux/udp.h>
2140 +#include <asm/div64.h>
2141 +#include "dpaa_eth.h"
2142 +#include "dpaa_eth_common.h"
2143 +#include "dpaa_1588.h"
2144 +#include "mac.h"
2145 +
2146 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
2147 +{
2148 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2149 +
2150 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
2151 + if (!circ_buf->buf)
2152 + return 1;
2153 +
2154 + circ_buf->head = 0;
2155 + circ_buf->tail = 0;
2156 + ptp_buf->size = size;
2157 + spin_lock_init(&ptp_buf->ptp_lock);
2158 +
2159 + return 0;
2160 +}
2161 +
2162 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
2163 +{
2164 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2165 +
2166 + circ_buf->head = 0;
2167 + circ_buf->tail = 0;
2168 + ptp_buf->size = size;
2169 +}
2170 +
2171 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
2172 + struct dpa_ptp_data *data)
2173 +{
2174 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2175 + int size = ptp_buf->size;
2176 + struct dpa_ptp_data *tmp;
2177 + unsigned long flags;
2178 + int head, tail;
2179 +
2180 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
2181 +
2182 + head = circ_buf->head;
2183 + tail = circ_buf->tail;
2184 +
2185 + if (CIRC_SPACE(head, tail, size) <= 0)
2186 + circ_buf->tail = (tail + 1) & (size - 1);
2187 +
2188 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
2189 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
2190 +
2191 + circ_buf->head = (head + 1) & (size - 1);
2192 +
2193 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2194 +
2195 + return 0;
2196 +}
2197 +
2198 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
2199 + struct dpa_ptp_ident *src)
2200 +{
2201 + int ret;
2202 +
2203 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
2204 + return 0;
2205 +
2206 + if ((dst->netw_prot == src->netw_prot)
2207 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
2208 + if (dst->seq_id != src->seq_id)
2209 + return 0;
2210 +
2211 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
2212 + DPA_PTP_SOURCE_PORT_LENGTH);
2213 + if (ret)
2214 + return 0;
2215 + else
2216 + return 1;
2217 + }
2218 +
2219 + return 0;
2220 +}
2221 +
2222 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
2223 + struct dpa_ptp_ident *ident,
2224 + struct dpa_ptp_time *ts)
2225 +{
2226 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2227 + int size = ptp_buf->size;
2228 + int head, tail, idx;
2229 + unsigned long flags;
2230 + struct dpa_ptp_data *tmp, *tmp2;
2231 + struct dpa_ptp_ident *tmp_ident;
2232 +
2233 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
2234 +
2235 + head = circ_buf->head;
2236 + tail = idx = circ_buf->tail;
2237 +
2238 + if (CIRC_CNT(head, tail, size) == 0) {
2239 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2240 + return 1;
2241 + }
2242 +
2243 + while (idx != head) {
2244 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
2245 + tmp_ident = &tmp->ident;
2246 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
2247 + break;
2248 + idx = (idx + 1) & (size - 1);
2249 + }
2250 +
2251 + if (idx == head) {
2252 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2253 + return 1;
2254 + }
2255 +
2256 + ts->sec = tmp->ts.sec;
2257 + ts->nsec = tmp->ts.nsec;
2258 +
2259 + if (idx != tail) {
2260 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
2261 + tail = circ_buf->tail =
2262 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
2263 + }
2264 +
2265 + while (CIRC_CNT(idx, tail, size) > 0) {
2266 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
2267 + idx = (idx - 1) & (size - 1);
2268 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
2269 + *tmp = *tmp2;
2270 + }
2271 + }
2272 + circ_buf->tail = (tail + 1) & (size - 1);
2273 +
2274 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2275 +
2276 + return 0;
2277 +}
2278 +
2279 +/* Parse the PTP packets
2280 + *
2281 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
2282 + * an IEEE802.3 ethernet frame. This function returns the position of
2283 + * the PTP packet or NULL if no PTP found
2284 + */
2285 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
2286 +{
2287 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
2288 + u8 *ptp_loc = NULL;
2289 + u8 msg_type;
2290 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
2291 + struct iphdr *iph;
2292 + struct udphdr *udph;
2293 + struct ipv6hdr *ipv6h;
2294 +
2295 + /* when we can receive S/G frames we need to check the data we want to
2296 + * access is in the linear skb buffer
2297 + */
2298 + if (!pskb_may_pull(skb, access_len))
2299 + return NULL;
2300 +
2301 + *eth_type = *((u16 *)pos);
2302 +
2303 + /* Check if inner tag is here */
2304 + if (*eth_type == ETH_P_8021Q) {
2305 + access_len += DPA_VLAN_TAG_LEN;
2306 +
2307 + if (!pskb_may_pull(skb, access_len))
2308 + return NULL;
2309 +
2310 + pos += DPA_VLAN_TAG_LEN;
2311 + *eth_type = *((u16 *)pos);
2312 + }
2313 +
2314 + pos += DPA_ETYPE_LEN;
2315 +
2316 + switch (*eth_type) {
2317 + /* Transport of PTP over Ethernet */
2318 + case ETH_P_1588:
2319 + ptp_loc = pos;
2320 +
2321 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
2322 + return NULL;
2323 +
2324 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
2325 + if ((msg_type == PTP_MSGTYPE_SYNC)
2326 + || (msg_type == PTP_MSGTYPE_DELREQ)
2327 + || (msg_type == PTP_MSGTYPE_PDELREQ)
2328 + || (msg_type == PTP_MSGTYPE_PDELRESP))
2329 + return ptp_loc;
2330 + break;
2331 + /* Transport of PTP over IPv4 */
2332 + case ETH_P_IP:
2333 + iph = (struct iphdr *)pos;
2334 + access_len += sizeof(struct iphdr);
2335 +
2336 + if (!pskb_may_pull(skb, access_len))
2337 + return NULL;
2338 +
2339 + if (ntohs(iph->protocol) != IPPROTO_UDP)
2340 + return NULL;
2341 +
2342 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
2343 + sizeof(struct udphdr);
2344 +
2345 + if (!pskb_may_pull(skb, access_len))
2346 + return NULL;
2347 +
2348 + pos += iph->ihl * 4;
2349 + udph = (struct udphdr *)pos;
2350 + if (ntohs(udph->dest) != 319)
2351 + return NULL;
2352 + ptp_loc = pos + sizeof(struct udphdr);
2353 + break;
2354 + /* Transport of PTP over IPv6 */
2355 + case ETH_P_IPV6:
2356 + ipv6h = (struct ipv6hdr *)pos;
2357 +
2358 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
2359 +
2360 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
2361 + return NULL;
2362 +
2363 + pos += sizeof(struct ipv6hdr);
2364 + udph = (struct udphdr *)pos;
2365 + if (ntohs(udph->dest) != 319)
2366 + return NULL;
2367 + ptp_loc = pos + sizeof(struct udphdr);
2368 + break;
2369 + default:
2370 + break;
2371 + }
2372 +
2373 + return ptp_loc;
2374 +}
2375 +
2376 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
2377 + struct sk_buff *skb, void *data, enum port_type rx_tx,
2378 + struct dpa_ptp_data *ptp_data)
2379 +{
2380 + u64 nsec;
2381 + u32 mod;
2382 + u8 *ptp_loc;
2383 + u16 eth_type;
2384 +
2385 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
2386 + if (!ptp_loc)
2387 + return -EINVAL;
2388 +
2389 + switch (eth_type) {
2390 + case ETH_P_IP:
2391 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
2392 + break;
2393 + case ETH_P_IPV6:
2394 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
2395 + break;
2396 + case ETH_P_1588:
2397 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
2398 + break;
2399 + default:
2400 + return -EINVAL;
2401 + }
2402 +
2403 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
2404 + return -EINVAL;
2405 +
2406 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
2407 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
2408 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
2409 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
2410 + DPA_PTP_SOURCE_PORT_LENGTH);
2411 +
2412 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
2413 + mod = do_div(nsec, NANOSEC_PER_SECOND);
2414 + ptp_data->ts.sec = nsec;
2415 + ptp_data->ts.nsec = mod;
2416 +
2417 + return 0;
2418 +}
2419 +
2420 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
2421 + struct sk_buff *skb, void *data)
2422 +{
2423 + struct dpa_ptp_tsu *tsu = priv->tsu;
2424 + struct dpa_ptp_data ptp_tx_data;
2425 +
2426 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
2427 + return;
2428 +
2429 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
2430 +}
2431 +
2432 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
2433 + struct sk_buff *skb, void *data)
2434 +{
2435 + struct dpa_ptp_tsu *tsu = priv->tsu;
2436 + struct dpa_ptp_data ptp_rx_data;
2437 +
2438 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
2439 + return;
2440 +
2441 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
2442 +}
2443 +
2444 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
2445 + struct dpa_ptp_ident *ident,
2446 + struct dpa_ptp_time *ts)
2447 +{
2448 + struct dpa_ptp_tsu *tsu = ptp_tsu;
2449 + struct dpa_ptp_time tmp;
2450 + int flag;
2451 +
2452 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
2453 + if (!flag) {
2454 + ts->sec = tmp.sec;
2455 + ts->nsec = tmp.nsec;
2456 + return 0;
2457 + }
2458 +
2459 + return -1;
2460 +}
2461 +
2462 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
2463 + struct dpa_ptp_ident *ident,
2464 + struct dpa_ptp_time *ts)
2465 +{
2466 + struct dpa_ptp_tsu *tsu = ptp_tsu;
2467 + struct dpa_ptp_time tmp;
2468 + int flag;
2469 +
2470 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
2471 + if (!flag) {
2472 + ts->sec = tmp.sec;
2473 + ts->nsec = tmp.nsec;
2474 + return 0;
2475 + }
2476 +
2477 + return -1;
2478 +}
2479 +
2480 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
2481 + struct dpa_ptp_time *cnt_time)
2482 +{
2483 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
2484 + u64 tmp, fiper;
2485 +
2486 + if (mac_dev->fm_rtc_disable)
2487 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
2488 +
2489 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
2490 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
2491 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
2492 + if (mac_dev->fm_rtc_set_alarm)
2493 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
2494 + 0, tmp);
2495 + if (mac_dev->fm_rtc_set_fiper)
2496 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
2497 + 0, fiper);
2498 +
2499 + if (mac_dev->fm_rtc_enable)
2500 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
2501 +}
2502 +
2503 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
2504 + struct dpa_ptp_time *curr_time)
2505 +{
2506 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
2507 + u64 tmp;
2508 + u32 mod;
2509 +
2510 + if (mac_dev->fm_rtc_get_cnt)
2511 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
2512 + &tmp);
2513 +
2514 + mod = do_div(tmp, NANOSEC_PER_SECOND);
2515 + curr_time->sec = (u32)tmp;
2516 + curr_time->nsec = mod;
2517 +}
2518 +
2519 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
2520 + struct dpa_ptp_time *cnt_time)
2521 +{
2522 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
2523 + u64 tmp;
2524 +
2525 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
2526 +
2527 + if (mac_dev->fm_rtc_set_cnt)
2528 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
2529 + tmp);
2530 +
2531 + /* Restart fiper two seconds later */
2532 + cnt_time->sec += 2;
2533 + cnt_time->nsec = 0;
2534 + dpa_set_fiper_alarm(tsu, cnt_time);
2535 +}
2536 +
2537 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
2538 +{
2539 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
2540 + u32 drift;
2541 +
2542 + if (mac_dev->fm_rtc_get_drift)
2543 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
2544 + &drift);
2545 +
2546 + *addend = drift;
2547 +}
2548 +
2549 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
2550 +{
2551 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
2552 +
2553 + if (mac_dev->fm_rtc_set_drift)
2554 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
2555 + addend);
2556 +}
2557 +
2558 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
2559 +{
2560 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
2561 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
2562 +}
2563 +
2564 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
2565 +{
2566 + struct dpa_priv_s *priv = netdev_priv(dev);
2567 + struct dpa_ptp_tsu *tsu = priv->tsu;
2568 + struct mac_device *mac_dev = priv->mac_dev;
2569 + struct dpa_ptp_data ptp_data;
2570 + struct dpa_ptp_data *ptp_data_user;
2571 + struct dpa_ptp_time act_time;
2572 + u32 addend;
2573 + int retval = 0;
2574 +
2575 + if (!tsu || !tsu->valid)
2576 + return -ENODEV;
2577 +
2578 + switch (cmd) {
2579 + case PTP_ENBL_TXTS_IOCTL:
2580 + tsu->hwts_tx_en_ioctl = 1;
2581 + if (mac_dev->fm_rtc_enable)
2582 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
2583 + if (mac_dev->ptp_enable)
2584 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
2585 + break;
2586 + case PTP_DSBL_TXTS_IOCTL:
2587 + tsu->hwts_tx_en_ioctl = 0;
2588 + if (mac_dev->fm_rtc_disable)
2589 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
2590 + if (mac_dev->ptp_disable)
2591 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
2592 + break;
2593 + case PTP_ENBL_RXTS_IOCTL:
2594 + tsu->hwts_rx_en_ioctl = 1;
2595 + break;
2596 + case PTP_DSBL_RXTS_IOCTL:
2597 + tsu->hwts_rx_en_ioctl = 0;
2598 + break;
2599 + case PTP_GET_RX_TIMESTAMP:
2600 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
2601 + if (copy_from_user(&ptp_data.ident,
2602 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
2603 + return -EINVAL;
2604 +
2605 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
2606 + return -EAGAIN;
2607 +
2608 + if (copy_to_user((void __user *)&ptp_data_user->ts,
2609 + &ptp_data.ts, sizeof(ptp_data.ts)))
2610 + return -EFAULT;
2611 + break;
2612 + case PTP_GET_TX_TIMESTAMP:
2613 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
2614 + if (copy_from_user(&ptp_data.ident,
2615 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
2616 + return -EINVAL;
2617 +
2618 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
2619 + return -EAGAIN;
2620 +
2621 + if (copy_to_user((void __user *)&ptp_data_user->ts,
2622 + &ptp_data.ts, sizeof(ptp_data.ts)))
2623 + return -EFAULT;
2624 + break;
2625 + case PTP_GET_TIME:
2626 + dpa_get_curr_cnt(tsu, &act_time);
2627 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
2628 + return -EFAULT;
2629 + break;
2630 + case PTP_SET_TIME:
2631 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
2632 + return -EINVAL;
2633 + dpa_set_1588cnt(tsu, &act_time);
2634 + break;
2635 + case PTP_GET_ADJ:
2636 + dpa_get_drift(tsu, &addend);
2637 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
2638 + return -EFAULT;
2639 + break;
2640 + case PTP_SET_ADJ:
2641 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
2642 + return -EINVAL;
2643 + dpa_set_drift(tsu, addend);
2644 + break;
2645 + case PTP_SET_FIPER_ALARM:
2646 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
2647 + return -EINVAL;
2648 + dpa_set_fiper_alarm(tsu, &act_time);
2649 + break;
2650 + case PTP_CLEANUP_TS:
2651 + dpa_flush_timestamp(tsu);
2652 + break;
2653 + default:
2654 + return -EINVAL;
2655 + }
2656 +
2657 + return retval;
2658 +}
2659 +
2660 +int dpa_ptp_init(struct dpa_priv_s *priv)
2661 +{
2662 + struct dpa_ptp_tsu *tsu;
2663 +
2664 + /* Allocate memory for PTP structure */
2665 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
2666 + if (!tsu)
2667 + return -ENOMEM;
2668 +
2669 + tsu->valid = TRUE;
2670 + tsu->dpa_priv = priv;
2671 +
2672 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
2673 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
2674 +
2675 + priv->tsu = tsu;
2676 +
2677 + return 0;
2678 +}
2679 +EXPORT_SYMBOL(dpa_ptp_init);
2680 +
2681 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
2682 +{
2683 + struct dpa_ptp_tsu *tsu = priv->tsu;
2684 +
2685 + tsu->valid = FALSE;
2686 + vfree(tsu->rx_timestamps.circ_buf.buf);
2687 + vfree(tsu->tx_timestamps.circ_buf.buf);
2688 +
2689 + kfree(tsu);
2690 +}
2691 +EXPORT_SYMBOL(dpa_ptp_cleanup);
2692 --- /dev/null
2693 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
2694 @@ -0,0 +1,138 @@
2695 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
2696 + *
2697 + * This program is free software; you can redistribute it and/or modify
2698 + * it under the terms of the GNU General Public License as published by
2699 + * the Free Software Foundation; either version 2 of the License, or
2700 + * (at your option) any later version.
2701 + *
2702 + * This program is distributed in the hope that it will be useful,
2703 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2704 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2705 + * GNU General Public License for more details.
2706 + *
2707 + * You should have received a copy of the GNU General Public License along
2708 + * with this program; if not, write to the Free Software Foundation, Inc.,
2709 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2710 + *
2711 + */
2712 +#ifndef __DPAA_1588_H__
2713 +#define __DPAA_1588_H__
2714 +
2715 +#include <linux/netdevice.h>
2716 +#include <linux/etherdevice.h>
2717 +#include <linux/circ_buf.h>
2718 +#include <linux/fsl_qman.h>
2719 +
2720 +#define DEFAULT_PTP_RX_BUF_SZ 256
2721 +#define DEFAULT_PTP_TX_BUF_SZ 256
2722 +
2723 +/* 1588 private ioctl calls */
2724 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
2725 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
2726 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
2727 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
2728 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
2729 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
2730 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
2731 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
2732 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
2733 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
2734 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
2735 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
2736 +
2737 +/* PTP V2 message type */
2738 +enum {
2739 + PTP_MSGTYPE_SYNC = 0x0,
2740 + PTP_MSGTYPE_DELREQ = 0x1,
2741 + PTP_MSGTYPE_PDELREQ = 0x2,
2742 + PTP_MSGTYPE_PDELRESP = 0x3,
2743 + PTP_MSGTYPE_FLWUP = 0x8,
2744 + PTP_MSGTYPE_DELRESP = 0x9,
2745 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
2746 + PTP_MSGTYPE_ANNOUNCE = 0xB,
2747 + PTP_MSGTYPE_SGNLNG = 0xC,
2748 + PTP_MSGTYPE_MNGMNT = 0xD,
2749 +};
2750 +
2751 +/* Byte offset of data in the PTP V2 headers */
2752 +#define PTP_OFFS_MSG_TYPE 0
2753 +#define PTP_OFFS_VER_PTP 1
2754 +#define PTP_OFFS_MSG_LEN 2
2755 +#define PTP_OFFS_DOM_NMB 4
2756 +#define PTP_OFFS_FLAGS 6
2757 +#define PTP_OFFS_CORFIELD 8
2758 +#define PTP_OFFS_SRCPRTID 20
2759 +#define PTP_OFFS_SEQ_ID 30
2760 +#define PTP_OFFS_CTRL 32
2761 +#define PTP_OFFS_LOGMEAN 33
2762 +
2763 +#define PTP_IP_OFFS 14
2764 +#define PTP_UDP_OFFS 34
2765 +#define PTP_HEADER_OFFS 42
2766 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
2767 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
2768 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
2769 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
2770 +
2771 +/* 1588-2008 network protocol enumeration values */
2772 +#define DPA_PTP_PROT_IPV4 1
2773 +#define DPA_PTP_PROT_IPV6 2
2774 +#define DPA_PTP_PROT_802_3 3
2775 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
2776 +
2777 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
2778 +#define DPA_PTP_HEADER_SZE 34
2779 +#define DPA_ETYPE_LEN 2
2780 +#define DPA_VLAN_TAG_LEN 4
2781 +#define NANOSEC_PER_SECOND 1000000000
2782 +
2783 +/* The threshold between the current found one and the oldest one */
2784 +#define TS_ACCUMULATION_THRESHOLD 50
2785 +
2786 +/* Struct needed to identify a timestamp */
2787 +struct dpa_ptp_ident {
2788 + u8 version;
2789 + u8 msg_type;
2790 + u16 netw_prot;
2791 + u16 seq_id;
2792 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
2793 +};
2794 +
2795 +/* Timestamp format in 1588-2008 */
2796 +struct dpa_ptp_time {
2797 + u64 sec; /* just 48 bit used */
2798 + u32 nsec;
2799 +};
2800 +
2801 +/* needed for timestamp data over ioctl */
2802 +struct dpa_ptp_data {
2803 + struct dpa_ptp_ident ident;
2804 + struct dpa_ptp_time ts;
2805 +};
2806 +
2807 +struct dpa_ptp_circ_buf {
2808 + struct circ_buf circ_buf;
2809 + u32 size;
2810 + spinlock_t ptp_lock;
2811 +};
2812 +
2813 +/* PTP TSU control structure */
2814 +struct dpa_ptp_tsu {
2815 + struct dpa_priv_s *dpa_priv;
2816 + bool valid;
2817 + struct dpa_ptp_circ_buf rx_timestamps;
2818 + struct dpa_ptp_circ_buf tx_timestamps;
2819 +
2820 + /* HW timestamping over ioctl enabled flag */
2821 + int hwts_tx_en_ioctl;
2822 + int hwts_rx_en_ioctl;
2823 +};
2824 +
2825 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
2826 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
2827 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
2828 + struct sk_buff *skb, void *data);
2829 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
2830 + struct sk_buff *skb, void *data);
2831 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
2832 +#endif
2833 --- /dev/null
2834 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
2835 @@ -0,0 +1,180 @@
2836 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
2837 + *
2838 + * Redistribution and use in source and binary forms, with or without
2839 + * modification, are permitted provided that the following conditions are met:
2840 + * * Redistributions of source code must retain the above copyright
2841 + * notice, this list of conditions and the following disclaimer.
2842 + * * Redistributions in binary form must reproduce the above copyright
2843 + * notice, this list of conditions and the following disclaimer in the
2844 + * documentation and/or other materials provided with the distribution.
2845 + * * Neither the name of Freescale Semiconductor nor the
2846 + * names of its contributors may be used to endorse or promote products
2847 + * derived from this software without specific prior written permission.
2848 + *
2849 + *
2850 + * ALTERNATIVELY, this software may be distributed under the terms of the
2851 + * GNU General Public License ("GPL") as published by the Free Software
2852 + * Foundation, either version 2 of that License or (at your option) any
2853 + * later version.
2854 + *
2855 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2856 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2857 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2858 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2859 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2860 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2861 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2862 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2863 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2864 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2865 + */
2866 +
2867 +#include <linux/module.h>
2868 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
2869 +#include <linux/debugfs.h>
2870 +#include "dpaa_debugfs.h"
2871 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
2872 +
2873 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
2874 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
2875 +
2876 +static struct dentry *dpa_debugfs_root;
2877 +
2878 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
2879 +static ssize_t dpa_loop_write(struct file *f,
2880 + const char __user *buf, size_t count, loff_t *off);
2881 +
2882 +static const struct file_operations dpa_debugfs_lp_fops = {
2883 + .open = dpa_debugfs_loop_open,
2884 + .write = dpa_loop_write,
2885 + .read = seq_read,
2886 + .llseek = seq_lseek,
2887 + .release = single_release,
2888 +};
2889 +
2890 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
2891 +{
2892 + struct dpa_priv_s *priv;
2893 +
2894 + BUG_ON(offset == NULL);
2895 +
2896 + priv = netdev_priv((struct net_device *)file->private);
2897 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
2898 +
2899 + return 0;
2900 +}
2901 +
2902 +static int user_input_convert(const char __user *user_buf, size_t count,
2903 + long *val)
2904 +{
2905 + char buf[12];
2906 +
2907 + if (count > sizeof(buf) - 1)
2908 + return -EINVAL;
2909 + if (copy_from_user(buf, user_buf, count))
2910 + return -EFAULT;
2911 + buf[count] = '\0';
2912 + if (kstrtol(buf, 0, val))
2913 + return -EINVAL;
2914 + return 0;
2915 +}
2916 +
2917 +static ssize_t dpa_loop_write(struct file *f,
2918 + const char __user *buf, size_t count, loff_t *off)
2919 +{
2920 + struct dpa_priv_s *priv;
2921 + struct net_device *netdev;
2922 + struct seq_file *sf;
2923 + int ret;
2924 + long val;
2925 +
2926 + ret = user_input_convert(buf, count, &val);
2927 + if (ret)
2928 + return ret;
2929 +
2930 + sf = (struct seq_file *)f->private_data;
2931 + netdev = (struct net_device *)sf->private;
2932 + priv = netdev_priv(netdev);
2933 +
2934 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
2935 +
2936 + return count;
2937 +}
2938 +
2939 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
2940 +{
2941 + int _errno;
2942 + const struct net_device *net_dev;
2943 +
2944 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
2945 + if (unlikely(_errno < 0)) {
2946 + net_dev = (struct net_device *)inode->i_private;
2947 +
2948 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
2949 + netdev_err(net_dev, "single_open() = %d\n",
2950 + _errno);
2951 + }
2952 +
2953 + return _errno;
2954 +}
2955 +
2956 +
2957 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
2958 +{
2959 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2960 + static int cnt;
2961 + char loop_file_name[100];
2962 +
2963 + if (unlikely(dpa_debugfs_root == NULL)) {
2964 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
2965 + KBUILD_BASENAME".c", __LINE__, __func__,
2966 + "root debugfs missing, possible module ordering issue");
2967 + return -ENOMEM;
2968 + }
2969 +
2970 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
2971 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
2972 + S_IRUGO,
2973 + dpa_debugfs_root,
2974 + net_dev,
2975 + &dpa_debugfs_lp_fops);
2976 + if (unlikely(priv->debugfs_loop_file == NULL)) {
2977 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
2978 + dpa_debugfs_root->d_iname,
2979 + loop_file_name);
2980 +
2981 + return -ENOMEM;
2982 + }
2983 + return 0;
2984 +}
2985 +
2986 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
2987 +{
2988 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2989 +
2990 + debugfs_remove(priv->debugfs_loop_file);
2991 +}
2992 +
2993 +int __init dpa_debugfs_module_init(void)
2994 +{
2995 + int _errno = 0;
2996 +
2997 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
2998 +
2999 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
3000 +
3001 + if (unlikely(dpa_debugfs_root == NULL)) {
3002 + _errno = -ENOMEM;
3003 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
3004 + KBUILD_BASENAME".c", __LINE__, __func__);
3005 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
3006 + DPA_ETH_DEBUGFS_ROOT, _errno);
3007 + }
3008 +
3009 + return _errno;
3010 +}
3011 +
3012 +void __exit dpa_debugfs_module_exit(void)
3013 +{
3014 + debugfs_remove(dpa_debugfs_root);
3015 +}
3016 --- /dev/null
3017 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
3018 @@ -0,0 +1,43 @@
3019 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
3020 + *
3021 + * Redistribution and use in source and binary forms, with or without
3022 + * modification, are permitted provided that the following conditions are met:
3023 + * * Redistributions of source code must retain the above copyright
3024 + * notice, this list of conditions and the following disclaimer.
3025 + * * Redistributions in binary form must reproduce the above copyright
3026 + * notice, this list of conditions and the following disclaimer in the
3027 + * documentation and/or other materials provided with the distribution.
3028 + * * Neither the name of Freescale Semiconductor nor the
3029 + * names of its contributors may be used to endorse or promote products
3030 + * derived from this software without specific prior written permission.
3031 + *
3032 + *
3033 + * ALTERNATIVELY, this software may be distributed under the terms of the
3034 + * GNU General Public License ("GPL") as published by the Free Software
3035 + * Foundation, either version 2 of that License or (at your option) any
3036 + * later version.
3037 + *
3038 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3039 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3040 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3041 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3042 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3043 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3044 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3045 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3046 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3047 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3048 + */
3049 +
3050 +#ifndef DPAA_DEBUGFS_H_
3051 +#define DPAA_DEBUGFS_H_
3052 +
3053 +#include <linux/netdevice.h>
3054 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
3055 +
3056 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
3057 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
3058 +int __init dpa_debugfs_module_init(void);
3059 +void __exit dpa_debugfs_module_exit(void);
3060 +
3061 +#endif /* DPAA_DEBUGFS_H_ */
3062 --- /dev/null
3063 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
3064 @@ -0,0 +1,1223 @@
3065 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
3066 + *
3067 + * Redistribution and use in source and binary forms, with or without
3068 + * modification, are permitted provided that the following conditions are met:
3069 + * * Redistributions of source code must retain the above copyright
3070 + * notice, this list of conditions and the following disclaimer.
3071 + * * Redistributions in binary form must reproduce the above copyright
3072 + * notice, this list of conditions and the following disclaimer in the
3073 + * documentation and/or other materials provided with the distribution.
3074 + * * Neither the name of Freescale Semiconductor nor the
3075 + * names of its contributors may be used to endorse or promote products
3076 + * derived from this software without specific prior written permission.
3077 + *
3078 + *
3079 + * ALTERNATIVELY, this software may be distributed under the terms of the
3080 + * GNU General Public License ("GPL") as published by the Free Software
3081 + * Foundation, either version 2 of that License or (at your option) any
3082 + * later version.
3083 + *
3084 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3085 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3086 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3087 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3088 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3089 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3090 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3091 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3092 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3093 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3094 + */
3095 +
3096 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3097 +#define pr_fmt(fmt) \
3098 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3099 + KBUILD_BASENAME".c", __LINE__, __func__
3100 +#else
3101 +#define pr_fmt(fmt) \
3102 + KBUILD_MODNAME ": " fmt
3103 +#endif
3104 +
3105 +#include <linux/init.h>
3106 +#include <linux/module.h>
3107 +#include <linux/of_mdio.h>
3108 +#include <linux/of_net.h>
3109 +#include <linux/kthread.h>
3110 +#include <linux/io.h>
3111 +#include <linux/if_arp.h> /* arp_hdr_len() */
3112 +#include <linux/if_vlan.h> /* VLAN_HLEN */
3113 +#include <linux/icmp.h> /* struct icmphdr */
3114 +#include <linux/ip.h> /* struct iphdr */
3115 +#include <linux/ipv6.h> /* struct ipv6hdr */
3116 +#include <linux/udp.h> /* struct udphdr */
3117 +#include <linux/tcp.h> /* struct tcphdr */
3118 +#include <linux/net.h> /* net_ratelimit() */
3119 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
3120 +#include <linux/highmem.h>
3121 +#include <linux/percpu.h>
3122 +#include <linux/dma-mapping.h>
3123 +#include <linux/fsl_bman.h>
3124 +#ifdef CONFIG_SOC_BUS
3125 +#include <linux/sys_soc.h> /* soc_device_match */
3126 +#endif
3127 +
3128 +#include "fsl_fman.h"
3129 +#include "fm_ext.h"
3130 +#include "fm_port_ext.h"
3131 +
3132 +#include "mac.h"
3133 +#include "dpaa_eth.h"
3134 +#include "dpaa_eth_common.h"
3135 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3136 +#include "dpaa_debugfs.h"
3137 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
3138 +
3139 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
3140 + * using trace events only need to #include <trace/events/sched.h>
3141 + */
3142 +#define CREATE_TRACE_POINTS
3143 +#include "dpaa_eth_trace.h"
3144 +
3145 +#define DPA_NAPI_WEIGHT 64
3146 +
3147 +/* Valid checksum indication */
3148 +#define DPA_CSUM_VALID 0xFFFF
3149 +
3150 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
3151 +
3152 +MODULE_LICENSE("Dual BSD/GPL");
3153 +
3154 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
3155 +
3156 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
3157 +
3158 +static uint8_t debug = -1;
3159 +module_param(debug, byte, S_IRUGO);
3160 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
3161 +
3162 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
3163 +static uint16_t tx_timeout = 1000;
3164 +module_param(tx_timeout, ushort, S_IRUGO);
3165 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
3166 +
3167 +static const char rtx[][3] = {
3168 + [RX] = "RX",
3169 + [TX] = "TX"
3170 +};
3171 +
3172 +#ifndef CONFIG_PPC
3173 +bool dpaa_errata_a010022;
3174 +EXPORT_SYMBOL(dpaa_errata_a010022);
3175 +#endif
3176 +
3177 +/* BM */
3178 +
3179 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
3180 +
3181 +static uint8_t dpa_priv_common_bpid;
3182 +
3183 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3184 +struct net_device *dpa_loop_netdevs[20];
3185 +#endif
3186 +
3187 +#ifdef CONFIG_PM
3188 +
3189 +static int dpaa_suspend(struct device *dev)
3190 +{
3191 + struct net_device *net_dev;
3192 + struct dpa_priv_s *priv;
3193 + struct mac_device *mac_dev;
3194 + int err = 0;
3195 +
3196 + net_dev = dev_get_drvdata(dev);
3197 +
3198 + if (net_dev->flags & IFF_UP) {
3199 + priv = netdev_priv(net_dev);
3200 + mac_dev = priv->mac_dev;
3201 +
3202 + if (priv->wol & DPAA_WOL_MAGIC) {
3203 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
3204 + priv->mac_dev->get_mac_handle(mac_dev), true);
3205 + if (err) {
3206 + netdev_err(net_dev, "set_wol() = %d\n", err);
3207 + goto set_wol_failed;
3208 + }
3209 + }
3210 +
3211 + err = fm_port_suspend(mac_dev->port_dev[RX]);
3212 + if (err) {
3213 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
3214 + goto rx_port_suspend_failed;
3215 + }
3216 +
3217 + err = fm_port_suspend(mac_dev->port_dev[TX]);
3218 + if (err) {
3219 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
3220 + goto tx_port_suspend_failed;
3221 + }
3222 + }
3223 +
3224 + return 0;
3225 +
3226 +tx_port_suspend_failed:
3227 + fm_port_resume(mac_dev->port_dev[RX]);
3228 +rx_port_suspend_failed:
3229 + if (priv->wol & DPAA_WOL_MAGIC) {
3230 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
3231 + priv->mac_dev->get_mac_handle(mac_dev), false);
3232 + }
3233 +set_wol_failed:
3234 + return err;
3235 +}
3236 +
3237 +static int dpaa_resume(struct device *dev)
3238 +{
3239 + struct net_device *net_dev;
3240 + struct dpa_priv_s *priv;
3241 + struct mac_device *mac_dev;
3242 + int err = 0;
3243 +
3244 + net_dev = dev_get_drvdata(dev);
3245 +
3246 + if (net_dev->flags & IFF_UP) {
3247 + priv = netdev_priv(net_dev);
3248 + mac_dev = priv->mac_dev;
3249 +
3250 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
3251 + if (err) {
3252 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
3253 + goto resume_failed;
3254 + }
3255 +
3256 + err = fm_port_resume(mac_dev->port_dev[TX]);
3257 + if (err) {
3258 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
3259 + goto resume_failed;
3260 + }
3261 +
3262 + err = fm_port_resume(mac_dev->port_dev[RX]);
3263 + if (err) {
3264 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
3265 + goto resume_failed;
3266 + }
3267 +
3268 + if (priv->wol & DPAA_WOL_MAGIC) {
3269 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
3270 + priv->mac_dev->get_mac_handle(mac_dev), false);
3271 + if (err) {
3272 + netdev_err(net_dev, "set_wol() = %d\n", err);
3273 + goto resume_failed;
3274 + }
3275 + }
3276 + }
3277 +
3278 + return 0;
3279 +
3280 +resume_failed:
3281 + return err;
3282 +}
3283 +
3284 +static const struct dev_pm_ops dpaa_pm_ops = {
3285 + .suspend = dpaa_suspend,
3286 + .resume = dpaa_resume,
3287 +};
3288 +
3289 +#define DPAA_PM_OPS (&dpaa_pm_ops)
3290 +
3291 +#else /* CONFIG_PM */
3292 +
3293 +#define DPAA_PM_OPS NULL
3294 +
3295 +#endif /* CONFIG_PM */
3296 +
3297 +/* Checks whether the checksum field in Parse Results array is valid
3298 + * (equals 0xFFFF) and increments the .cse counter otherwise
3299 + */
3300 +static inline void
3301 +dpa_csum_validation(const struct dpa_priv_s *priv,
3302 + struct dpa_percpu_priv_s *percpu_priv,
3303 + const struct qm_fd *fd)
3304 +{
3305 + dma_addr_t addr = qm_fd_addr(fd);
3306 + struct dpa_bp *dpa_bp = priv->dpa_bp;
3307 + void *frm = phys_to_virt(addr);
3308 + fm_prs_result_t *parse_result;
3309 +
3310 + if (unlikely(!frm))
3311 + return;
3312 +
3313 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
3314 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
3315 +
3316 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
3317 +
3318 + if (parse_result->cksum != DPA_CSUM_VALID)
3319 + percpu_priv->rx_errors.cse++;
3320 +}
3321 +
3322 +static void _dpa_rx_error(struct net_device *net_dev,
3323 + const struct dpa_priv_s *priv,
3324 + struct dpa_percpu_priv_s *percpu_priv,
3325 + const struct qm_fd *fd,
3326 + u32 fqid)
3327 +{
3328 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
3329 + * interference with zero-loss convergence benchmark results.
3330 + */
3331 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
3332 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
3333 + else
3334 + if (netif_msg_hw(priv) && net_ratelimit())
3335 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
3336 + fd->status & FM_FD_STAT_RX_ERRORS);
3337 +#ifdef CONFIG_FSL_DPAA_HOOKS
3338 + if (dpaa_eth_hooks.rx_error &&
3339 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
3340 + /* it's up to the hook to perform resource cleanup */
3341 + return;
3342 +#endif
3343 + percpu_priv->stats.rx_errors++;
3344 +
3345 + if (fd->status & FM_PORT_FRM_ERR_DMA)
3346 + percpu_priv->rx_errors.dme++;
3347 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
3348 + percpu_priv->rx_errors.fpe++;
3349 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
3350 + percpu_priv->rx_errors.fse++;
3351 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
3352 + percpu_priv->rx_errors.phe++;
3353 + if (fd->status & FM_FD_STAT_L4CV)
3354 + dpa_csum_validation(priv, percpu_priv, fd);
3355 +
3356 + dpa_fd_release(net_dev, fd);
3357 +}
3358 +
3359 +static void _dpa_tx_error(struct net_device *net_dev,
3360 + const struct dpa_priv_s *priv,
3361 + struct dpa_percpu_priv_s *percpu_priv,
3362 + const struct qm_fd *fd,
3363 + u32 fqid)
3364 +{
3365 + struct sk_buff *skb;
3366 +
3367 + if (netif_msg_hw(priv) && net_ratelimit())
3368 + netdev_warn(net_dev, "FD status = 0x%08x\n",
3369 + fd->status & FM_FD_STAT_TX_ERRORS);
3370 +#ifdef CONFIG_FSL_DPAA_HOOKS
3371 + if (dpaa_eth_hooks.tx_error &&
3372 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
3373 + /* now the hook must ensure proper cleanup */
3374 + return;
3375 +#endif
3376 + percpu_priv->stats.tx_errors++;
3377 +
3378 + /* If we intended the buffers from this frame to go into the bpools
3379 + * when the FMan transmit was done, we need to put it in manually.
3380 + */
3381 + if (fd->bpid != 0xff) {
3382 + dpa_fd_release(net_dev, fd);
3383 + return;
3384 + }
3385 +
3386 + skb = _dpa_cleanup_tx_fd(priv, fd);
3387 + dev_kfree_skb(skb);
3388 +}
3389 +
3390 +/* Helper function to factor out frame validation logic on all Rx paths. Its
3391 + * purpose is to extract from the Parse Results structure information about
3392 + * the integrity of the frame, its checksum, the length of the parsed headers
3393 + * and whether the frame is suitable for GRO.
3394 + *
3395 + * Assumes no parser errors, since any error frame is dropped before this
3396 + * function is called.
3397 + *
3398 + * @skb will have its ip_summed field overwritten;
3399 + * @use_gro will only be written with 0, if the frame is definitely not
3400 + * GRO-able; otherwise, it will be left unchanged;
3401 + * @hdr_size will be written with a safe value, at least the size of the
3402 + * headers' length.
3403 + */
3404 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3405 + const struct qm_fd *fd,
3406 + struct sk_buff *skb, int *use_gro)
3407 +{
3408 + if (fd->status & FM_FD_STAT_L4CV) {
3409 + /* The parser has run and performed L4 checksum validation.
3410 + * We know there were no parser errors (and implicitly no
3411 + * L4 csum error), otherwise we wouldn't be here.
3412 + */
3413 + skb->ip_summed = CHECKSUM_UNNECESSARY;
3414 +
3415 + /* Don't go through GRO for certain types of traffic that
3416 + * we know are not GRO-able, such as dgram-based protocols.
3417 + * In the worst-case scenarios, such as small-pkt terminating
3418 + * UDP, the extra GRO processing would be overkill.
3419 + *
3420 + * The only protocol the Parser supports that is also GRO-able
3421 + * is currently TCP.
3422 + */
3423 + if (!fm_l4_frame_is_tcp(parse_results))
3424 + *use_gro = 0;
3425 +
3426 + return;
3427 + }
3428 +
3429 + /* We're here because either the parser didn't run or the L4 checksum
3430 + * was not verified. This may include the case of a UDP frame with
3431 + * checksum zero or an L4 proto other than TCP/UDP
3432 + */
3433 + skb->ip_summed = CHECKSUM_NONE;
3434 +
3435 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
3436 + *use_gro = 0;
3437 +}
3438 +
3439 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
3440 +{
3441 + struct dpa_napi_portal *np =
3442 + container_of(napi, struct dpa_napi_portal, napi);
3443 +
3444 + int cleaned = qman_p_poll_dqrr(np->p, budget);
3445 +
3446 + if (cleaned < budget) {
3447 + int tmp;
3448 + napi_complete(napi);
3449 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
3450 + DPA_BUG_ON(tmp);
3451 + }
3452 +
3453 + return cleaned;
3454 +}
3455 +EXPORT_SYMBOL(dpaa_eth_poll);
3456 +
3457 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
3458 + const struct dpa_priv_s *priv,
3459 + struct dpa_percpu_priv_s *percpu_priv,
3460 + const struct qm_fd *fd,
3461 + u32 fqid)
3462 +{
3463 + struct sk_buff *skb;
3464 +
3465 + /* do we need the timestamp for the error frames? */
3466 +
3467 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
3468 + if (netif_msg_hw(priv) && net_ratelimit())
3469 + netdev_warn(net_dev, "FD status = 0x%08x\n",
3470 + fd->status & FM_FD_STAT_TX_ERRORS);
3471 +
3472 + percpu_priv->stats.tx_errors++;
3473 + }
3474 +
3475 + /* hopefully we need not get the timestamp before the hook */
3476 +#ifdef CONFIG_FSL_DPAA_HOOKS
3477 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
3478 + fd, fqid) == DPAA_ETH_STOLEN)
3479 + /* it's the hook that must now perform cleanup */
3480 + return;
3481 +#endif
3482 + /* This might not perfectly reflect the reality, if the core dequeuing
3483 + * the Tx confirmation is different from the one that did the enqueue,
3484 + * but at least it'll show up in the total count.
3485 + */
3486 + percpu_priv->tx_confirm++;
3487 +
3488 + skb = _dpa_cleanup_tx_fd(priv, fd);
3489 +
3490 + dev_kfree_skb(skb);
3491 +}
3492 +
3493 +enum qman_cb_dqrr_result
3494 +priv_rx_error_dqrr(struct qman_portal *portal,
3495 + struct qman_fq *fq,
3496 + const struct qm_dqrr_entry *dq)
3497 +{
3498 + struct net_device *net_dev;
3499 + struct dpa_priv_s *priv;
3500 + struct dpa_percpu_priv_s *percpu_priv;
3501 + int *count_ptr;
3502 +
3503 + net_dev = ((struct dpa_fq *)fq)->net_dev;
3504 + priv = netdev_priv(net_dev);
3505 +
3506 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
3507 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
3508 +
3509 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
3510 + return qman_cb_dqrr_stop;
3511 +
3512 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
3513 + /* Unable to refill the buffer pool due to insufficient
3514 + * system memory. Just release the frame back into the pool,
3515 + * otherwise we'll soon end up with an empty buffer pool.
3516 + */
3517 + dpa_fd_release(net_dev, &dq->fd);
3518 + else
3519 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
3520 +
3521 + return qman_cb_dqrr_consume;
3522 +}
3523 +
3524 +
3525 +enum qman_cb_dqrr_result __hot
3526 +priv_rx_default_dqrr(struct qman_portal *portal,
3527 + struct qman_fq *fq,
3528 + const struct qm_dqrr_entry *dq)
3529 +{
3530 + struct net_device *net_dev;
3531 + struct dpa_priv_s *priv;
3532 + struct dpa_percpu_priv_s *percpu_priv;
3533 + int *count_ptr;
3534 + struct dpa_bp *dpa_bp;
3535 +
3536 + net_dev = ((struct dpa_fq *)fq)->net_dev;
3537 + priv = netdev_priv(net_dev);
3538 + dpa_bp = priv->dpa_bp;
3539 +
3540 + /* Trace the Rx fd */
3541 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
3542 +
3543 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
3544 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
3545 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
3546 +
3547 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
3548 + return qman_cb_dqrr_stop;
3549 +
3550 + /* Vale of plenty: make sure we didn't run out of buffers */
3551 +
3552 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
3553 + /* Unable to refill the buffer pool due to insufficient
3554 + * system memory. Just release the frame back into the pool,
3555 + * otherwise we'll soon end up with an empty buffer pool.
3556 + */
3557 + dpa_fd_release(net_dev, &dq->fd);
3558 + else
3559 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
3560 + count_ptr);
3561 +
3562 + return qman_cb_dqrr_consume;
3563 +}
3564 +
3565 +enum qman_cb_dqrr_result
3566 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
3567 + struct qman_fq *fq,
3568 + const struct qm_dqrr_entry *dq)
3569 +{
3570 + struct net_device *net_dev;
3571 + struct dpa_priv_s *priv;
3572 + struct dpa_percpu_priv_s *percpu_priv;
3573 +
3574 + net_dev = ((struct dpa_fq *)fq)->net_dev;
3575 + priv = netdev_priv(net_dev);
3576 +
3577 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
3578 +
3579 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
3580 + return qman_cb_dqrr_stop;
3581 +
3582 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
3583 +
3584 + return qman_cb_dqrr_consume;
3585 +}
3586 +
3587 +enum qman_cb_dqrr_result __hot
3588 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
3589 + struct qman_fq *fq,
3590 + const struct qm_dqrr_entry *dq)
3591 +{
3592 + struct net_device *net_dev;
3593 + struct dpa_priv_s *priv;
3594 + struct dpa_percpu_priv_s *percpu_priv;
3595 +
3596 + net_dev = ((struct dpa_fq *)fq)->net_dev;
3597 + priv = netdev_priv(net_dev);
3598 +
3599 + /* Trace the fd */
3600 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
3601 +
3602 + /* Non-migratable context, safe to use raw_cpu_ptr */
3603 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
3604 +
3605 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
3606 + return qman_cb_dqrr_stop;
3607 +
3608 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
3609 +
3610 + return qman_cb_dqrr_consume;
3611 +}
3612 +
3613 +void priv_ern(struct qman_portal *portal,
3614 + struct qman_fq *fq,
3615 + const struct qm_mr_entry *msg)
3616 +{
3617 + struct net_device *net_dev;
3618 + const struct dpa_priv_s *priv;
3619 + struct sk_buff *skb;
3620 + struct dpa_percpu_priv_s *percpu_priv;
3621 + struct qm_fd fd = msg->ern.fd;
3622 +
3623 + net_dev = ((struct dpa_fq *)fq)->net_dev;
3624 + priv = netdev_priv(net_dev);
3625 + /* Non-migratable context, safe to use raw_cpu_ptr */
3626 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
3627 +
3628 + percpu_priv->stats.tx_dropped++;
3629 + percpu_priv->stats.tx_fifo_errors++;
3630 + count_ern(percpu_priv, msg);
3631 +
3632 + /* If we intended this buffer to go into the pool
3633 + * when the FM was done, we need to put it in
3634 + * manually.
3635 + */
3636 + if (msg->ern.fd.bpid != 0xff) {
3637 + dpa_fd_release(net_dev, &fd);
3638 + return;
3639 + }
3640 +
3641 + skb = _dpa_cleanup_tx_fd(priv, &fd);
3642 + dev_kfree_skb_any(skb);
3643 +}
3644 +
3645 +const struct dpa_fq_cbs_t private_fq_cbs = {
3646 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
3647 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
3648 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
3649 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
3650 + .egress_ern = { .cb = { .ern = priv_ern } }
3651 +};
3652 +EXPORT_SYMBOL(private_fq_cbs);
3653 +
3654 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
3655 +{
3656 + struct dpa_percpu_priv_s *percpu_priv;
3657 + int i, j;
3658 +
3659 + for_each_possible_cpu(i) {
3660 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
3661 +
3662 + for (j = 0; j < qman_portal_max; j++)
3663 + napi_enable(&percpu_priv->np[j].napi);
3664 + }
3665 +}
3666 +
3667 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
3668 +{
3669 + struct dpa_percpu_priv_s *percpu_priv;
3670 + int i, j;
3671 +
3672 + for_each_possible_cpu(i) {
3673 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
3674 +
3675 + for (j = 0; j < qman_portal_max; j++)
3676 + napi_disable(&percpu_priv->np[j].napi);
3677 + }
3678 +}
3679 +
3680 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
3681 +{
3682 + int err;
3683 + struct dpa_priv_s *priv;
3684 +
3685 + priv = netdev_priv(net_dev);
3686 +
3687 + dpaa_eth_napi_enable(priv);
3688 +
3689 + err = dpa_start(net_dev);
3690 + if (err < 0)
3691 + dpaa_eth_napi_disable(priv);
3692 +
3693 + return err;
3694 +}
3695 +
3696 +
3697 +
3698 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
3699 +{
3700 + int _errno;
3701 + struct dpa_priv_s *priv;
3702 +
3703 + _errno = dpa_stop(net_dev);
3704 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
3705 + * ingress queues. This is to avoid a race between the current
3706 + * context and ksoftirqd which could leave NAPI disabled while
3707 + * in fact there's still Rx traffic to be processed.
3708 + */
3709 + usleep_range(5000, 10000);
3710 +
3711 + priv = netdev_priv(net_dev);
3712 + dpaa_eth_napi_disable(priv);
3713 +
3714 + return _errno;
3715 +}
3716 +
3717 +#ifdef CONFIG_NET_POLL_CONTROLLER
3718 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
3719 +{
3720 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3721 + struct dpa_percpu_priv_s *percpu_priv =
3722 + raw_cpu_ptr(priv->percpu_priv);
3723 + struct qman_portal *p;
3724 + const struct qman_portal_config *pc;
3725 + struct dpa_napi_portal *np;
3726 +
3727 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
3728 + pc = qman_p_get_portal_config(p);
3729 + np = &percpu_priv->np[pc->index];
3730 +
3731 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
3732 + qman_p_poll_dqrr(np->p, np->napi.weight);
3733 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
3734 +}
3735 +#endif
3736 +
3737 +static const struct net_device_ops dpa_private_ops = {
3738 + .ndo_open = dpa_eth_priv_start,
3739 + .ndo_start_xmit = dpa_tx,
3740 + .ndo_stop = dpa_eth_priv_stop,
3741 + .ndo_tx_timeout = dpa_timeout,
3742 + .ndo_get_stats64 = dpa_get_stats64,
3743 + .ndo_set_mac_address = dpa_set_mac_address,
3744 + .ndo_validate_addr = eth_validate_addr,
3745 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
3746 + .ndo_select_queue = dpa_select_queue,
3747 +#endif
3748 + .ndo_set_rx_mode = dpa_set_rx_mode,
3749 + .ndo_init = dpa_ndo_init,
3750 + .ndo_set_features = dpa_set_features,
3751 + .ndo_fix_features = dpa_fix_features,
3752 + .ndo_do_ioctl = dpa_ioctl,
3753 +#ifdef CONFIG_NET_POLL_CONTROLLER
3754 + .ndo_poll_controller = dpaa_eth_poll_controller,
3755 +#endif
3756 +};
3757 +
3758 +static int dpa_private_napi_add(struct net_device *net_dev)
3759 +{
3760 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3761 + struct dpa_percpu_priv_s *percpu_priv;
3762 + int i, cpu;
3763 +
3764 + for_each_possible_cpu(cpu) {
3765 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
3766 +
3767 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
3768 + qman_portal_max * sizeof(struct dpa_napi_portal),
3769 + GFP_KERNEL);
3770 +
3771 + if (unlikely(percpu_priv->np == NULL)) {
3772 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
3773 + return -ENOMEM;
3774 + }
3775 +
3776 + for (i = 0; i < qman_portal_max; i++)
3777 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
3778 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
3779 + }
3780 +
3781 + return 0;
3782 +}
3783 +
3784 +void dpa_private_napi_del(struct net_device *net_dev)
3785 +{
3786 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3787 + struct dpa_percpu_priv_s *percpu_priv;
3788 + int i, cpu;
3789 +
3790 + for_each_possible_cpu(cpu) {
3791 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
3792 +
3793 + if (percpu_priv->np) {
3794 + for (i = 0; i < qman_portal_max; i++)
3795 + netif_napi_del(&percpu_priv->np[i].napi);
3796 +
3797 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
3798 + }
3799 + }
3800 +}
3801 +EXPORT_SYMBOL(dpa_private_napi_del);
3802 +
3803 +static int dpa_private_netdev_init(struct net_device *net_dev)
3804 +{
3805 + int i;
3806 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3807 + struct dpa_percpu_priv_s *percpu_priv;
3808 + const uint8_t *mac_addr;
3809 +
3810 + /* Although we access another CPU's private data here
3811 + * we do it at initialization so it is safe
3812 + */
3813 + for_each_possible_cpu(i) {
3814 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
3815 + percpu_priv->net_dev = net_dev;
3816 + }
3817 +
3818 + net_dev->netdev_ops = &dpa_private_ops;
3819 + mac_addr = priv->mac_dev->addr;
3820 +
3821 + net_dev->mem_start = priv->mac_dev->res->start;
3822 + net_dev->mem_end = priv->mac_dev->res->end;
3823 +
3824 + /* Configure the maximum MTU according to the FMan's MAXFRM */
3825 + net_dev->min_mtu = ETH_MIN_MTU;
3826 + net_dev->max_mtu = dpa_get_max_mtu();
3827 +
3828 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
3829 + NETIF_F_LLTX);
3830 +
3831 + /* Advertise S/G and HIGHDMA support for private interfaces */
3832 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
3833 + /* Recent kernels enable GSO automatically, if
3834 + * we declare NETIF_F_SG. For conformity, we'll
3835 + * still declare GSO explicitly.
3836 + */
3837 + net_dev->features |= NETIF_F_GSO;
3838 +
3839 + /* Advertise GRO support */
3840 + net_dev->features |= NETIF_F_GRO;
3841 +
3842 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
3843 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
3844 +
3845 +#ifndef CONFIG_PPC
3846 + /* Due to the A010022 FMan errata, we can not use S/G frames. We need
3847 + * to stop advertising S/G and GSO support.
3848 + */
3849 + if (unlikely(dpaa_errata_a010022)) {
3850 + net_dev->hw_features &= ~NETIF_F_SG;
3851 + net_dev->features &= ~NETIF_F_GSO;
3852 + }
3853 +#endif
3854 +
3855 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
3856 +}
3857 +
3858 +static struct dpa_bp * __cold
3859 +dpa_priv_bp_probe(struct device *dev)
3860 +{
3861 + struct dpa_bp *dpa_bp;
3862 +
3863 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
3864 + if (unlikely(dpa_bp == NULL)) {
3865 + dev_err(dev, "devm_kzalloc() failed\n");
3866 + return ERR_PTR(-ENOMEM);
3867 + }
3868 +
3869 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
3870 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
3871 +
3872 + dpa_bp->seed_cb = dpa_bp_priv_seed;
3873 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
3874 +
3875 + return dpa_bp;
3876 +}
3877 +
3878 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
3879 + * We won't be sending congestion notifications to FMan; for now, we just use
3880 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
3881 + * before they reach our ingress queues and eat up memory.
3882 + */
3883 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
3884 +{
3885 + struct qm_mcc_initcgr initcgr;
3886 + u32 cs_th;
3887 + int err;
3888 +
3889 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
3890 + if (err < 0) {
3891 + pr_err("Error %d allocating CGR ID\n", err);
3892 + goto out_error;
3893 + }
3894 +
3895 + /* Enable CS TD, but disable Congestion State Change Notifications. */
3896 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
3897 + initcgr.cgr.cscn_en = QM_CGR_EN;
3898 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
3899 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
3900 +
3901 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
3902 + initcgr.cgr.cstd_en = QM_CGR_EN;
3903 +
3904 + /* This is actually a hack, because this CGR will be associated with
3905 + * our affine SWP. However, we'll place our ingress FQs in it.
3906 + */
3907 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
3908 + &initcgr);
3909 + if (err < 0) {
3910 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
3911 + priv->ingress_cgr.cgrid);
3912 + qman_release_cgrid(priv->ingress_cgr.cgrid);
3913 + goto out_error;
3914 + }
3915 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
3916 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
3917 +
3918 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
3919 + * range), but we have no common initialization path between the
3920 + * different variants of the DPAA Eth driver, so we do it here rather
3921 + * than modifying every other variant than "private Eth".
3922 + */
3923 + priv->use_ingress_cgr = true;
3924 +
3925 +out_error:
3926 + return err;
3927 +}
3928 +
3929 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3930 + size_t count)
3931 +{
3932 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3933 + int i;
3934 +
3935 + if (netif_msg_probe(priv))
3936 + dev_dbg(net_dev->dev.parent,
3937 + "Using private BM buffer pools\n");
3938 +
3939 + priv->bp_count = count;
3940 +
3941 + for (i = 0; i < count; i++) {
3942 + int err;
3943 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
3944 + if (err < 0) {
3945 + dpa_bp_free(priv);
3946 + priv->dpa_bp = NULL;
3947 + return err;
3948 + }
3949 +
3950 + priv->dpa_bp = &dpa_bp[i];
3951 + }
3952 +
3953 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
3954 + return 0;
3955 +}
3956 +
3957 +static const struct of_device_id dpa_match[];
3958 +
3959 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3960 +static int dpa_new_loop_id(void)
3961 +{
3962 + static int if_id;
3963 +
3964 + return if_id++;
3965 +}
3966 +#endif
3967 +
3968 +static int
3969 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
3970 +{
3971 + int err = 0, i, channel;
3972 + struct device *dev;
3973 + struct device_node *dpa_node;
3974 + struct dpa_bp *dpa_bp;
3975 + size_t count = 1;
3976 + struct net_device *net_dev = NULL;
3977 + struct dpa_priv_s *priv = NULL;
3978 + struct dpa_percpu_priv_s *percpu_priv;
3979 + struct fm_port_fqs port_fqs;
3980 + struct dpa_buffer_layout_s *buf_layout = NULL;
3981 + struct mac_device *mac_dev;
3982 +
3983 + dev = &_of_dev->dev;
3984 +
3985 + dpa_node = dev->of_node;
3986 +
3987 + if (!of_device_is_available(dpa_node))
3988 + return -ENODEV;
3989 +
3990 + /* Get the buffer pools assigned to this interface;
3991 + * run only once the default pool probing code
3992 + */
3993 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
3994 + dpa_priv_bp_probe(dev);
3995 + if (IS_ERR(dpa_bp))
3996 + return PTR_ERR(dpa_bp);
3997 +
3998 + /* Allocate this early, so we can store relevant information in
3999 + * the private area (needed by 1588 code in dpa_mac_probe)
4000 + */
4001 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
4002 + if (!net_dev) {
4003 + dev_err(dev, "alloc_etherdev_mq() failed\n");
4004 + goto alloc_etherdev_mq_failed;
4005 + }
4006 +
4007 + /* Do this here, so we can be verbose early */
4008 + SET_NETDEV_DEV(net_dev, dev);
4009 + dev_set_drvdata(dev, net_dev);
4010 +
4011 + priv = netdev_priv(net_dev);
4012 + priv->net_dev = net_dev;
4013 + strcpy(priv->if_type, "private");
4014 +
4015 + priv->msg_enable = netif_msg_init(debug, -1);
4016 +
4017 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4018 + priv->loop_id = dpa_new_loop_id();
4019 + priv->loop_to = -1; /* disabled by default */
4020 + dpa_loop_netdevs[priv->loop_id] = net_dev;
4021 +#endif
4022 +
4023 + mac_dev = dpa_mac_probe(_of_dev);
4024 + if (IS_ERR(mac_dev) || !mac_dev) {
4025 + err = PTR_ERR(mac_dev);
4026 + goto mac_probe_failed;
4027 + }
4028 +
4029 + /* We have physical ports, so we need to establish
4030 + * the buffer layout.
4031 + */
4032 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
4033 + GFP_KERNEL);
4034 + if (!buf_layout) {
4035 + dev_err(dev, "devm_kzalloc() failed\n");
4036 + goto alloc_failed;
4037 + }
4038 + dpa_set_buffers_layout(mac_dev, buf_layout);
4039 +
4040 + /* For private ports, need to compute the size of the default
4041 + * buffer pool, based on FMan port buffer layout;also update
4042 + * the maximum buffer size for private ports if necessary
4043 + */
4044 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
4045 +
4046 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
4047 + /* We only want to use jumbo frame optimization if we actually have
4048 + * L2 MAX FRM set for jumbo frames as well.
4049 + */
4050 + if(fm_get_max_frm() < 9600)
4051 + dev_warn(dev,
4052 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
4053 +#endif
4054 +
4055 + INIT_LIST_HEAD(&priv->dpa_fq_list);
4056 +
4057 + memset(&port_fqs, 0, sizeof(port_fqs));
4058 +
4059 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
4060 + if (!err)
4061 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
4062 + &port_fqs, true, TX);
4063 +
4064 + if (err < 0)
4065 + goto fq_probe_failed;
4066 +
4067 + /* bp init */
4068 +
4069 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
4070 +
4071 + if (err < 0)
4072 + goto bp_create_failed;
4073 +
4074 + priv->mac_dev = mac_dev;
4075 +
4076 + channel = dpa_get_channel();
4077 +
4078 + if (channel < 0) {
4079 + err = channel;
4080 + goto get_channel_failed;
4081 + }
4082 +
4083 + priv->channel = (uint16_t)channel;
4084 + dpaa_eth_add_channel(priv->channel);
4085 +
4086 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
4087 +
4088 + /* Create a congestion group for this netdev, with
4089 + * dynamically-allocated CGR ID.
4090 + * Must be executed after probing the MAC, but before
4091 + * assigning the egress FQs to the CGRs.
4092 + */
4093 + err = dpaa_eth_cgr_init(priv);
4094 + if (err < 0) {
4095 + dev_err(dev, "Error initializing CGR\n");
4096 + goto tx_cgr_init_failed;
4097 + }
4098 + err = dpaa_eth_priv_ingress_cgr_init(priv);
4099 + if (err < 0) {
4100 + dev_err(dev, "Error initializing ingress CGR\n");
4101 + goto rx_cgr_init_failed;
4102 + }
4103 +
4104 + /* Add the FQs to the interface, and make them active */
4105 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
4106 + if (err < 0)
4107 + goto fq_alloc_failed;
4108 +
4109 + priv->buf_layout = buf_layout;
4110 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
4111 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
4112 +
4113 + /* All real interfaces need their ports initialized */
4114 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
4115 + buf_layout, dev);
4116 +
4117 +#ifdef CONFIG_FMAN_PFC
4118 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
4119 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
4120 + mac_dev->port_dev[TX], i, i);
4121 + if (unlikely(err != 0)) {
4122 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
4123 + goto pfc_mapping_failed;
4124 + }
4125 + }
4126 +#endif
4127 +
4128 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
4129 +
4130 + if (priv->percpu_priv == NULL) {
4131 + dev_err(dev, "devm_alloc_percpu() failed\n");
4132 + err = -ENOMEM;
4133 + goto alloc_percpu_failed;
4134 + }
4135 + for_each_possible_cpu(i) {
4136 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
4137 + memset(percpu_priv, 0, sizeof(*percpu_priv));
4138 + }
4139 +
4140 + /* Initialize NAPI */
4141 + err = dpa_private_napi_add(net_dev);
4142 +
4143 + if (err < 0)
4144 + goto napi_add_failed;
4145 +
4146 + err = dpa_private_netdev_init(net_dev);
4147 +
4148 + if (err < 0)
4149 + goto netdev_init_failed;
4150 +
4151 + dpaa_eth_sysfs_init(&net_dev->dev);
4152 +
4153 +#ifdef CONFIG_PM
4154 + device_set_wakeup_capable(dev, true);
4155 +#endif
4156 +
4157 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
4158 +
4159 + return 0;
4160 +
4161 +netdev_init_failed:
4162 +napi_add_failed:
4163 + dpa_private_napi_del(net_dev);
4164 +alloc_percpu_failed:
4165 +#ifdef CONFIG_FMAN_PFC
4166 +pfc_mapping_failed:
4167 +#endif
4168 + dpa_fq_free(dev, &priv->dpa_fq_list);
4169 +fq_alloc_failed:
4170 + qman_delete_cgr_safe(&priv->ingress_cgr);
4171 + qman_release_cgrid(priv->ingress_cgr.cgrid);
4172 +rx_cgr_init_failed:
4173 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
4174 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
4175 +tx_cgr_init_failed:
4176 +get_channel_failed:
4177 + dpa_bp_free(priv);
4178 +bp_create_failed:
4179 +fq_probe_failed:
4180 +alloc_failed:
4181 +mac_probe_failed:
4182 + dev_set_drvdata(dev, NULL);
4183 + free_netdev(net_dev);
4184 +alloc_etherdev_mq_failed:
4185 + if (atomic_read(&dpa_bp->refs) == 0)
4186 + devm_kfree(dev, dpa_bp);
4187 +
4188 + return err;
4189 +}
4190 +
4191 +static const struct of_device_id dpa_match[] = {
4192 + {
4193 + .compatible = "fsl,dpa-ethernet"
4194 + },
4195 + {}
4196 +};
4197 +MODULE_DEVICE_TABLE(of, dpa_match);
4198 +
4199 +static struct platform_driver dpa_driver = {
4200 + .driver = {
4201 + .name = KBUILD_MODNAME,
4202 + .of_match_table = dpa_match,
4203 + .owner = THIS_MODULE,
4204 + .pm = DPAA_PM_OPS,
4205 + },
4206 + .probe = dpaa_eth_priv_probe,
4207 + .remove = dpa_remove
4208 +};
4209 +
4210 +#ifndef CONFIG_PPC
4211 +static bool __init __cold soc_has_errata_a010022(void)
4212 +{
4213 +#ifdef CONFIG_SOC_BUS
4214 + const struct soc_device_attribute soc_msi_matches[] = {
4215 + { .family = "QorIQ LS1043A",
4216 + .data = NULL },
4217 + { },
4218 + };
4219 +
4220 + if (soc_device_match(soc_msi_matches))
4221 + return true;
4222 +
4223 + return false;
4224 +#else
4225 + return true; /* cannot identify SoC */
4226 +#endif
4227 +}
4228 +#endif
4229 +
4230 +static int __init __cold dpa_load(void)
4231 +{
4232 + int _errno;
4233 +
4234 + pr_info(DPA_DESCRIPTION "\n");
4235 +
4236 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4237 + dpa_debugfs_module_init();
4238 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
4239 +
4240 + /* initialise dpaa_eth mirror values */
4241 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
4242 + dpa_max_frm = fm_get_max_frm();
4243 + dpa_num_cpus = num_possible_cpus();
4244 +
4245 +#ifndef CONFIG_PPC
4246 + /* Detect if the current SoC requires the 4K alignment workaround */
4247 + dpaa_errata_a010022 = soc_has_errata_a010022();
4248 +#endif
4249 +
4250 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4251 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
4252 +#endif
4253 +
4254 + _errno = platform_driver_register(&dpa_driver);
4255 + if (unlikely(_errno < 0)) {
4256 + pr_err(KBUILD_MODNAME
4257 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
4258 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
4259 + }
4260 +
4261 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
4262 + KBUILD_BASENAME".c", __func__);
4263 +
4264 + return _errno;
4265 +}
4266 +module_init(dpa_load);
4267 +
4268 +static void __exit __cold dpa_unload(void)
4269 +{
4270 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
4271 + KBUILD_BASENAME".c", __func__);
4272 +
4273 + platform_driver_unregister(&dpa_driver);
4274 +
4275 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4276 + dpa_debugfs_module_exit();
4277 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
4278 +
4279 + /* Only one channel is used and needs to be relased after all
4280 + * interfaces are removed
4281 + */
4282 + dpa_release_channel();
4283 +
4284 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
4285 + KBUILD_BASENAME".c", __func__);
4286 +}
4287 +module_exit(dpa_unload);
4288 --- /dev/null
4289 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
4290 @@ -0,0 +1,691 @@
4291 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
4292 + *
4293 + * Redistribution and use in source and binary forms, with or without
4294 + * modification, are permitted provided that the following conditions are met:
4295 + * * Redistributions of source code must retain the above copyright
4296 + * notice, this list of conditions and the following disclaimer.
4297 + * * Redistributions in binary form must reproduce the above copyright
4298 + * notice, this list of conditions and the following disclaimer in the
4299 + * documentation and/or other materials provided with the distribution.
4300 + * * Neither the name of Freescale Semiconductor nor the
4301 + * names of its contributors may be used to endorse or promote products
4302 + * derived from this software without specific prior written permission.
4303 + *
4304 + *
4305 + * ALTERNATIVELY, this software may be distributed under the terms of the
4306 + * GNU General Public License ("GPL") as published by the Free Software
4307 + * Foundation, either version 2 of that License or (at your option) any
4308 + * later version.
4309 + *
4310 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
4311 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4312 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4313 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
4314 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4315 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4316 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4317 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4318 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4319 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4320 + */
4321 +
4322 +#ifndef __DPA_H
4323 +#define __DPA_H
4324 +
4325 +#include <linux/netdevice.h>
4326 +#include <linux/fsl_qman.h> /* struct qman_fq */
4327 +
4328 +#include "fm_ext.h"
4329 +#include "dpaa_eth_trace.h"
4330 +
4331 +extern int dpa_rx_extra_headroom;
4332 +extern int dpa_max_frm;
4333 +extern int dpa_num_cpus;
4334 +
4335 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
4336 +#define dpa_get_max_frm() dpa_max_frm
4337 +
4338 +#define dpa_get_max_mtu() \
4339 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
4340 +
4341 +#define __hot
4342 +
4343 +/* Simple enum of FQ types - used for array indexing */
4344 +enum port_type {RX, TX};
4345 +
4346 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
4347 +struct dpa_buffer_layout_s {
4348 + uint16_t priv_data_size;
4349 + bool parse_results;
4350 + bool time_stamp;
4351 + bool hash_results;
4352 + uint8_t manip_extra_space;
4353 + uint16_t data_align;
4354 +};
4355 +
4356 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
4357 +#define DPA_BUG_ON(cond) BUG_ON(cond)
4358 +#else
4359 +#define DPA_BUG_ON(cond)
4360 +#endif
4361 +
4362 +#define DPA_TX_PRIV_DATA_SIZE 16
4363 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
4364 +#define DPA_TIME_STAMP_SIZE 8
4365 +#define DPA_HASH_RESULTS_SIZE 8
4366 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
4367 + dpa_get_rx_extra_headroom())
4368 +
4369 +#define FM_FD_STAT_RX_ERRORS \
4370 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
4371 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
4372 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
4373 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
4374 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
4375 +
4376 +#define FM_FD_STAT_TX_ERRORS \
4377 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
4378 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
4379 +
4380 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
4381 +/* The raw buffer size must be cacheline aligned.
4382 + * Normally we use 2K buffers.
4383 + */
4384 +#define DPA_BP_RAW_SIZE 2048
4385 +#else
4386 +/* For jumbo frame optimizations, use buffers large enough to accommodate
4387 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
4388 + * space to account for further alignments.
4389 + */
4390 +#define DPA_MAX_FRM_SIZE 9600
4391 +#ifdef CONFIG_PPC
4392 +#define DPA_BP_RAW_SIZE \
4393 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
4394 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
4395 +#else /* CONFIG_PPC */
4396 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
4397 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
4398 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
4399 +#endif /* CONFIG_PPC */
4400 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
4401 +
4402 +/* This is what FMan is ever allowed to use.
4403 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
4404 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
4405 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
4406 + * half-page-aligned buffers (can we?), so we reserve some more space
4407 + * for start-of-buffer alignment.
4408 + */
4409 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
4410 + SMP_CACHE_BYTES)
4411 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
4412 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
4413 +
4414 +/* Maximum size of a buffer for which recycling is allowed.
4415 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
4416 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
4417 + * that skbs allocated by us will not fail to be recycled due to their size.
4418 + *
4419 + * For a requested size, the kernel allocator provides the next power of two
4420 + * sized block, which the stack will use as is, regardless of the actual size
4421 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
4422 + * supported frame size), set the recycling upper limit to 16K.
4423 + */
4424 +#define DPA_RECYCLE_MAX_SIZE 16384
4425 +
4426 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
4427 +/*TODO: temporary for fman pcd testing */
4428 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
4429 +#endif
4430 +
4431 +#define DPAA_ETH_FQ_DELTA 0x10000
4432 +
4433 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
4434 + (((device_addr) & 0x1fffff) >> 6)
4435 +
4436 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
4437 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
4438 +
4439 +/* Largest value that the FQD's OAL field can hold.
4440 + * This is DPAA-1.x specific.
4441 + * TODO: This rather belongs in fsl_qman.h
4442 + */
4443 +#define FSL_QMAN_MAX_OAL 127
4444 +
4445 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
4446 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
4447 +
4448 +/* Default alignment for start of data in an Rx FD */
4449 +#define DPA_FD_DATA_ALIGNMENT 16
4450 +
4451 +/* Values for the L3R field of the FM Parse Results
4452 + */
4453 +/* L3 Type field: First IP Present IPv4 */
4454 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
4455 +/* L3 Type field: First IP Present IPv6 */
4456 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
4457 +
4458 +/* Values for the L4R field of the FM Parse Results
4459 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
4460 + */
4461 +/* L4 Type field: UDP */
4462 +#define FM_L4_PARSE_RESULT_UDP 0x40
4463 +/* L4 Type field: TCP */
4464 +#define FM_L4_PARSE_RESULT_TCP 0x20
4465 +/* FD status field indicating whether the FM Parser has attempted to validate
4466 + * the L4 csum of the frame.
4467 + * Note that having this bit set doesn't necessarily imply that the checksum
4468 + * is valid. One would have to check the parse results to find that out.
4469 + */
4470 +#define FM_FD_STAT_L4CV 0x00000004
4471 +
4472 +
4473 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
4474 +
4475 +/* Check if the parsed frame was found to be a TCP segment.
4476 + *
4477 + * @parse_result_ptr must be of type (fm_prs_result_t *).
4478 + */
4479 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
4480 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
4481 +
4482 +/* number of Tx queues to FMan */
4483 +#ifdef CONFIG_FMAN_PFC
4484 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
4485 +#else
4486 +#define DPAA_ETH_TX_QUEUES NR_CPUS
4487 +#endif
4488 +
4489 +#define DPAA_ETH_RX_QUEUES 128
4490 +
4491 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
4492 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
4493 + * was allocated by ourselves, respectively by the stack. In the former case,
4494 + * we could store the skb at negative offset; in the latter case, we can't,
4495 + * so we'll use 0 as offset.
4496 + *
4497 + * NB: @off is an offset from a (struct sk_buff **) pointer!
4498 + */
4499 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
4500 +{ \
4501 + skbh = (struct sk_buff **)addr; \
4502 + *(skbh + (off)) = skb; \
4503 +}
4504 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
4505 +{ \
4506 + skbh = (struct sk_buff **)addr; \
4507 + skb = *(skbh + (off)); \
4508 +}
4509 +
4510 +#ifdef CONFIG_PM
4511 +/* Magic Packet wakeup */
4512 +#define DPAA_WOL_MAGIC 0x00000001
4513 +#endif
4514 +
4515 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
4516 +struct pcd_range {
4517 + uint32_t base;
4518 + uint32_t count;
4519 +};
4520 +#endif
4521 +
4522 +/* More detailed FQ types - used for fine-grained WQ assignments */
4523 +enum dpa_fq_type {
4524 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
4525 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
4526 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
4527 + FQ_TYPE_TX, /* "Real" Tx FQs */
4528 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
4529 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
4530 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
4531 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
4532 +};
4533 +
4534 +struct dpa_fq {
4535 + struct qman_fq fq_base;
4536 + struct list_head list;
4537 + struct net_device *net_dev;
4538 + bool init;
4539 + uint32_t fqid;
4540 + uint32_t flags;
4541 + uint16_t channel;
4542 + uint8_t wq;
4543 + enum dpa_fq_type fq_type;
4544 +};
4545 +
4546 +struct dpa_fq_cbs_t {
4547 + struct qman_fq rx_defq;
4548 + struct qman_fq tx_defq;
4549 + struct qman_fq rx_errq;
4550 + struct qman_fq tx_errq;
4551 + struct qman_fq egress_ern;
4552 +};
4553 +
4554 +struct fqid_cell {
4555 + uint32_t start;
4556 + uint32_t count;
4557 +};
4558 +
4559 +struct dpa_bp {
4560 + struct bman_pool *pool;
4561 + uint8_t bpid;
4562 + struct device *dev;
4563 + union {
4564 + /* The buffer pools used for the private ports are initialized
4565 + * with target_count buffers for each CPU; at runtime the
4566 + * number of buffers per CPU is constantly brought back to this
4567 + * level
4568 + */
4569 + int target_count;
4570 + /* The configured value for the number of buffers in the pool,
4571 + * used for shared port buffer pools
4572 + */
4573 + int config_count;
4574 + };
4575 + size_t size;
4576 + bool seed_pool;
4577 + /* physical address of the contiguous memory used by the pool to store
4578 + * the buffers
4579 + */
4580 + dma_addr_t paddr;
4581 + /* virtual address of the contiguous memory used by the pool to store
4582 + * the buffers
4583 + */
4584 + void __iomem *vaddr;
4585 + /* current number of buffers in the bpool alloted to this CPU */
4586 + int __percpu *percpu_count;
4587 + atomic_t refs;
4588 + /* some bpools need to be seeded before use by this cb */
4589 + int (*seed_cb)(struct dpa_bp *);
4590 + /* some bpools need to be emptied before freeing; this cb is used
4591 + * for freeing of individual buffers taken from the pool
4592 + */
4593 + void (*free_buf_cb)(void *addr);
4594 +};
4595 +
4596 +struct dpa_rx_errors {
4597 + u64 dme; /* DMA Error */
4598 + u64 fpe; /* Frame Physical Error */
4599 + u64 fse; /* Frame Size Error */
4600 + u64 phe; /* Header Error */
4601 + u64 cse; /* Checksum Validation Error */
4602 +};
4603 +
4604 +/* Counters for QMan ERN frames - one counter per rejection code */
4605 +struct dpa_ern_cnt {
4606 + u64 cg_tdrop; /* Congestion group taildrop */
4607 + u64 wred; /* WRED congestion */
4608 + u64 err_cond; /* Error condition */
4609 + u64 early_window; /* Order restoration, frame too early */
4610 + u64 late_window; /* Order restoration, frame too late */
4611 + u64 fq_tdrop; /* FQ taildrop */
4612 + u64 fq_retired; /* FQ is retired */
4613 + u64 orp_zero; /* ORP disabled */
4614 +};
4615 +
4616 +struct dpa_napi_portal {
4617 + struct napi_struct napi;
4618 + struct qman_portal *p;
4619 +};
4620 +
4621 +struct dpa_percpu_priv_s {
4622 + struct net_device *net_dev;
4623 + struct dpa_napi_portal *np;
4624 + u64 in_interrupt;
4625 + u64 tx_returned;
4626 + u64 tx_confirm;
4627 + /* fragmented (non-linear) skbuffs received from the stack */
4628 + u64 tx_frag_skbuffs;
4629 + /* number of S/G frames received */
4630 + u64 rx_sg;
4631 +
4632 + struct rtnl_link_stats64 stats;
4633 + struct dpa_rx_errors rx_errors;
4634 + struct dpa_ern_cnt ern_cnt;
4635 +};
4636 +
4637 +struct dpa_priv_s {
4638 + struct dpa_percpu_priv_s __percpu *percpu_priv;
4639 + struct dpa_bp *dpa_bp;
4640 + /* Store here the needed Tx headroom for convenience and speed
4641 + * (even though it can be computed based on the fields of buf_layout)
4642 + */
4643 + uint16_t tx_headroom;
4644 + struct net_device *net_dev;
4645 + struct mac_device *mac_dev;
4646 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
4647 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
4648 +
4649 + size_t bp_count;
4650 +
4651 + uint16_t channel; /* "fsl,qman-channel-id" */
4652 + struct list_head dpa_fq_list;
4653 +
4654 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4655 + struct dentry *debugfs_loop_file;
4656 +#endif
4657 +
4658 + uint32_t msg_enable; /* net_device message level */
4659 +#ifdef CONFIG_FSL_DPAA_1588
4660 + struct dpa_ptp_tsu *tsu;
4661 +#endif
4662 +
4663 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
4664 +/* TODO: this is temporary until pcd support is implemented in dpaa */
4665 + int priv_pcd_num_ranges;
4666 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
4667 +#endif
4668 +
4669 + struct {
4670 + /**
4671 + * All egress queues to a given net device belong to one
4672 + * (and the same) congestion group.
4673 + */
4674 + struct qman_cgr cgr;
4675 + /* If congested, when it began. Used for performance stats. */
4676 + u32 congestion_start_jiffies;
4677 + /* Number of jiffies the Tx port was congested. */
4678 + u32 congested_jiffies;
4679 + /**
4680 + * Counter for the number of times the CGR
4681 + * entered congestion state
4682 + */
4683 + u32 cgr_congested_count;
4684 + } cgr_data;
4685 + /* Use a per-port CGR for ingress traffic. */
4686 + bool use_ingress_cgr;
4687 + struct qman_cgr ingress_cgr;
4688 +
4689 +#ifdef CONFIG_FSL_DPAA_TS
4690 + bool ts_tx_en; /* Tx timestamping enabled */
4691 + bool ts_rx_en; /* Rx timestamping enabled */
4692 +#endif /* CONFIG_FSL_DPAA_TS */
4693 +
4694 + struct dpa_buffer_layout_s *buf_layout;
4695 + uint16_t rx_headroom;
4696 + char if_type[30];
4697 +
4698 + void *peer;
4699 +#ifdef CONFIG_PM
4700 + u32 wol;
4701 +#endif
4702 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4703 + int loop_id;
4704 + int loop_to;
4705 +#endif
4706 +#ifdef CONFIG_FSL_DPAA_CEETM
4707 + bool ceetm_en; /* CEETM QoS enabled */
4708 +#endif
4709 +};
4710 +
4711 +struct fm_port_fqs {
4712 + struct dpa_fq *tx_defq;
4713 + struct dpa_fq *tx_errq;
4714 + struct dpa_fq *rx_defq;
4715 + struct dpa_fq *rx_errq;
4716 +};
4717 +
4718 +
4719 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4720 +extern struct net_device *dpa_loop_netdevs[20];
4721 +#endif
4722 +
4723 +/* functions with different implementation for SG and non-SG: */
4724 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
4725 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
4726 +void __hot _dpa_rx(struct net_device *net_dev,
4727 + struct qman_portal *portal,
4728 + const struct dpa_priv_s *priv,
4729 + struct dpa_percpu_priv_s *percpu_priv,
4730 + const struct qm_fd *fd,
4731 + u32 fqid,
4732 + int *count_ptr);
4733 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
4734 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
4735 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
4736 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
4737 + const struct qm_fd *fd);
4738 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
4739 + const struct qm_fd *fd,
4740 + struct sk_buff *skb,
4741 + int *use_gro);
4742 +#ifndef CONFIG_FSL_DPAA_TS
4743 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
4744 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
4745 + uint32_t min_size,
4746 + uint16_t min_offset,
4747 + unsigned char **new_buf_start);
4748 +#endif
4749 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
4750 + struct sk_buff *skb, struct qm_fd *fd,
4751 + int *count_ptr, int *offset);
4752 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
4753 + struct sk_buff *skb, struct qm_fd *fd);
4754 +int __cold __attribute__((nonnull))
4755 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
4756 +
4757 +/* Turn on HW checksum computation for this outgoing frame.
4758 + * If the current protocol is not something we support in this regard
4759 + * (or if the stack has already computed the SW checksum), we do nothing.
4760 + *
4761 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
4762 + * otherwise.
4763 + *
4764 + * Note that this function may modify the fd->cmd field and the skb data buffer
4765 + * (the Parse Results area).
4766 + */
4767 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
4768 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
4769 +
4770 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
4771 + struct qman_portal *portal)
4772 +{
4773 + /* In case of threaded ISR for RT enable kernel,
4774 + * in_irq() does not return appropriate value, so use
4775 + * in_serving_softirq to distinguish softirq or irq context.
4776 + */
4777 + if (unlikely(in_irq() || !in_serving_softirq())) {
4778 + /* Disable QMan IRQ and invoke NAPI */
4779 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
4780 + if (likely(!ret)) {
4781 + const struct qman_portal_config *pc =
4782 + qman_p_get_portal_config(portal);
4783 + struct dpa_napi_portal *np =
4784 + &percpu_priv->np[pc->index];
4785 +
4786 + np->p = portal;
4787 + napi_schedule(&np->napi);
4788 + percpu_priv->in_interrupt++;
4789 + return 1;
4790 + }
4791 + }
4792 + return 0;
4793 +}
4794 +
4795 +static inline ssize_t __const __must_check __attribute__((nonnull))
4796 +dpa_fd_length(const struct qm_fd *fd)
4797 +{
4798 + return fd->length20;
4799 +}
4800 +
4801 +static inline ssize_t __const __must_check __attribute__((nonnull))
4802 +dpa_fd_offset(const struct qm_fd *fd)
4803 +{
4804 + return fd->offset;
4805 +}
4806 +
4807 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
4808 +{
4809 + uint16_t headroom;
4810 + /* The frame headroom must accommodate:
4811 + * - the driver private data area
4812 + * - parse results, hash results, timestamp if selected
4813 + * - manip extra space
4814 + * If either hash results or time stamp are selected, both will
4815 + * be copied to/from the frame headroom, as TS is located between PR and
4816 + * HR in the IC and IC copy size has a granularity of 16bytes
4817 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
4818 + *
4819 + * Also make sure the headroom is a multiple of data_align bytes
4820 + */
4821 + headroom = (uint16_t)(bl->priv_data_size +
4822 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
4823 + (bl->hash_results || bl->time_stamp ?
4824 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
4825 + bl->manip_extra_space);
4826 +
4827 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
4828 +}
4829 +
4830 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
4831 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
4832 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
4833 +
4834 +void dpaa_eth_sysfs_remove(struct device *dev);
4835 +void dpaa_eth_sysfs_init(struct device *dev);
4836 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
4837 +
4838 +void dpa_private_napi_del(struct net_device *net_dev);
4839 +
4840 +/* Equivalent to a memset(0), but works faster */
4841 +static inline void clear_fd(struct qm_fd *fd)
4842 +{
4843 + fd->opaque_addr = 0;
4844 + fd->opaque = 0;
4845 + fd->cmd = 0;
4846 +}
4847 +
4848 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
4849 + struct qman_fq *tx_fq)
4850 +{
4851 + int i;
4852 +
4853 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
4854 + if (priv->egress_fqs[i] == tx_fq)
4855 + return i;
4856 +
4857 + return -EINVAL;
4858 +}
4859 +
4860 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
4861 + struct rtnl_link_stats64 *percpu_stats,
4862 + struct qm_fd *fd, struct qman_fq *egress_fq,
4863 + struct qman_fq *conf_fq)
4864 +{
4865 + int err, i;
4866 +
4867 + if (fd->bpid == 0xff)
4868 + fd->cmd |= qman_fq_fqid(conf_fq);
4869 +
4870 + /* Trace this Tx fd */
4871 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
4872 +
4873 + for (i = 0; i < 100000; i++) {
4874 + err = qman_enqueue(egress_fq, fd, 0);
4875 + if (err != -EBUSY)
4876 + break;
4877 + }
4878 +
4879 + if (unlikely(err < 0)) {
4880 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
4881 + percpu_stats->tx_errors++;
4882 + percpu_stats->tx_fifo_errors++;
4883 + return err;
4884 + }
4885 +
4886 + percpu_stats->tx_packets++;
4887 + percpu_stats->tx_bytes += dpa_fd_length(fd);
4888 +
4889 + return 0;
4890 +}
4891 +
4892 +/* Use multiple WQs for FQ assignment:
4893 + * - Tx Confirmation queues go to WQ1.
4894 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
4895 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
4896 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
4897 + * to be scheduled, in case there are many more FQs in WQ3).
4898 + * This ensures that Tx-confirmed buffers are timely released. In particular,
4899 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
4900 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
4901 + * dequeue scheduling is round-robin.
4902 + */
4903 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
4904 +{
4905 + switch (fq->fq_type) {
4906 + case FQ_TYPE_TX_CONFIRM:
4907 + case FQ_TYPE_TX_CONF_MQ:
4908 + fq->wq = 1;
4909 + break;
4910 + case FQ_TYPE_RX_DEFAULT:
4911 + case FQ_TYPE_TX:
4912 + fq->wq = 3;
4913 + break;
4914 + case FQ_TYPE_RX_ERROR:
4915 + case FQ_TYPE_TX_ERROR:
4916 + case FQ_TYPE_RX_PCD_HI_PRIO:
4917 + fq->wq = 2;
4918 + break;
4919 + case FQ_TYPE_RX_PCD:
4920 + fq->wq = 5;
4921 + break;
4922 + default:
4923 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
4924 + fq->fq_type, fq->fqid);
4925 + }
4926 +}
4927 +
4928 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
4929 +/* Use in lieu of skb_get_queue_mapping() */
4930 +#ifdef CONFIG_FMAN_PFC
4931 +#define dpa_get_queue_mapping(skb) \
4932 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
4933 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
4934 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
4935 + dpa_num_cpus + smp_processor_id()));
4936 +
4937 +#else
4938 +#define dpa_get_queue_mapping(skb) \
4939 + raw_smp_processor_id()
4940 +#endif
4941 +#else
4942 +/* Use the queue selected by XPS */
4943 +#define dpa_get_queue_mapping(skb) \
4944 + skb_get_queue_mapping(skb)
4945 +#endif
4946 +
4947 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
4948 +struct ptp_priv_s {
4949 + struct device_node *node;
4950 + struct platform_device *of_dev;
4951 + struct ptp_clock *clock;
4952 + struct mac_device *mac_dev;
4953 +};
4954 +extern struct ptp_priv_s ptp_priv;
4955 +#endif
4956 +
4957 +static inline void _dpa_bp_free_pf(void *addr)
4958 +{
4959 + put_page(virt_to_head_page(addr));
4960 +}
4961 +
4962 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
4963 + * manifests itself at high traffic rates when frames cross 4K memory
4964 + * boundaries or when they are not aligned to 16 bytes; For the moment, we
4965 + * use a SW workaround that realigns frames to 256 bytes. Scatter/Gather
4966 + * frames aren't supported on egress.
4967 + */
4968 +
4969 +#ifndef CONFIG_PPC
4970 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
4971 +#define NONREC_MARK 0x01
4972 +#define HAS_DMA_ISSUE(start, size) \
4973 + (((uintptr_t)(start) + (size)) > \
4974 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
4975 +/* The headroom needs to accommodate our private data (64 bytes) but
4976 + * we reserve 256 bytes instead to guarantee 256 data alignment.
4977 + */
4978 +#define DPAA_A010022_HEADROOM 256
4979 +#endif /* !CONFIG_PPC */
4980 +
4981 +#endif /* __DPA_H */
4982 --- /dev/null
4983 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
4984 @@ -0,0 +1,205 @@
4985 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
4986 + *
4987 + * Redistribution and use in source and binary forms, with or without
4988 + * modification, are permitted provided that the following conditions are met:
4989 + * * Redistributions of source code must retain the above copyright
4990 + * notice, this list of conditions and the following disclaimer.
4991 + * * Redistributions in binary form must reproduce the above copyright
4992 + * notice, this list of conditions and the following disclaimer in the
4993 + * documentation and/or other materials provided with the distribution.
4994 + * * Neither the name of Freescale Semiconductor nor the
4995 + * names of its contributors may be used to endorse or promote products
4996 + * derived from this software without specific prior written permission.
4997 + *
4998 + *
4999 + * ALTERNATIVELY, this software may be distributed under the terms of the
5000 + * GNU General Public License ("GPL") as published by the Free Software
5001 + * Foundation, either version 2 of that License or (at your option) any
5002 + * later version.
5003 + *
5004 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5005 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5006 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5007 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5008 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5009 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5010 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5011 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5012 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5013 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5014 + */
5015 +
5016 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
5017 +#define pr_fmt(fmt) \
5018 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
5019 + KBUILD_BASENAME".c", __LINE__, __func__
5020 +#else
5021 +#define pr_fmt(fmt) \
5022 + KBUILD_MODNAME ": " fmt
5023 +#endif
5024 +
5025 +#include <linux/init.h>
5026 +#include <linux/module.h>
5027 +#include <linux/io.h>
5028 +#include <linux/of_platform.h>
5029 +#include <linux/of_net.h>
5030 +#include <linux/etherdevice.h>
5031 +#include <linux/kthread.h>
5032 +#include <linux/percpu.h>
5033 +#include <linux/highmem.h>
5034 +#include <linux/sort.h>
5035 +#include <linux/fsl_qman.h>
5036 +#include "dpaa_eth.h"
5037 +#include "dpaa_eth_common.h"
5038 +#include "dpaa_eth_base.h"
5039 +
5040 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
5041 +
5042 +MODULE_LICENSE("Dual BSD/GPL");
5043 +
5044 +uint8_t advanced_debug = -1;
5045 +module_param(advanced_debug, byte, S_IRUGO);
5046 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
5047 +EXPORT_SYMBOL(advanced_debug);
5048 +
5049 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
5050 +{
5051 + return ((struct dpa_bp *)dpa_bp0)->size -
5052 + ((struct dpa_bp *)dpa_bp1)->size;
5053 +}
5054 +
5055 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
5056 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
5057 +{
5058 + int i, lenp, na, ns, err;
5059 + struct device *dev;
5060 + struct device_node *dev_node;
5061 + const __be32 *bpool_cfg;
5062 + struct dpa_bp *dpa_bp;
5063 + u32 bpid;
5064 +
5065 + dev = &_of_dev->dev;
5066 +
5067 + *count = of_count_phandle_with_args(dev->of_node,
5068 + "fsl,bman-buffer-pools", NULL);
5069 + if (*count < 1) {
5070 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
5071 + return ERR_PTR(-EINVAL);
5072 + }
5073 +
5074 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
5075 + if (dpa_bp == NULL) {
5076 + dev_err(dev, "devm_kzalloc() failed\n");
5077 + return ERR_PTR(-ENOMEM);
5078 + }
5079 +
5080 + dev_node = of_find_node_by_path("/");
5081 + if (unlikely(dev_node == NULL)) {
5082 + dev_err(dev, "of_find_node_by_path(/) failed\n");
5083 + return ERR_PTR(-EINVAL);
5084 + }
5085 +
5086 + na = of_n_addr_cells(dev_node);
5087 + ns = of_n_size_cells(dev_node);
5088 +
5089 + for (i = 0; i < *count; i++) {
5090 + of_node_put(dev_node);
5091 +
5092 + dev_node = of_parse_phandle(dev->of_node,
5093 + "fsl,bman-buffer-pools", i);
5094 + if (dev_node == NULL) {
5095 + dev_err(dev, "of_find_node_by_phandle() failed\n");
5096 + return ERR_PTR(-EFAULT);
5097 + }
5098 +
5099 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
5100 + dev_err(dev,
5101 + "!of_device_is_compatible(%s, fsl,bpool)\n",
5102 + dev_node->full_name);
5103 + dpa_bp = ERR_PTR(-EINVAL);
5104 + goto _return_of_node_put;
5105 + }
5106 +
5107 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
5108 + if (err) {
5109 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
5110 + dpa_bp = ERR_PTR(-EINVAL);
5111 + goto _return_of_node_put;
5112 + }
5113 + dpa_bp[i].bpid = (uint8_t)bpid;
5114 +
5115 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
5116 + &lenp);
5117 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
5118 + const uint32_t *seed_pool;
5119 +
5120 + dpa_bp[i].config_count =
5121 + (int)of_read_number(bpool_cfg, ns);
5122 + dpa_bp[i].size =
5123 + (size_t)of_read_number(bpool_cfg + ns, ns);
5124 + dpa_bp[i].paddr =
5125 + of_read_number(bpool_cfg + 2 * ns, na);
5126 +
5127 + seed_pool = of_get_property(dev_node,
5128 + "fsl,bpool-ethernet-seeds", &lenp);
5129 + dpa_bp[i].seed_pool = !!seed_pool;
5130 +
5131 + } else {
5132 + dev_err(dev,
5133 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
5134 + dev_node->full_name);
5135 + dpa_bp = ERR_PTR(-EINVAL);
5136 + goto _return_of_node_put;
5137 + }
5138 + }
5139 +
5140 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
5141 +
5142 + return dpa_bp;
5143 +
5144 +_return_of_node_put:
5145 + if (dev_node)
5146 + of_node_put(dev_node);
5147 +
5148 + return dpa_bp;
5149 +}
5150 +EXPORT_SYMBOL(dpa_bp_probe);
5151 +
5152 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
5153 + size_t count)
5154 +{
5155 + struct dpa_priv_s *priv = netdev_priv(net_dev);
5156 + int i;
5157 +
5158 + priv->dpa_bp = dpa_bp;
5159 + priv->bp_count = count;
5160 +
5161 + for (i = 0; i < count; i++) {
5162 + int err;
5163 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
5164 + if (err < 0) {
5165 + dpa_bp_free(priv);
5166 + priv->dpa_bp = NULL;
5167 + return err;
5168 + }
5169 + }
5170 +
5171 + return 0;
5172 +}
5173 +EXPORT_SYMBOL(dpa_bp_create);
5174 +
5175 +static int __init __cold dpa_advanced_load(void)
5176 +{
5177 + pr_info(DPA_DESCRIPTION "\n");
5178 +
5179 + return 0;
5180 +}
5181 +module_init(dpa_advanced_load);
5182 +
5183 +static void __exit __cold dpa_advanced_unload(void)
5184 +{
5185 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
5186 + KBUILD_BASENAME".c", __func__);
5187 +
5188 +}
5189 +module_exit(dpa_advanced_unload);
5190 --- /dev/null
5191 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
5192 @@ -0,0 +1,49 @@
5193 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
5194 + *
5195 + * Redistribution and use in source and binary forms, with or without
5196 + * modification, are permitted provided that the following conditions are met:
5197 + * * Redistributions of source code must retain the above copyright
5198 + * notice, this list of conditions and the following disclaimer.
5199 + * * Redistributions in binary form must reproduce the above copyright
5200 + * notice, this list of conditions and the following disclaimer in the
5201 + * documentation and/or other materials provided with the distribution.
5202 + * * Neither the name of Freescale Semiconductor nor the
5203 + * names of its contributors may be used to endorse or promote products
5204 + * derived from this software without specific prior written permission.
5205 + *
5206 + *
5207 + * ALTERNATIVELY, this software may be distributed under the terms of the
5208 + * GNU General Public License ("GPL") as published by the Free Software
5209 + * Foundation, either version 2 of that License or (at your option) any
5210 + * later version.
5211 + *
5212 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5213 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5214 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5215 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5216 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5217 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5218 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5219 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5220 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5221 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5222 + */
5223 +
5224 +#ifndef __DPAA_ETH_BASE_H
5225 +#define __DPAA_ETH_BASE_H
5226 +
5227 +#include <linux/etherdevice.h> /* struct net_device */
5228 +#include <linux/fsl_bman.h> /* struct bm_buffer */
5229 +#include <linux/of_platform.h> /* struct platform_device */
5230 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
5231 +
5232 +extern uint8_t advanced_debug;
5233 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
5234 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
5235 +
5236 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
5237 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
5238 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
5239 + size_t count);
5240 +
5241 +#endif /* __DPAA_ETH_BASE_H */
5242 --- /dev/null
5243 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
5244 @@ -0,0 +1,2099 @@
5245 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5246 + *
5247 + * Redistribution and use in source and binary forms, with or without
5248 + * modification, are permitted provided that the following conditions are met:
5249 + * * Redistributions of source code must retain the above copyright
5250 + * notice, this list of conditions and the following disclaimer.
5251 + * * Redistributions in binary form must reproduce the above copyright
5252 + * notice, this list of conditions and the following disclaimer in the
5253 + * documentation and/or other materials provided with the distribution.
5254 + * * Neither the name of Freescale Semiconductor nor the
5255 + * names of its contributors may be used to endorse or promote products
5256 + * derived from this software without specific prior written permission.
5257 + *
5258 + *
5259 + * ALTERNATIVELY, this software may be distributed under the terms of the
5260 + * GNU General Public License ("GPL") as published by the Free Software
5261 + * Foundation, either version 2 of that License or (at your option) any
5262 + * later version.
5263 + *
5264 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5265 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5266 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5267 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5268 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5269 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5270 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5271 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5272 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5273 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5274 + */
5275 +
5276 +#include <linux/init.h>
5277 +#include "dpaa_eth_ceetm.h"
5278 +
5279 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
5280 +
5281 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
5282 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
5283 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
5284 +};
5285 +
5286 +struct Qdisc_ops ceetm_qdisc_ops;
5287 +
5288 +/* Obtain the DCP and the SP ids from the FMan port */
5289 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
5290 + unsigned int *sp_id)
5291 +{
5292 + uint32_t channel;
5293 + t_LnxWrpFmPortDev *port_dev;
5294 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
5295 + struct mac_device *mac_dev = dpa_priv->mac_dev;
5296 +
5297 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
5298 + channel = port_dev->txCh;
5299 +
5300 + *sp_id = channel & CHANNEL_SP_MASK;
5301 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
5302 +
5303 + if (channel < DCP0_MAX_CHANNEL) {
5304 + *dcp_id = qm_dc_portal_fman0;
5305 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
5306 + } else {
5307 + *dcp_id = qm_dc_portal_fman1;
5308 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
5309 + }
5310 +}
5311 +
5312 +/* Wait for the DPAA Eth driver WQ TX FQs to empty */
5313 +static void dpaa_drain_fqs(struct net_device *dev)
5314 +{
5315 + const struct dpa_priv_s *priv = netdev_priv(dev);
5316 + struct qm_mcr_queryfq_np np;
5317 + struct qman_fq *fq;
5318 + int ret, i;
5319 +
5320 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i ++) {
5321 + fq = priv->egress_fqs[i];
5322 + while (true) {
5323 + ret = qman_query_fq_np(fq, &np);
5324 + if (unlikely(ret)) {
5325 + pr_err(KBUILD_BASENAME
5326 + " : %s : unable to query FQ %x: %d\n",
5327 + __func__, fq->fqid, ret);
5328 + break;
5329 + }
5330 +
5331 + if (np.frm_cnt == 0)
5332 + break;
5333 + }
5334 + }
5335 +}
5336 +
5337 +/* Wait for the DPAA CEETM TX CQs to empty */
5338 +static void ceetm_drain_class(struct ceetm_class *cl)
5339 +{
5340 + struct qm_mcr_ceetm_cq_query cq_query;
5341 + struct qm_ceetm_cq *cq;
5342 + unsigned int idx;
5343 + int ret;
5344 +
5345 + if (!cl)
5346 + return;
5347 +
5348 + switch (cl->type) {
5349 + case CEETM_ROOT:
5350 + /* The ROOT classes aren't directly linked to CEETM CQs */
5351 + return;
5352 + case CEETM_PRIO:
5353 + cq = (struct qm_ceetm_cq*)cl->prio.cq;
5354 + break;
5355 + case CEETM_WBFS:
5356 + cq = (struct qm_ceetm_cq*)cl->wbfs.cq;
5357 + break;
5358 + }
5359 +
5360 + if (!cq || !cl->ch)
5361 + return;
5362 +
5363 + /* Build the query CQID by merging the channel and the CQ IDs */
5364 + idx = (cq->parent->idx << 4) | cq->idx;
5365 +
5366 + while (true) {
5367 + ret = qman_ceetm_query_cq(idx,
5368 + cl->ch->dcp_idx,
5369 + &cq_query);
5370 + if (unlikely(ret)) {
5371 + pr_err(KBUILD_BASENAME
5372 + " : %s : unable to query CQ %x: %d\n",
5373 + __func__, idx, ret);
5374 + break;
5375 + }
5376 +
5377 + if (cq_query.frm_cnt == 0)
5378 + break;
5379 + }
5380 +}
5381 +
5382 +/* Enqueue Rejection Notification callback */
5383 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
5384 + const struct qm_mr_entry *msg)
5385 +{
5386 + struct dpa_percpu_priv_s *dpa_percpu_priv;
5387 + struct ceetm_class_stats *cstats = NULL;
5388 + const struct dpa_priv_s *dpa_priv;
5389 + struct qm_fd fd = msg->ern.fd;
5390 + struct net_device *net_dev;
5391 + struct ceetm_fq *ceetm_fq;
5392 + struct ceetm_class *cls;
5393 + struct sk_buff *skb;
5394 +
5395 + ceetm_fq = container_of(fq, struct ceetm_fq, fq);
5396 + net_dev = ceetm_fq->net_dev;
5397 + dpa_priv = netdev_priv(net_dev);
5398 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
5399 +
5400 + /* Increment DPA counters */
5401 + dpa_percpu_priv->stats.tx_dropped++;
5402 + dpa_percpu_priv->stats.tx_fifo_errors++;
5403 + count_ern(dpa_percpu_priv, msg);
5404 +
5405 + /* Increment CEETM counters */
5406 + cls = ceetm_fq->ceetm_cls;
5407 + switch (cls->type) {
5408 + case CEETM_PRIO:
5409 + cstats = this_cpu_ptr(cls->prio.cstats);
5410 + break;
5411 + case CEETM_WBFS:
5412 + cstats = this_cpu_ptr(cls->wbfs.cstats);
5413 + break;
5414 + }
5415 +
5416 + if (cstats)
5417 + cstats->ern_drop_count++;
5418 +
5419 + /* Release the buffers that were supposed to be recycled. */
5420 + if (fd.bpid != 0xff) {
5421 + dpa_fd_release(net_dev, &fd);
5422 + return;
5423 + }
5424 +
5425 + /* Release the frames that were supposed to return on the
5426 + * confirmation path.
5427 + */
5428 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
5429 + dev_kfree_skb_any(skb);
5430 +}
5431 +
5432 +/* Congestion State Change Notification callback */
5433 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
5434 +{
5435 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
5436 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
5437 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
5438 + struct ceetm_class_stats *cstats = NULL;
5439 +
5440 + switch (cls->type) {
5441 + case CEETM_PRIO:
5442 + cstats = this_cpu_ptr(cls->prio.cstats);
5443 + break;
5444 + case CEETM_WBFS:
5445 + cstats = this_cpu_ptr(cls->wbfs.cstats);
5446 + break;
5447 + }
5448 +
5449 + ceetm_fq->congested = congested;
5450 +
5451 + if (congested) {
5452 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
5453 + dpa_priv->cgr_data.cgr_congested_count++;
5454 + if (cstats)
5455 + cstats->congested_count++;
5456 + } else {
5457 + dpa_priv->cgr_data.congested_jiffies +=
5458 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
5459 + }
5460 +}
5461 +
5462 +/* Allocate a ceetm fq */
5463 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
5464 + struct ceetm_class *cls)
5465 +{
5466 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
5467 + if (!*fq)
5468 + return -ENOMEM;
5469 +
5470 + (*fq)->net_dev = dev;
5471 + (*fq)->ceetm_cls = cls;
5472 + (*fq)->congested = 0;
5473 + return 0;
5474 +}
5475 +
5476 +/* Configure a ceetm Class Congestion Group */
5477 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
5478 + struct qm_ceetm_channel *channel, unsigned int id,
5479 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
5480 +{
5481 + int err;
5482 + u32 cs_th;
5483 + u16 ccg_mask;
5484 + struct qm_ceetm_ccg_params ccg_params;
5485 +
5486 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
5487 + if (err)
5488 + return err;
5489 +
5490 + /* Configure the count mode (frames/bytes), enable congestion state
5491 + * notifications, configure the congestion entry and exit thresholds,
5492 + * enable tail-drop, configure the tail-drop mode, and set the
5493 + * overhead accounting limit
5494 + */
5495 + ccg_mask = QM_CCGR_WE_MODE |
5496 + QM_CCGR_WE_CSCN_EN |
5497 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
5498 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
5499 + QM_CCGR_WE_OAL;
5500 +
5501 + ccg_params.mode = 0; /* count bytes */
5502 + ccg_params.cscn_en = 1; /* generate notifications */
5503 + ccg_params.td_en = 1; /* enable tail-drop */
5504 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
5505 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
5506 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
5507 +
5508 + /* Set the congestion state thresholds according to the link speed */
5509 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
5510 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_10G;
5511 + else
5512 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_1G;
5513 +
5514 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
5515 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
5516 + cs_th * CEETM_CCGR_RATIO, 1);
5517 +
5518 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
5519 + if (err)
5520 + return err;
5521 +
5522 + return 0;
5523 +}
5524 +
5525 +/* Configure a ceetm Logical Frame Queue */
5526 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
5527 + struct qm_ceetm_lfq **lfq)
5528 +{
5529 + int err;
5530 + u64 context_a;
5531 + u32 context_b;
5532 +
5533 + err = qman_ceetm_lfq_claim(lfq, cq);
5534 + if (err)
5535 + return err;
5536 +
5537 + /* Get the former contexts in order to preserve context B */
5538 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
5539 + if (err)
5540 + return err;
5541 +
5542 + context_a = CEETM_CONTEXT_A;
5543 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
5544 + if (err)
5545 + return err;
5546 +
5547 + (*lfq)->ern = ceetm_ern;
5548 +
5549 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
5550 + if (err)
5551 + return err;
5552 +
5553 + return 0;
5554 +}
5555 +
5556 +/* Configure a prio ceetm class */
5557 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
5558 + struct net_device *dev,
5559 + unsigned int id)
5560 +{
5561 + int err;
5562 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
5563 +
5564 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
5565 + if (err)
5566 + return err;
5567 +
5568 + /* Claim and configure the CCG */
5569 + err = ceetm_config_ccg(&cls->prio.ccg, cls->ch, id, cls->prio.fq,
5570 + dpa_priv);
5571 + if (err)
5572 + return err;
5573 +
5574 + /* Claim and configure the CQ */
5575 + err = qman_ceetm_cq_claim(&cls->prio.cq, cls->ch, id, cls->prio.ccg);
5576 + if (err)
5577 + return err;
5578 +
5579 + if (cls->shaped) {
5580 + err = qman_ceetm_channel_set_cq_cr_eligibility(cls->ch, id, 1);
5581 + if (err)
5582 + return err;
5583 +
5584 + err = qman_ceetm_channel_set_cq_er_eligibility(cls->ch, id, 1);
5585 + if (err)
5586 + return err;
5587 + }
5588 +
5589 + /* Claim and configure a LFQ */
5590 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
5591 + if (err)
5592 + return err;
5593 +
5594 + return 0;
5595 +}
5596 +
5597 +/* Configure a wbfs ceetm class */
5598 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
5599 + struct net_device *dev,
5600 + unsigned int id, int type)
5601 +{
5602 + int err;
5603 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
5604 +
5605 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
5606 + if (err)
5607 + return err;
5608 +
5609 + /* Claim and configure the CCG */
5610 + err = ceetm_config_ccg(&cls->wbfs.ccg, cls->ch, id, cls->wbfs.fq,
5611 + dpa_priv);
5612 + if (err)
5613 + return err;
5614 +
5615 + /* Claim and configure the CQ */
5616 + if (type == WBFS_GRP_B)
5617 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, cls->ch, id,
5618 + cls->wbfs.ccg);
5619 + else
5620 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, cls->ch, id,
5621 + cls->wbfs.ccg);
5622 + if (err)
5623 + return err;
5624 +
5625 + /* Configure the CQ weight: real number multiplied by 100 to get rid
5626 + * of the fraction
5627 + */
5628 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
5629 + cls->wbfs.weight * 100);
5630 + if (err)
5631 + return err;
5632 +
5633 + /* Claim and configure a LFQ */
5634 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
5635 + if (err)
5636 + return err;
5637 +
5638 + return 0;
5639 +}
5640 +
5641 +/* Find class in qdisc hash table using given handle */
5642 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
5643 +{
5644 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5645 + struct Qdisc_class_common *clc;
5646 +
5647 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
5648 + __func__, handle, sch->handle);
5649 +
5650 + clc = qdisc_class_find(&priv->clhash, handle);
5651 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
5652 +}
5653 +
5654 +/* Insert a class in the qdisc's class hash */
5655 +static void ceetm_link_class(struct Qdisc *sch,
5656 + struct Qdisc_class_hash *clhash,
5657 + struct Qdisc_class_common *common)
5658 +{
5659 + sch_tree_lock(sch);
5660 + qdisc_class_hash_insert(clhash, common);
5661 + sch_tree_unlock(sch);
5662 + qdisc_class_hash_grow(sch, clhash);
5663 +}
5664 +
5665 +/* Destroy a ceetm class */
5666 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
5667 +{
5668 + struct net_device *dev = qdisc_dev(sch);
5669 +
5670 + if (!cl)
5671 + return;
5672 +
5673 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
5674 + __func__, cl->common.classid, sch->handle);
5675 +
5676 + switch (cl->type) {
5677 + case CEETM_ROOT:
5678 + if (cl->root.child) {
5679 + qdisc_destroy(cl->root.child);
5680 + cl->root.child = NULL;
5681 + }
5682 +
5683 + if (cl->ch && qman_ceetm_channel_release(cl->ch))
5684 + pr_err(KBUILD_BASENAME
5685 + " : %s : error releasing the channel %d\n",
5686 + __func__, cl->ch->idx);
5687 +
5688 + break;
5689 +
5690 + case CEETM_PRIO:
5691 + if (cl->prio.child) {
5692 + qdisc_destroy(cl->prio.child);
5693 + cl->prio.child = NULL;
5694 + }
5695 +
5696 + /* We must make sure the CQ is empty before releasing it.
5697 + * Pause all transmissions while we wait for it to drain.
5698 + */
5699 + netif_tx_stop_all_queues(dev);
5700 + ceetm_drain_class(cl);
5701 +
5702 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
5703 + pr_err(KBUILD_BASENAME
5704 + " : %s : error releasing the LFQ %d\n",
5705 + __func__, cl->prio.lfq->idx);
5706 +
5707 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
5708 + pr_err(KBUILD_BASENAME
5709 + " : %s : error releasing the CQ %d\n",
5710 + __func__, cl->prio.cq->idx);
5711 +
5712 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
5713 + pr_err(KBUILD_BASENAME
5714 + " : %s : error releasing the CCG %d\n",
5715 + __func__, cl->prio.ccg->idx);
5716 +
5717 + kfree(cl->prio.fq);
5718 +
5719 + if (cl->prio.cstats)
5720 + free_percpu(cl->prio.cstats);
5721 +
5722 + netif_tx_wake_all_queues(dev);
5723 + break;
5724 +
5725 + case CEETM_WBFS:
5726 + /* We must make sure the CQ is empty before releasing it.
5727 + * Pause all transmissions while we wait for it to drain.
5728 + */
5729 + netif_tx_stop_all_queues(dev);
5730 + ceetm_drain_class(cl);
5731 +
5732 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
5733 + pr_err(KBUILD_BASENAME
5734 + " : %s : error releasing the LFQ %d\n",
5735 + __func__, cl->wbfs.lfq->idx);
5736 +
5737 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
5738 + pr_err(KBUILD_BASENAME
5739 + " : %s : error releasing the CQ %d\n",
5740 + __func__, cl->wbfs.cq->idx);
5741 +
5742 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
5743 + pr_err(KBUILD_BASENAME
5744 + " : %s : error releasing the CCG %d\n",
5745 + __func__, cl->wbfs.ccg->idx);
5746 +
5747 + kfree(cl->wbfs.fq);
5748 +
5749 + if (cl->wbfs.cstats)
5750 + free_percpu(cl->wbfs.cstats);
5751 +
5752 + netif_tx_wake_all_queues(dev);
5753 + }
5754 +
5755 + tcf_block_put(cl->block);
5756 + kfree(cl);
5757 +}
5758 +
5759 +/* Destroy a ceetm qdisc */
5760 +static void ceetm_destroy(struct Qdisc *sch)
5761 +{
5762 + unsigned int ntx, i;
5763 + struct hlist_node *next;
5764 + struct ceetm_class *cl;
5765 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5766 + struct net_device *dev = qdisc_dev(sch);
5767 +
5768 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
5769 + __func__, sch->handle);
5770 +
5771 + /* All filters need to be removed before destroying the classes */
5772 + tcf_block_put(priv->block);
5773 +
5774 + for (i = 0; i < priv->clhash.hashsize; i++) {
5775 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5776 + tcf_block_put(cl->block);
5777 + cl->block = NULL;
5778 + }
5779 + }
5780 +
5781 + for (i = 0; i < priv->clhash.hashsize; i++) {
5782 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
5783 + common.hnode)
5784 + ceetm_cls_destroy(sch, cl);
5785 + }
5786 +
5787 + qdisc_class_hash_destroy(&priv->clhash);
5788 +
5789 + switch (priv->type) {
5790 + case CEETM_ROOT:
5791 + dpa_disable_ceetm(dev);
5792 +
5793 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
5794 + pr_err(KBUILD_BASENAME
5795 + " : %s : error releasing the LNI %d\n",
5796 + __func__, priv->root.lni->idx);
5797 +
5798 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
5799 + pr_err(KBUILD_BASENAME
5800 + " : %s : error releasing the SP %d\n",
5801 + __func__, priv->root.sp->idx);
5802 +
5803 + if (priv->root.qstats)
5804 + free_percpu(priv->root.qstats);
5805 +
5806 + if (!priv->root.qdiscs)
5807 + break;
5808 +
5809 + /* Destroy the pfifo qdiscs in case they haven't been attached
5810 + * to the netdev queues yet.
5811 + */
5812 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
5813 + if (priv->root.qdiscs[ntx])
5814 + qdisc_destroy(priv->root.qdiscs[ntx]);
5815 +
5816 + kfree(priv->root.qdiscs);
5817 + break;
5818 +
5819 + case CEETM_PRIO:
5820 + if (priv->prio.parent)
5821 + priv->prio.parent->root.child = NULL;
5822 + break;
5823 +
5824 + case CEETM_WBFS:
5825 + /* Reset the WBFS groups and priorities */
5826 + if (priv->wbfs.ch)
5827 + qman_ceetm_channel_set_group(priv->wbfs.ch, 1, 0, 0);
5828 +
5829 + if (priv->wbfs.parent)
5830 + priv->wbfs.parent->prio.child = NULL;
5831 + break;
5832 + }
5833 +}
5834 +
5835 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
5836 +{
5837 + struct Qdisc *qdisc;
5838 + unsigned int ntx, i;
5839 + struct nlattr *nest;
5840 + struct tc_ceetm_qopt qopt;
5841 + struct ceetm_qdisc_stats *qstats;
5842 + struct net_device *dev = qdisc_dev(sch);
5843 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5844 +
5845 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5846 +
5847 + sch_tree_lock(sch);
5848 + memset(&qopt, 0, sizeof(qopt));
5849 + qopt.type = priv->type;
5850 + qopt.shaped = priv->shaped;
5851 +
5852 + switch (priv->type) {
5853 + case CEETM_ROOT:
5854 + /* Gather statistics from the underlying pfifo qdiscs */
5855 + sch->q.qlen = 0;
5856 + memset(&sch->bstats, 0, sizeof(sch->bstats));
5857 + memset(&sch->qstats, 0, sizeof(sch->qstats));
5858 +
5859 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
5860 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
5861 + sch->q.qlen += qdisc->q.qlen;
5862 + sch->bstats.bytes += qdisc->bstats.bytes;
5863 + sch->bstats.packets += qdisc->bstats.packets;
5864 + sch->qstats.qlen += qdisc->qstats.qlen;
5865 + sch->qstats.backlog += qdisc->qstats.backlog;
5866 + sch->qstats.drops += qdisc->qstats.drops;
5867 + sch->qstats.requeues += qdisc->qstats.requeues;
5868 + sch->qstats.overlimits += qdisc->qstats.overlimits;
5869 + }
5870 +
5871 + for_each_online_cpu(i) {
5872 + qstats = per_cpu_ptr(priv->root.qstats, i);
5873 + sch->qstats.drops += qstats->drops;
5874 + }
5875 +
5876 + qopt.rate = priv->root.rate;
5877 + qopt.ceil = priv->root.ceil;
5878 + qopt.overhead = priv->root.overhead;
5879 + break;
5880 +
5881 + case CEETM_PRIO:
5882 + qopt.qcount = priv->prio.qcount;
5883 + break;
5884 +
5885 + case CEETM_WBFS:
5886 + qopt.qcount = priv->wbfs.qcount;
5887 + qopt.cr = priv->wbfs.cr;
5888 + qopt.er = priv->wbfs.er;
5889 + break;
5890 +
5891 + default:
5892 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5893 + sch_tree_unlock(sch);
5894 + return -EINVAL;
5895 + }
5896 +
5897 + nest = nla_nest_start(skb, TCA_OPTIONS);
5898 + if (!nest)
5899 + goto nla_put_failure;
5900 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
5901 + goto nla_put_failure;
5902 + nla_nest_end(skb, nest);
5903 +
5904 + sch_tree_unlock(sch);
5905 + return skb->len;
5906 +
5907 +nla_put_failure:
5908 + sch_tree_unlock(sch);
5909 + nla_nest_cancel(skb, nest);
5910 + return -EMSGSIZE;
5911 +}
5912 +
5913 +/* Configure a root ceetm qdisc */
5914 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
5915 + struct tc_ceetm_qopt *qopt)
5916 +{
5917 + struct netdev_queue *dev_queue;
5918 + struct Qdisc *qdisc;
5919 + enum qm_dc_portal dcp_id;
5920 + unsigned int i, sp_id, parent_id;
5921 + int err;
5922 + u64 bps;
5923 + struct qm_ceetm_sp *sp;
5924 + struct qm_ceetm_lni *lni;
5925 + struct net_device *dev = qdisc_dev(sch);
5926 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
5927 + struct mac_device *mac_dev = dpa_priv->mac_dev;
5928 +
5929 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5930 +
5931 + /* Validate inputs */
5932 + if (sch->parent != TC_H_ROOT) {
5933 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
5934 + tcf_block_put(priv->block);
5935 + qdisc_class_hash_destroy(&priv->clhash);
5936 + return -EINVAL;
5937 + }
5938 +
5939 + if (!mac_dev) {
5940 + pr_err("CEETM: the interface is lacking a mac\n");
5941 + err = -EINVAL;
5942 + goto err_init_root;
5943 + }
5944 +
5945 + /* Pre-allocate underlying pfifo qdiscs.
5946 + *
5947 + * We want to offload shaping and scheduling decisions to the hardware.
5948 + * The pfifo qdiscs will be attached to the netdev queues and will
5949 + * guide the traffic from the IP stack down to the driver with minimum
5950 + * interference.
5951 + *
5952 + * The CEETM qdiscs and classes will be crossed when the traffic
5953 + * reaches the driver.
5954 + */
5955 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
5956 + sizeof(priv->root.qdiscs[0]),
5957 + GFP_KERNEL);
5958 + if (!priv->root.qdiscs) {
5959 + err = -ENOMEM;
5960 + goto err_init_root;
5961 + }
5962 +
5963 + for (i = 0; i < dev->num_tx_queues; i++) {
5964 + dev_queue = netdev_get_tx_queue(dev, i);
5965 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
5966 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
5967 +
5968 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
5969 + parent_id);
5970 + if (!qdisc) {
5971 + err = -ENOMEM;
5972 + goto err_init_root;
5973 + }
5974 +
5975 + priv->root.qdiscs[i] = qdisc;
5976 + qdisc->flags |= TCQ_F_ONETXQUEUE;
5977 + }
5978 +
5979 + sch->flags |= TCQ_F_MQROOT;
5980 +
5981 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
5982 + if (!priv->root.qstats) {
5983 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
5984 + __func__);
5985 + err = -ENOMEM;
5986 + goto err_init_root;
5987 + }
5988 +
5989 + priv->shaped = qopt->shaped;
5990 + priv->root.rate = qopt->rate;
5991 + priv->root.ceil = qopt->ceil;
5992 + priv->root.overhead = qopt->overhead;
5993 +
5994 + /* Claim the SP */
5995 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
5996 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
5997 + if (err) {
5998 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
5999 + __func__);
6000 + goto err_init_root;
6001 + }
6002 +
6003 + priv->root.sp = sp;
6004 +
6005 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
6006 + * are connected to the TX FMan ports
6007 + */
6008 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
6009 + if (err) {
6010 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
6011 + __func__);
6012 + goto err_init_root;
6013 + }
6014 +
6015 + priv->root.lni = lni;
6016 +
6017 + err = qman_ceetm_sp_set_lni(sp, lni);
6018 + if (err) {
6019 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
6020 + __func__);
6021 + goto err_init_root;
6022 + }
6023 +
6024 + lni->sp = sp;
6025 +
6026 + /* Configure the LNI shaper */
6027 + if (priv->shaped) {
6028 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
6029 + if (err) {
6030 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
6031 + __func__);
6032 + goto err_init_root;
6033 + }
6034 +
6035 + bps = priv->root.rate << 3; /* Bps -> bps */
6036 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
6037 + if (err) {
6038 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
6039 + __func__);
6040 + goto err_init_root;
6041 + }
6042 +
6043 + bps = priv->root.ceil << 3; /* Bps -> bps */
6044 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
6045 + if (err) {
6046 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
6047 + __func__);
6048 + goto err_init_root;
6049 + }
6050 + }
6051 +
6052 + /* TODO default configuration */
6053 +
6054 + dpa_enable_ceetm(dev);
6055 + return 0;
6056 +
6057 +err_init_root:
6058 + ceetm_destroy(sch);
6059 + return err;
6060 +}
6061 +
6062 +/* Configure a prio ceetm qdisc */
6063 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
6064 + struct tc_ceetm_qopt *qopt)
6065 +{
6066 + int err;
6067 + unsigned int i;
6068 + struct ceetm_class *parent_cl, *child_cl;
6069 + struct Qdisc *parent_qdisc;
6070 + struct net_device *dev = qdisc_dev(sch);
6071 +
6072 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6073 +
6074 + if (sch->parent == TC_H_ROOT) {
6075 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
6076 + err = -EINVAL;
6077 + goto err_init_prio;
6078 + }
6079 +
6080 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
6081 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
6082 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
6083 + err = -EINVAL;
6084 + goto err_init_prio;
6085 + }
6086 +
6087 + /* Obtain the parent root ceetm_class */
6088 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
6089 +
6090 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
6091 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
6092 + err = -EINVAL;
6093 + goto err_init_prio;
6094 + }
6095 +
6096 + priv->prio.parent = parent_cl;
6097 + parent_cl->root.child = sch;
6098 +
6099 + priv->shaped = parent_cl->shaped;
6100 + priv->prio.qcount = qopt->qcount;
6101 + priv->prio.ch = parent_cl->ch;
6102 +
6103 + /* Create and configure qcount child classes */
6104 + for (i = 0; i < priv->prio.qcount; i++) {
6105 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
6106 + if (!child_cl) {
6107 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
6108 + __func__);
6109 + err = -ENOMEM;
6110 + goto err_init_prio;
6111 + }
6112 +
6113 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
6114 + if (!child_cl->prio.cstats) {
6115 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
6116 + __func__);
6117 + err = -ENOMEM;
6118 + goto err_init_prio_cls;
6119 + }
6120 +
6121 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
6122 + child_cl->parent = sch;
6123 + child_cl->type = CEETM_PRIO;
6124 + child_cl->shaped = priv->shaped;
6125 + child_cl->prio.child = NULL;
6126 + child_cl->ch = priv->prio.ch;
6127 +
6128 + /* All shaped CQs have CR and ER enabled by default */
6129 + child_cl->prio.cr = child_cl->shaped;
6130 + child_cl->prio.er = child_cl->shaped;
6131 + child_cl->prio.fq = NULL;
6132 + child_cl->prio.cq = NULL;
6133 +
6134 + /* Configure the corresponding hardware CQ */
6135 + err = ceetm_config_prio_cls(child_cl, dev, i);
6136 + if (err) {
6137 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
6138 + __func__, child_cl->common.classid);
6139 + goto err_init_prio_cls;
6140 + }
6141 +
6142 + /* Add class handle in Qdisc */
6143 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
6144 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
6145 + __func__, child_cl->common.classid,
6146 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
6147 + }
6148 +
6149 + return 0;
6150 +
6151 +err_init_prio_cls:
6152 + ceetm_cls_destroy(sch, child_cl);
6153 +err_init_prio:
6154 + ceetm_destroy(sch);
6155 + return err;
6156 +}
6157 +
6158 +/* Configure a wbfs ceetm qdisc */
6159 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
6160 + struct tc_ceetm_qopt *qopt)
6161 +{
6162 + int err, group_b, small_group;
6163 + unsigned int i, id, prio_a, prio_b;
6164 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
6165 + struct Qdisc *parent_qdisc;
6166 + struct ceetm_qdisc *parent_priv;
6167 + struct net_device *dev = qdisc_dev(sch);
6168 +
6169 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6170 +
6171 + /* Validate inputs */
6172 + if (sch->parent == TC_H_ROOT) {
6173 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
6174 + err = -EINVAL;
6175 + goto err_init_wbfs;
6176 + }
6177 +
6178 + /* Obtain the parent prio ceetm qdisc */
6179 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
6180 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
6181 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
6182 + err = -EINVAL;
6183 + goto err_init_wbfs;
6184 + }
6185 +
6186 + /* Obtain the parent prio ceetm class */
6187 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
6188 + parent_priv = qdisc_priv(parent_qdisc);
6189 +
6190 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
6191 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
6192 + err = -EINVAL;
6193 + goto err_init_wbfs;
6194 + }
6195 +
6196 + if (!qopt->qcount || !qopt->qweight[0]) {
6197 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
6198 + err = -EINVAL;
6199 + goto err_init_wbfs;
6200 + }
6201 +
6202 + priv->shaped = parent_cl->shaped;
6203 +
6204 + if (!priv->shaped && (qopt->cr || qopt->er)) {
6205 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
6206 + err = -EINVAL;
6207 + goto err_init_wbfs;
6208 + }
6209 +
6210 + if (priv->shaped && !(qopt->cr || qopt->er)) {
6211 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
6212 + err = -EINVAL;
6213 + goto err_init_wbfs;
6214 + }
6215 +
6216 + /* Obtain the parent root ceetm class */
6217 + root_cl = parent_priv->prio.parent;
6218 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
6219 + root_cl->root.wbfs_grp_large) {
6220 + pr_err("CEETM: no more wbfs classes are available\n");
6221 + err = -EINVAL;
6222 + goto err_init_wbfs;
6223 + }
6224 +
6225 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
6226 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
6227 + pr_err("CEETM: only %d wbfs classes are available\n",
6228 + CEETM_MIN_WBFS_QCOUNT);
6229 + err = -EINVAL;
6230 + goto err_init_wbfs;
6231 + }
6232 +
6233 + priv->wbfs.parent = parent_cl;
6234 + parent_cl->prio.child = sch;
6235 +
6236 + priv->wbfs.qcount = qopt->qcount;
6237 + priv->wbfs.cr = qopt->cr;
6238 + priv->wbfs.er = qopt->er;
6239 + priv->wbfs.ch = parent_cl->ch;
6240 +
6241 + /* Configure the hardware wbfs channel groups */
6242 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
6243 + /* Configure the large group A */
6244 + priv->wbfs.group_type = WBFS_GRP_LARGE;
6245 + small_group = false;
6246 + group_b = false;
6247 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
6248 + prio_b = prio_a;
6249 +
6250 + } else if (root_cl->root.wbfs_grp_a) {
6251 + /* Configure the group B */
6252 + priv->wbfs.group_type = WBFS_GRP_B;
6253 +
6254 + err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group,
6255 + &prio_a, &prio_b);
6256 + if (err) {
6257 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
6258 + __func__);
6259 + goto err_init_wbfs;
6260 + }
6261 +
6262 + small_group = true;
6263 + group_b = true;
6264 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
6265 + /* If group A isn't configured, configure it as group B */
6266 + prio_a = prio_a ? : prio_b;
6267 +
6268 + } else {
6269 + /* Configure the small group A */
6270 + priv->wbfs.group_type = WBFS_GRP_A;
6271 +
6272 + err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group,
6273 + &prio_a, &prio_b);
6274 + if (err) {
6275 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
6276 + __func__);
6277 + goto err_init_wbfs;
6278 + }
6279 +
6280 + small_group = true;
6281 + group_b = false;
6282 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
6283 + /* If group B isn't configured, configure it as group A */
6284 + prio_b = prio_b ? : prio_a;
6285 + }
6286 +
6287 + err = qman_ceetm_channel_set_group(priv->wbfs.ch, small_group, prio_a,
6288 + prio_b);
6289 + if (err)
6290 + goto err_init_wbfs;
6291 +
6292 + if (priv->shaped) {
6293 + err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch,
6294 + group_b,
6295 + priv->wbfs.cr);
6296 + if (err) {
6297 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
6298 + __func__);
6299 + goto err_init_wbfs;
6300 + }
6301 +
6302 + err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch,
6303 + group_b,
6304 + priv->wbfs.er);
6305 + if (err) {
6306 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
6307 + __func__);
6308 + goto err_init_wbfs;
6309 + }
6310 + }
6311 +
6312 + /* Create qcount child classes */
6313 + for (i = 0; i < priv->wbfs.qcount; i++) {
6314 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
6315 + if (!child_cl) {
6316 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
6317 + __func__);
6318 + err = -ENOMEM;
6319 + goto err_init_wbfs;
6320 + }
6321 +
6322 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
6323 + if (!child_cl->wbfs.cstats) {
6324 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
6325 + __func__);
6326 + err = -ENOMEM;
6327 + goto err_init_wbfs_cls;
6328 + }
6329 +
6330 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
6331 + child_cl->parent = sch;
6332 + child_cl->type = CEETM_WBFS;
6333 + child_cl->shaped = priv->shaped;
6334 + child_cl->wbfs.fq = NULL;
6335 + child_cl->wbfs.cq = NULL;
6336 + child_cl->wbfs.weight = qopt->qweight[i];
6337 + child_cl->ch = priv->wbfs.ch;
6338 +
6339 + if (priv->wbfs.group_type == WBFS_GRP_B)
6340 + id = WBFS_GRP_B_OFFSET + i;
6341 + else
6342 + id = WBFS_GRP_A_OFFSET + i;
6343 +
6344 + err = ceetm_config_wbfs_cls(child_cl, dev, id,
6345 + priv->wbfs.group_type);
6346 + if (err) {
6347 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
6348 + __func__, child_cl->common.classid);
6349 + goto err_init_wbfs_cls;
6350 + }
6351 +
6352 + /* Add class handle in Qdisc */
6353 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
6354 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
6355 + __func__, child_cl->common.classid,
6356 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
6357 + }
6358 +
6359 + /* Signal the root class that a group has been configured */
6360 + switch (priv->wbfs.group_type) {
6361 + case WBFS_GRP_LARGE:
6362 + root_cl->root.wbfs_grp_large = true;
6363 + break;
6364 + case WBFS_GRP_A:
6365 + root_cl->root.wbfs_grp_a = true;
6366 + break;
6367 + case WBFS_GRP_B:
6368 + root_cl->root.wbfs_grp_b = true;
6369 + break;
6370 + }
6371 +
6372 + return 0;
6373 +
6374 +err_init_wbfs_cls:
6375 + ceetm_cls_destroy(sch, child_cl);
6376 +err_init_wbfs:
6377 + ceetm_destroy(sch);
6378 + return err;
6379 +}
6380 +
6381 +/* Configure a generic ceetm qdisc */
6382 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
6383 +{
6384 + struct tc_ceetm_qopt *qopt;
6385 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
6386 + int ret;
6387 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6388 + struct net_device *dev = qdisc_dev(sch);
6389 +
6390 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6391 +
6392 + if (!netif_is_multiqueue(dev))
6393 + return -EOPNOTSUPP;
6394 +
6395 + if (!opt) {
6396 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6397 + return -EINVAL;
6398 + }
6399 +
6400 + ret = tcf_block_get(&priv->block, &priv->filter_list);
6401 + if (ret)
6402 + return ret;
6403 +
6404 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL);
6405 + if (ret < 0) {
6406 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6407 + return ret;
6408 + }
6409 +
6410 + if (!tb[TCA_CEETM_QOPS]) {
6411 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6412 + return -EINVAL;
6413 + }
6414 +
6415 + if (TC_H_MIN(sch->handle)) {
6416 + pr_err("CEETM: a qdisc should not have a minor\n");
6417 + return -EINVAL;
6418 + }
6419 +
6420 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
6421 +
6422 + /* Initialize the class hash list. Each qdisc has its own class hash */
6423 + ret = qdisc_class_hash_init(&priv->clhash);
6424 + if (ret < 0) {
6425 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
6426 + __func__);
6427 + return ret;
6428 + }
6429 +
6430 + priv->type = qopt->type;
6431 +
6432 + switch (priv->type) {
6433 + case CEETM_ROOT:
6434 + netif_tx_stop_all_queues(dev);
6435 + dpaa_drain_fqs(dev);
6436 + ret = ceetm_init_root(sch, priv, qopt);
6437 + netif_tx_wake_all_queues(dev);
6438 + break;
6439 + case CEETM_PRIO:
6440 + ret = ceetm_init_prio(sch, priv, qopt);
6441 + break;
6442 + case CEETM_WBFS:
6443 + ret = ceetm_init_wbfs(sch, priv, qopt);
6444 + break;
6445 + default:
6446 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
6447 + ceetm_destroy(sch);
6448 + ret = -EINVAL;
6449 + }
6450 +
6451 + return ret;
6452 +}
6453 +
6454 +/* Edit a root ceetm qdisc */
6455 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
6456 + struct net_device *dev,
6457 + struct tc_ceetm_qopt *qopt)
6458 +{
6459 + int err = 0;
6460 + u64 bps;
6461 +
6462 + if (priv->shaped != (bool)qopt->shaped) {
6463 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
6464 + priv->shaped ? "shaped" : "unshaped");
6465 + return -EINVAL;
6466 + }
6467 +
6468 + /* Nothing to modify for unshaped qdiscs */
6469 + if (!priv->shaped)
6470 + return 0;
6471 +
6472 + /* Configure the LNI shaper */
6473 + if (priv->root.overhead != qopt->overhead) {
6474 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
6475 + qopt->overhead);
6476 + if (err)
6477 + goto change_err;
6478 + priv->root.overhead = qopt->overhead;
6479 + }
6480 +
6481 + if (priv->root.rate != qopt->rate) {
6482 + bps = qopt->rate << 3; /* Bps -> bps */
6483 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
6484 + dev->mtu);
6485 + if (err)
6486 + goto change_err;
6487 + priv->root.rate = qopt->rate;
6488 + }
6489 +
6490 + if (priv->root.ceil != qopt->ceil) {
6491 + bps = qopt->ceil << 3; /* Bps -> bps */
6492 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
6493 + dev->mtu);
6494 + if (err)
6495 + goto change_err;
6496 + priv->root.ceil = qopt->ceil;
6497 + }
6498 +
6499 + return 0;
6500 +
6501 +change_err:
6502 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
6503 + __func__, sch->handle);
6504 + return err;
6505 +}
6506 +
6507 +/* Edit a wbfs ceetm qdisc */
6508 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
6509 + struct tc_ceetm_qopt *qopt)
6510 +{
6511 + int err;
6512 + bool group_b;
6513 +
6514 + if (qopt->qcount) {
6515 + pr_err("CEETM: the qcount can not be modified\n");
6516 + return -EINVAL;
6517 + }
6518 +
6519 + if (qopt->qweight[0]) {
6520 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
6521 + return -EINVAL;
6522 + }
6523 +
6524 + if (!priv->shaped && (qopt->cr || qopt->er)) {
6525 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
6526 + return -EINVAL;
6527 + }
6528 +
6529 + if (priv->shaped && !(qopt->cr || qopt->er)) {
6530 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
6531 + return -EINVAL;
6532 + }
6533 +
6534 + /* Nothing to modify for unshaped qdiscs */
6535 + if (!priv->shaped)
6536 + return 0;
6537 +
6538 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
6539 +
6540 + if (qopt->cr != priv->wbfs.cr) {
6541 + err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch,
6542 + group_b,
6543 + qopt->cr);
6544 + if (err)
6545 + goto change_err;
6546 + priv->wbfs.cr = qopt->cr;
6547 + }
6548 +
6549 + if (qopt->er != priv->wbfs.er) {
6550 + err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch,
6551 + group_b,
6552 + qopt->er);
6553 + if (err)
6554 + goto change_err;
6555 + priv->wbfs.er = qopt->er;
6556 + }
6557 +
6558 + return 0;
6559 +
6560 +change_err:
6561 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
6562 + __func__, sch->handle);
6563 + return err;
6564 +}
6565 +
6566 +/* Edit a ceetm qdisc */
6567 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
6568 +{
6569 + struct tc_ceetm_qopt *qopt;
6570 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
6571 + int ret;
6572 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6573 + struct net_device *dev = qdisc_dev(sch);
6574 +
6575 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6576 +
6577 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL);
6578 + if (ret < 0) {
6579 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6580 + return ret;
6581 + }
6582 +
6583 + if (!tb[TCA_CEETM_QOPS]) {
6584 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6585 + return -EINVAL;
6586 + }
6587 +
6588 + if (TC_H_MIN(sch->handle)) {
6589 + pr_err("CEETM: a qdisc should not have a minor\n");
6590 + return -EINVAL;
6591 + }
6592 +
6593 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
6594 +
6595 + if (priv->type != qopt->type) {
6596 + pr_err("CEETM: qdisc %X is not of the provided type\n",
6597 + sch->handle);
6598 + return -EINVAL;
6599 + }
6600 +
6601 + switch (priv->type) {
6602 + case CEETM_ROOT:
6603 + ret = ceetm_change_root(sch, priv, dev, qopt);
6604 + break;
6605 + case CEETM_PRIO:
6606 + pr_err("CEETM: prio qdiscs can not be modified\n");
6607 + ret = -EINVAL;
6608 + break;
6609 + case CEETM_WBFS:
6610 + ret = ceetm_change_wbfs(sch, priv, qopt);
6611 + break;
6612 + default:
6613 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
6614 + ret = -EINVAL;
6615 + }
6616 +
6617 + return ret;
6618 +}
6619 +
6620 +/* Graft the underlying pfifo qdiscs to the netdev queues.
6621 + * It's safe to remove our references at this point, since the kernel will
6622 + * destroy the qdiscs on its own and no cleanup from our part is required.
6623 + */
6624 +static void ceetm_attach(struct Qdisc *sch)
6625 +{
6626 + struct net_device *dev = qdisc_dev(sch);
6627 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6628 + struct Qdisc *qdisc, *old_qdisc;
6629 + unsigned int i;
6630 +
6631 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6632 +
6633 + for (i = 0; i < dev->num_tx_queues; i++) {
6634 + qdisc = priv->root.qdiscs[i];
6635 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
6636 + if (old_qdisc)
6637 + qdisc_destroy(old_qdisc);
6638 + }
6639 +
6640 + kfree(priv->root.qdiscs);
6641 + priv->root.qdiscs = NULL;
6642 +}
6643 +
6644 +static unsigned long ceetm_cls_search(struct Qdisc *sch, u32 handle)
6645 +{
6646 + return (unsigned long)ceetm_find(handle, sch);
6647 +}
6648 +
6649 +static int ceetm_cls_change_root(struct ceetm_class *cl,
6650 + struct tc_ceetm_copt *copt,
6651 + struct net_device *dev)
6652 +{
6653 + int err;
6654 + u64 bps;
6655 +
6656 + if ((bool)copt->shaped != cl->shaped) {
6657 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
6658 + cl->shaped ? "shaped" : "unshaped");
6659 + return -EINVAL;
6660 + }
6661 +
6662 + if (cl->shaped && cl->root.rate != copt->rate) {
6663 + bps = copt->rate << 3; /* Bps -> bps */
6664 + err = qman_ceetm_channel_set_commit_rate_bps(cl->ch, bps,
6665 + dev->mtu);
6666 + if (err)
6667 + goto change_cls_err;
6668 + cl->root.rate = copt->rate;
6669 + }
6670 +
6671 + if (cl->shaped && cl->root.ceil != copt->ceil) {
6672 + bps = copt->ceil << 3; /* Bps -> bps */
6673 + err = qman_ceetm_channel_set_excess_rate_bps(cl->ch, bps,
6674 + dev->mtu);
6675 + if (err)
6676 + goto change_cls_err;
6677 + cl->root.ceil = copt->ceil;
6678 + }
6679 +
6680 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
6681 + err = qman_ceetm_channel_set_weight(cl->ch, copt->tbl);
6682 + if (err)
6683 + goto change_cls_err;
6684 + cl->root.tbl = copt->tbl;
6685 + }
6686 +
6687 + return 0;
6688 +
6689 +change_cls_err:
6690 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
6691 + __func__, cl->common.classid);
6692 + return err;
6693 +}
6694 +
6695 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
6696 + struct tc_ceetm_copt *copt)
6697 +{
6698 + int err;
6699 +
6700 + if (!cl->shaped && (copt->cr || copt->er)) {
6701 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
6702 + return -EINVAL;
6703 + }
6704 +
6705 + if (cl->prio.cr != (bool)copt->cr) {
6706 + err = qman_ceetm_channel_set_cq_cr_eligibility(
6707 + cl->prio.cq->parent,
6708 + cl->prio.cq->idx,
6709 + copt->cr);
6710 + if (err)
6711 + goto change_cls_err;
6712 + cl->prio.cr = copt->cr;
6713 + }
6714 +
6715 + if (cl->prio.er != (bool)copt->er) {
6716 + err = qman_ceetm_channel_set_cq_er_eligibility(
6717 + cl->prio.cq->parent,
6718 + cl->prio.cq->idx,
6719 + copt->er);
6720 + if (err)
6721 + goto change_cls_err;
6722 + cl->prio.er = copt->er;
6723 + }
6724 +
6725 + return 0;
6726 +
6727 +change_cls_err:
6728 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
6729 + __func__, cl->common.classid);
6730 + return err;
6731 +}
6732 +
6733 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
6734 + struct tc_ceetm_copt *copt)
6735 +{
6736 + int err;
6737 +
6738 + if (copt->weight != cl->wbfs.weight) {
6739 + /* Configure the CQ weight: real number multiplied by 100 to
6740 + * get rid of the fraction
6741 + */
6742 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
6743 + copt->weight * 100);
6744 +
6745 + if (err) {
6746 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
6747 + __func__, cl->common.classid);
6748 + return err;
6749 + }
6750 +
6751 + cl->wbfs.weight = copt->weight;
6752 + }
6753 +
6754 + return 0;
6755 +}
6756 +
6757 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
6758 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
6759 + struct nlattr **tca, unsigned long *arg)
6760 +{
6761 + int err;
6762 + u64 bps;
6763 + struct ceetm_qdisc *priv;
6764 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
6765 + struct nlattr *opt = tca[TCA_OPTIONS];
6766 + struct nlattr *tb[__TCA_CEETM_MAX];
6767 + struct tc_ceetm_copt *copt;
6768 + struct qm_ceetm_channel *channel;
6769 + struct net_device *dev = qdisc_dev(sch);
6770 +
6771 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
6772 + __func__, classid, sch->handle);
6773 +
6774 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
6775 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
6776 + return -EINVAL;
6777 + }
6778 +
6779 + priv = qdisc_priv(sch);
6780 +
6781 + if (!opt) {
6782 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6783 + return -EINVAL;
6784 + }
6785 +
6786 + if (!cl && sch->handle != parentid) {
6787 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
6788 + return -EINVAL;
6789 + }
6790 +
6791 + if (!cl && priv->type != CEETM_ROOT) {
6792 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
6793 + return -EINVAL;
6794 + }
6795 +
6796 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy, NULL);
6797 + if (err < 0) {
6798 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6799 + return -EINVAL;
6800 + }
6801 +
6802 + if (!tb[TCA_CEETM_COPT]) {
6803 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
6804 + return -EINVAL;
6805 + }
6806 +
6807 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
6808 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
6809 + return -EINVAL;
6810 + }
6811 +
6812 + copt = nla_data(tb[TCA_CEETM_COPT]);
6813 +
6814 + /* Configure an existing ceetm class */
6815 + if (cl) {
6816 + if (copt->type != cl->type) {
6817 + pr_err("CEETM: class %X is not of the provided type\n",
6818 + cl->common.classid);
6819 + return -EINVAL;
6820 + }
6821 +
6822 + switch (copt->type) {
6823 + case CEETM_ROOT:
6824 + return ceetm_cls_change_root(cl, copt, dev);
6825 +
6826 + case CEETM_PRIO:
6827 + return ceetm_cls_change_prio(cl, copt);
6828 +
6829 + case CEETM_WBFS:
6830 + return ceetm_cls_change_wbfs(cl, copt);
6831 +
6832 + default:
6833 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
6834 + __func__);
6835 + return -EINVAL;
6836 + }
6837 + }
6838 +
6839 + /* Add a new root ceetm class */
6840 + if (copt->type != CEETM_ROOT) {
6841 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
6842 + return -EINVAL;
6843 + }
6844 +
6845 + if (copt->shaped && !priv->shaped) {
6846 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
6847 + return -EINVAL;
6848 + }
6849 +
6850 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
6851 + if (!cl)
6852 + return -ENOMEM;
6853 +
6854 + err = tcf_block_get(&cl->block, &cl->filter_list);
6855 + if (err) {
6856 + kfree(cl);
6857 + return err;
6858 + }
6859 +
6860 + cl->type = copt->type;
6861 + cl->shaped = copt->shaped;
6862 + cl->root.rate = copt->rate;
6863 + cl->root.ceil = copt->ceil;
6864 + cl->root.tbl = copt->tbl;
6865 +
6866 + cl->common.classid = classid;
6867 + cl->parent = sch;
6868 + cl->root.child = NULL;
6869 + cl->root.wbfs_grp_a = false;
6870 + cl->root.wbfs_grp_b = false;
6871 + cl->root.wbfs_grp_large = false;
6872 +
6873 + /* Claim a CEETM channel */
6874 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
6875 + if (err) {
6876 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
6877 + __func__);
6878 + goto claim_err;
6879 + }
6880 +
6881 + cl->ch = channel;
6882 +
6883 + if (cl->shaped) {
6884 + /* Configure the channel shaper */
6885 + err = qman_ceetm_channel_enable_shaper(channel, 1);
6886 + if (err)
6887 + goto channel_err;
6888 +
6889 + bps = cl->root.rate << 3; /* Bps -> bps */
6890 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
6891 + dev->mtu);
6892 + if (err)
6893 + goto channel_err;
6894 +
6895 + bps = cl->root.ceil << 3; /* Bps -> bps */
6896 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
6897 + dev->mtu);
6898 + if (err)
6899 + goto channel_err;
6900 +
6901 + } else {
6902 + /* Configure the uFQ algorithm */
6903 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
6904 + if (err)
6905 + goto channel_err;
6906 + }
6907 +
6908 + /* Add class handle in Qdisc */
6909 + ceetm_link_class(sch, &priv->clhash, &cl->common);
6910 +
6911 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
6912 + __func__, classid, channel->idx);
6913 + *arg = (unsigned long)cl;
6914 + return 0;
6915 +
6916 +channel_err:
6917 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
6918 + __func__, channel->idx);
6919 + if (qman_ceetm_channel_release(channel))
6920 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
6921 + __func__, channel->idx);
6922 +claim_err:
6923 + tcf_block_put(cl->block);
6924 + kfree(cl);
6925 + return err;
6926 +}
6927 +
6928 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
6929 +{
6930 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6931 + struct ceetm_class *cl;
6932 + unsigned int i;
6933 +
6934 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6935 +
6936 + if (arg->stop)
6937 + return;
6938 +
6939 + for (i = 0; i < priv->clhash.hashsize; i++) {
6940 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
6941 + if (arg->count < arg->skip) {
6942 + arg->count++;
6943 + continue;
6944 + }
6945 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
6946 + arg->stop = 1;
6947 + return;
6948 + }
6949 + arg->count++;
6950 + }
6951 + }
6952 +}
6953 +
6954 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
6955 + struct sk_buff *skb, struct tcmsg *tcm)
6956 +{
6957 + struct ceetm_class *cl = (struct ceetm_class *)arg;
6958 + struct nlattr *nest;
6959 + struct tc_ceetm_copt copt;
6960 +
6961 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
6962 + __func__, cl->common.classid, sch->handle);
6963 +
6964 + sch_tree_lock(sch);
6965 +
6966 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
6967 + tcm->tcm_handle = cl->common.classid;
6968 +
6969 + memset(&copt, 0, sizeof(copt));
6970 +
6971 + copt.shaped = cl->shaped;
6972 + copt.type = cl->type;
6973 +
6974 + switch (cl->type) {
6975 + case CEETM_ROOT:
6976 + if (cl->root.child)
6977 + tcm->tcm_info = cl->root.child->handle;
6978 +
6979 + copt.rate = cl->root.rate;
6980 + copt.ceil = cl->root.ceil;
6981 + copt.tbl = cl->root.tbl;
6982 + break;
6983 +
6984 + case CEETM_PRIO:
6985 + if (cl->prio.child)
6986 + tcm->tcm_info = cl->prio.child->handle;
6987 +
6988 + copt.cr = cl->prio.cr;
6989 + copt.er = cl->prio.er;
6990 + break;
6991 +
6992 + case CEETM_WBFS:
6993 + copt.weight = cl->wbfs.weight;
6994 + break;
6995 + }
6996 +
6997 + nest = nla_nest_start(skb, TCA_OPTIONS);
6998 + if (!nest)
6999 + goto nla_put_failure;
7000 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
7001 + goto nla_put_failure;
7002 + nla_nest_end(skb, nest);
7003 + sch_tree_unlock(sch);
7004 + return skb->len;
7005 +
7006 +nla_put_failure:
7007 + sch_tree_unlock(sch);
7008 + nla_nest_cancel(skb, nest);
7009 + return -EMSGSIZE;
7010 +}
7011 +
7012 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
7013 +{
7014 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7015 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7016 +
7017 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
7018 + __func__, cl->common.classid, sch->handle);
7019 +
7020 + sch_tree_lock(sch);
7021 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
7022 +
7023 + sch_tree_unlock(sch);
7024 + ceetm_cls_destroy(sch, cl);
7025 + return 0;
7026 +}
7027 +
7028 +/* Get the class' child qdisc, if any */
7029 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
7030 +{
7031 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7032 +
7033 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
7034 + __func__, cl->common.classid, sch->handle);
7035 +
7036 + switch (cl->type) {
7037 + case CEETM_ROOT:
7038 + return cl->root.child;
7039 +
7040 + case CEETM_PRIO:
7041 + return cl->prio.child;
7042 + }
7043 +
7044 + return NULL;
7045 +}
7046 +
7047 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
7048 + struct Qdisc *new, struct Qdisc **old)
7049 +{
7050 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
7051 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
7052 + return -EOPNOTSUPP;
7053 + }
7054 +
7055 + return 0;
7056 +}
7057 +
7058 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
7059 + struct gnet_dump *d)
7060 +{
7061 + unsigned int i;
7062 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7063 + struct gnet_stats_basic_packed tmp_bstats;
7064 + struct ceetm_class_stats *cstats = NULL;
7065 + struct qm_ceetm_cq *cq = NULL;
7066 + struct tc_ceetm_xstats xstats;
7067 +
7068 + memset(&xstats, 0, sizeof(xstats));
7069 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
7070 +
7071 + switch (cl->type) {
7072 + case CEETM_ROOT:
7073 + return 0;
7074 + case CEETM_PRIO:
7075 + cq = cl->prio.cq;
7076 + break;
7077 + case CEETM_WBFS:
7078 + cq = cl->wbfs.cq;
7079 + break;
7080 + }
7081 +
7082 + for_each_online_cpu(i) {
7083 + switch (cl->type) {
7084 + case CEETM_PRIO:
7085 + cstats = per_cpu_ptr(cl->prio.cstats, i);
7086 + break;
7087 + case CEETM_WBFS:
7088 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
7089 + break;
7090 + }
7091 +
7092 + if (cstats) {
7093 + xstats.ern_drop_count += cstats->ern_drop_count;
7094 + xstats.congested_count += cstats->congested_count;
7095 + tmp_bstats.bytes += cstats->bstats.bytes;
7096 + tmp_bstats.packets += cstats->bstats.packets;
7097 + }
7098 + }
7099 +
7100 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
7101 + d, NULL, &tmp_bstats) < 0)
7102 + return -1;
7103 +
7104 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
7105 + &xstats.frame_count,
7106 + &xstats.byte_count))
7107 + return -1;
7108 +
7109 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
7110 +}
7111 +
7112 +static struct tcf_block *ceetm_tcf_block(struct Qdisc *sch, unsigned long arg)
7113 +{
7114 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7115 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7116 + struct tcf_block *block = cl ? cl->block : priv->block;
7117 +
7118 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
7119 + cl ? cl->common.classid : 0, sch->handle);
7120 + return block;
7121 +}
7122 +
7123 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
7124 + u32 classid)
7125 +{
7126 + struct ceetm_class *cl = ceetm_find(classid, sch);
7127 +
7128 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
7129 + cl ? cl->common.classid : 0, sch->handle);
7130 + return (unsigned long)cl;
7131 +}
7132 +
7133 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
7134 +{
7135 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7136 +
7137 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
7138 + cl ? cl->common.classid : 0, sch->handle);
7139 +}
7140 +
7141 +const struct Qdisc_class_ops ceetm_cls_ops = {
7142 + .graft = ceetm_cls_graft,
7143 + .leaf = ceetm_cls_leaf,
7144 + .find = ceetm_cls_search,
7145 + .change = ceetm_cls_change,
7146 + .delete = ceetm_cls_delete,
7147 + .walk = ceetm_cls_walk,
7148 + .tcf_block = ceetm_tcf_block,
7149 + .bind_tcf = ceetm_tcf_bind,
7150 + .unbind_tcf = ceetm_tcf_unbind,
7151 + .dump = ceetm_cls_dump,
7152 + .dump_stats = ceetm_cls_dump_stats,
7153 +};
7154 +
7155 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
7156 + .id = "ceetm",
7157 + .priv_size = sizeof(struct ceetm_qdisc),
7158 + .cl_ops = &ceetm_cls_ops,
7159 + .init = ceetm_init,
7160 + .destroy = ceetm_destroy,
7161 + .change = ceetm_change,
7162 + .dump = ceetm_dump,
7163 + .attach = ceetm_attach,
7164 + .owner = THIS_MODULE,
7165 +};
7166 +
7167 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
7168 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
7169 + struct Qdisc *sch, int *qerr,
7170 + bool *act_drop)
7171 +{
7172 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7173 + struct ceetm_class *cl = NULL, *wbfs_cl;
7174 + struct tcf_result res;
7175 + struct tcf_proto *tcf;
7176 + int result;
7177 +
7178 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
7179 + tcf = priv->filter_list;
7180 + while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) {
7181 +#ifdef CONFIG_NET_CLS_ACT
7182 + switch (result) {
7183 + case TC_ACT_QUEUED:
7184 + case TC_ACT_STOLEN:
7185 + case TC_ACT_TRAP:
7186 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
7187 + case TC_ACT_SHOT:
7188 + /* No valid class found due to action */
7189 + *act_drop = true;
7190 + return NULL;
7191 + }
7192 +#endif
7193 + cl = (void *)res.class;
7194 + if (!cl) {
7195 + if (res.classid == sch->handle) {
7196 + /* The filter leads to the qdisc */
7197 + /* TODO default qdisc */
7198 + return NULL;
7199 + }
7200 +
7201 + cl = ceetm_find(res.classid, sch);
7202 + if (!cl)
7203 + /* The filter leads to an invalid class */
7204 + break;
7205 + }
7206 +
7207 + /* The class might have its own filters attached */
7208 + tcf = cl->filter_list;
7209 + }
7210 +
7211 + if (!cl) {
7212 + /* No valid class found */
7213 + /* TODO default qdisc */
7214 + return NULL;
7215 + }
7216 +
7217 + switch (cl->type) {
7218 + case CEETM_ROOT:
7219 + if (cl->root.child) {
7220 + /* Run the prio qdisc classifiers */
7221 + return ceetm_classify(skb, cl->root.child, qerr,
7222 + act_drop);
7223 + } else {
7224 + /* The root class does not have a child prio qdisc */
7225 + /* TODO default qdisc */
7226 + return NULL;
7227 + }
7228 + case CEETM_PRIO:
7229 + if (cl->prio.child) {
7230 + /* If filters lead to a wbfs class, return it.
7231 + * Otherwise, return the prio class
7232 + */
7233 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
7234 + act_drop);
7235 + /* A NULL result might indicate either an erroneous
7236 + * filter, or no filters at all. We will assume the
7237 + * latter
7238 + */
7239 + return wbfs_cl ? : cl;
7240 + }
7241 + }
7242 +
7243 + /* For wbfs and childless prio classes, return the class directly */
7244 + return cl;
7245 +}
7246 +
7247 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
7248 +{
7249 + const int queue_mapping = dpa_get_queue_mapping(skb);
7250 + struct Qdisc *sch = net_dev->qdisc;
7251 + struct ceetm_class_stats *cstats;
7252 + struct ceetm_qdisc_stats *qstats;
7253 + struct dpa_priv_s *priv_dpa;
7254 + struct ceetm_fq *ceetm_fq;
7255 + struct ceetm_qdisc *priv;
7256 + struct qman_fq *conf_fq;
7257 + struct ceetm_class *cl;
7258 + spinlock_t *root_lock;
7259 + bool act_drop = false;
7260 + int ret;
7261 +
7262 + root_lock = qdisc_lock(sch);
7263 + priv = qdisc_priv(sch);
7264 + qstats = this_cpu_ptr(priv->root.qstats);
7265 +
7266 + spin_lock(root_lock);
7267 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
7268 + spin_unlock(root_lock);
7269 +
7270 +#ifdef CONFIG_NET_CLS_ACT
7271 + if (act_drop) {
7272 + if (ret & __NET_XMIT_BYPASS)
7273 + qstats->drops++;
7274 + goto drop;
7275 + }
7276 +#endif
7277 + /* TODO default class */
7278 + if (unlikely(!cl)) {
7279 + qstats->drops++;
7280 + goto drop;
7281 + }
7282 +
7283 + priv_dpa = netdev_priv(net_dev);
7284 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
7285 +
7286 + /* Choose the proper tx fq and update the basic stats (bytes and
7287 + * packets sent by the class)
7288 + */
7289 + switch (cl->type) {
7290 + case CEETM_PRIO:
7291 + ceetm_fq = cl->prio.fq;
7292 + cstats = this_cpu_ptr(cl->prio.cstats);
7293 + break;
7294 + case CEETM_WBFS:
7295 + ceetm_fq = cl->wbfs.fq;
7296 + cstats = this_cpu_ptr(cl->wbfs.cstats);
7297 + break;
7298 + default:
7299 + qstats->drops++;
7300 + goto drop;
7301 + }
7302 +
7303 + /* If the FQ is congested, avoid enqueuing the frame and dropping it
7304 + * when it returns on the ERN path. Drop it here directly instead.
7305 + */
7306 + if (unlikely(ceetm_fq->congested)) {
7307 + qstats->drops++;
7308 + goto drop;
7309 + }
7310 +
7311 + bstats_update(&cstats->bstats, skb);
7312 + return dpa_tx_extended(skb, net_dev, &ceetm_fq->fq, conf_fq);
7313 +
7314 +drop:
7315 + dev_kfree_skb_any(skb);
7316 + return NET_XMIT_SUCCESS;
7317 +}
7318 +
7319 +static int __init ceetm_register(void)
7320 +{
7321 + int _errno = 0;
7322 +
7323 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
7324 +
7325 + _errno = register_qdisc(&ceetm_qdisc_ops);
7326 + if (unlikely(_errno))
7327 + pr_err(KBUILD_MODNAME
7328 + ": %s:%hu:%s(): register_qdisc() = %d\n",
7329 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
7330 +
7331 + return _errno;
7332 +}
7333 +
7334 +static void __exit ceetm_unregister(void)
7335 +{
7336 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
7337 + KBUILD_BASENAME ".c", __func__);
7338 +
7339 + unregister_qdisc(&ceetm_qdisc_ops);
7340 +}
7341 +
7342 +module_init(ceetm_register);
7343 +module_exit(ceetm_unregister);
7344 --- /dev/null
7345 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
7346 @@ -0,0 +1,241 @@
7347 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
7348 + *
7349 + * Redistribution and use in source and binary forms, with or without
7350 + * modification, are permitted provided that the following conditions are met:
7351 + * * Redistributions of source code must retain the above copyright
7352 + * notice, this list of conditions and the following disclaimer.
7353 + * * Redistributions in binary form must reproduce the above copyright
7354 + * notice, this list of conditions and the following disclaimer in the
7355 + * documentation and/or other materials provided with the distribution.
7356 + * * Neither the name of Freescale Semiconductor nor the
7357 + * names of its contributors may be used to endorse or promote products
7358 + * derived from this software without specific prior written permission.
7359 + *
7360 + *
7361 + * ALTERNATIVELY, this software may be distributed under the terms of the
7362 + * GNU General Public License ("GPL") as published by the Free Software
7363 + * Foundation, either version 2 of that License or (at your option) any
7364 + * later version.
7365 + *
7366 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7367 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7368 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7369 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
7370 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7371 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7372 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7373 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7374 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7375 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7376 + */
7377 +
7378 +#ifndef __DPAA_ETH_CEETM_H
7379 +#define __DPAA_ETH_CEETM_H
7380 +
7381 +#include <net/pkt_sched.h>
7382 +#include <net/pkt_cls.h>
7383 +#include <net/netlink.h>
7384 +#include <lnxwrp_fm.h>
7385 +
7386 +#include "mac.h"
7387 +#include "dpaa_eth_common.h"
7388 +
7389 +/* Mask to determine the sub-portal id from a channel number */
7390 +#define CHANNEL_SP_MASK 0x1f
7391 +/* The number of the last channel that services DCP0, connected to FMan 0.
7392 + * Value validated for B4 and T series platforms.
7393 + */
7394 +#define DCP0_MAX_CHANNEL 0x80f
7395 +/* A2V=1 - field A2 is valid
7396 + * A0V=1 - field A0 is valid - enables frame confirmation
7397 + * OVOM=1 - override operation mode bits with values from A2
7398 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
7399 + * NL=0 - the BMI releases all the internal buffers
7400 + */
7401 +#define CEETM_CONTEXT_A 0x1a00000080000000
7402 +/* The ratio between the superior and inferior congestion state thresholds. The
7403 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
7404 + * scheduling).
7405 + */
7406 +#define CEETM_CCGR_RATIO 0.875
7407 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
7408 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
7409 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
7410 + * hex).
7411 + */
7412 +#define PFIFO_MIN_OFFSET 0x21
7413 +
7414 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
7415 +#define CEETM_MAX_PRIO_QCOUNT 8
7416 +#define CEETM_MAX_WBFS_QCOUNT 8
7417 +#define CEETM_MIN_WBFS_QCOUNT 4
7418 +
7419 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
7420 + * and/or 12-15 for group B).
7421 + */
7422 +#define WBFS_GRP_A_OFFSET 8
7423 +#define WBFS_GRP_B_OFFSET 12
7424 +
7425 +#define WBFS_GRP_A 1
7426 +#define WBFS_GRP_B 2
7427 +#define WBFS_GRP_LARGE 3
7428 +
7429 +enum {
7430 + TCA_CEETM_UNSPEC,
7431 + TCA_CEETM_COPT,
7432 + TCA_CEETM_QOPS,
7433 + __TCA_CEETM_MAX,
7434 +};
7435 +
7436 +/* CEETM configuration types */
7437 +enum {
7438 + CEETM_ROOT = 1,
7439 + CEETM_PRIO,
7440 + CEETM_WBFS
7441 +};
7442 +
7443 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
7444 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
7445 +
7446 +struct ceetm_class;
7447 +struct ceetm_qdisc_stats;
7448 +struct ceetm_class_stats;
7449 +
7450 +struct ceetm_fq {
7451 + struct qman_fq fq;
7452 + struct net_device *net_dev;
7453 + struct ceetm_class *ceetm_cls;
7454 + int congested; /* Congestion status */
7455 +};
7456 +
7457 +struct root_q {
7458 + struct Qdisc **qdiscs;
7459 + __u16 overhead;
7460 + __u32 rate;
7461 + __u32 ceil;
7462 + struct qm_ceetm_sp *sp;
7463 + struct qm_ceetm_lni *lni;
7464 + struct ceetm_qdisc_stats __percpu *qstats;
7465 +};
7466 +
7467 +struct prio_q {
7468 + __u16 qcount;
7469 + struct ceetm_class *parent;
7470 + struct qm_ceetm_channel *ch;
7471 +};
7472 +
7473 +struct wbfs_q {
7474 + __u16 qcount;
7475 + int group_type;
7476 + struct ceetm_class *parent;
7477 + struct qm_ceetm_channel *ch;
7478 + __u16 cr;
7479 + __u16 er;
7480 +};
7481 +
7482 +struct ceetm_qdisc {
7483 + int type; /* LNI/CHNL/WBFS */
7484 + bool shaped;
7485 + union {
7486 + struct root_q root;
7487 + struct prio_q prio;
7488 + struct wbfs_q wbfs;
7489 + };
7490 + struct Qdisc_class_hash clhash;
7491 + struct tcf_proto *filter_list; /* qdisc attached filters */
7492 + struct tcf_block *block;
7493 +};
7494 +
7495 +/* CEETM Qdisc configuration parameters */
7496 +struct tc_ceetm_qopt {
7497 + __u32 type;
7498 + __u16 shaped;
7499 + __u16 qcount;
7500 + __u16 overhead;
7501 + __u32 rate;
7502 + __u32 ceil;
7503 + __u16 cr;
7504 + __u16 er;
7505 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
7506 +};
7507 +
7508 +struct root_c {
7509 + unsigned int rate;
7510 + unsigned int ceil;
7511 + unsigned int tbl;
7512 + bool wbfs_grp_a;
7513 + bool wbfs_grp_b;
7514 + bool wbfs_grp_large;
7515 + struct Qdisc *child;
7516 +};
7517 +
7518 +struct prio_c {
7519 + bool cr;
7520 + bool er;
7521 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
7522 + struct qm_ceetm_lfq *lfq;
7523 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
7524 + struct qm_ceetm_ccg *ccg;
7525 + /* only one wbfs can be linked to one priority CQ */
7526 + struct Qdisc *child;
7527 + struct ceetm_class_stats __percpu *cstats;
7528 +};
7529 +
7530 +struct wbfs_c {
7531 + __u8 weight; /* The weight of the class between 1 and 248 */
7532 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
7533 + struct qm_ceetm_lfq *lfq;
7534 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
7535 + struct qm_ceetm_ccg *ccg;
7536 + struct ceetm_class_stats __percpu *cstats;
7537 +};
7538 +
7539 +struct ceetm_class {
7540 + struct Qdisc_class_common common;
7541 + struct tcf_proto *filter_list; /* class attached filters */
7542 + struct tcf_block *block;
7543 + struct Qdisc *parent;
7544 + struct qm_ceetm_channel *ch;
7545 + bool shaped;
7546 + int type; /* ROOT/PRIO/WBFS */
7547 + union {
7548 + struct root_c root;
7549 + struct prio_c prio;
7550 + struct wbfs_c wbfs;
7551 + };
7552 +};
7553 +
7554 +/* CEETM Class configuration parameters */
7555 +struct tc_ceetm_copt {
7556 + __u32 type;
7557 + __u16 shaped;
7558 + __u32 rate;
7559 + __u32 ceil;
7560 + __u16 tbl;
7561 + __u16 cr;
7562 + __u16 er;
7563 + __u8 weight;
7564 +};
7565 +
7566 +/* CEETM stats */
7567 +struct ceetm_qdisc_stats {
7568 + __u32 drops;
7569 +};
7570 +
7571 +struct ceetm_class_stats {
7572 + /* Software counters */
7573 + struct gnet_stats_basic_packed bstats;
7574 + __u32 ern_drop_count;
7575 + __u32 congested_count;
7576 +};
7577 +
7578 +struct tc_ceetm_xstats {
7579 + __u32 ern_drop_count;
7580 + __u32 congested_count;
7581 + /* Hardware counters */
7582 + __u64 frame_count;
7583 + __u64 byte_count;
7584 +};
7585 +
7586 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
7587 +#endif
7588 --- /dev/null
7589 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
7590 @@ -0,0 +1,1776 @@
7591 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
7592 + *
7593 + * Redistribution and use in source and binary forms, with or without
7594 + * modification, are permitted provided that the following conditions are met:
7595 + * * Redistributions of source code must retain the above copyright
7596 + * notice, this list of conditions and the following disclaimer.
7597 + * * Redistributions in binary form must reproduce the above copyright
7598 + * notice, this list of conditions and the following disclaimer in the
7599 + * documentation and/or other materials provided with the distribution.
7600 + * * Neither the name of Freescale Semiconductor nor the
7601 + * names of its contributors may be used to endorse or promote products
7602 + * derived from this software without specific prior written permission.
7603 + *
7604 + *
7605 + * ALTERNATIVELY, this software may be distributed under the terms of the
7606 + * GNU General Public License ("GPL") as published by the Free Software
7607 + * Foundation, either version 2 of that License or (at your option) any
7608 + * later version.
7609 + *
7610 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7611 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7612 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7613 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
7614 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7615 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7616 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7617 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7618 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7619 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7620 + */
7621 +
7622 +#include <linux/init.h>
7623 +#include <linux/module.h>
7624 +#include <linux/of_platform.h>
7625 +#include <linux/of_net.h>
7626 +#include <linux/etherdevice.h>
7627 +#include <linux/kthread.h>
7628 +#include <linux/percpu.h>
7629 +#include <linux/highmem.h>
7630 +#include <linux/sort.h>
7631 +#include <linux/fsl_qman.h>
7632 +#include <linux/ip.h>
7633 +#include <linux/ipv6.h>
7634 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
7635 +#include "dpaa_eth.h"
7636 +#include "dpaa_eth_common.h"
7637 +#ifdef CONFIG_FSL_DPAA_1588
7638 +#include "dpaa_1588.h"
7639 +#endif
7640 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
7641 +#include "dpaa_debugfs.h"
7642 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
7643 +#include "mac.h"
7644 +
7645 +/* Size in bytes of the FQ taildrop threshold */
7646 +#define DPA_FQ_TD 0x200000
7647 +
7648 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
7649 +struct ptp_priv_s ptp_priv;
7650 +#endif
7651 +
7652 +static struct dpa_bp *dpa_bp_array[64];
7653 +
7654 +int dpa_max_frm;
7655 +EXPORT_SYMBOL(dpa_max_frm);
7656 +
7657 +int dpa_rx_extra_headroom;
7658 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
7659 +
7660 +int dpa_num_cpus = NR_CPUS;
7661 +
7662 +static const struct fqid_cell tx_confirm_fqids[] = {
7663 + {0, DPAA_ETH_TX_QUEUES}
7664 +};
7665 +
7666 +static struct fqid_cell default_fqids[][3] = {
7667 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
7668 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
7669 +};
7670 +
7671 +static const char fsl_qman_frame_queues[][25] = {
7672 + [RX] = "fsl,qman-frame-queues-rx",
7673 + [TX] = "fsl,qman-frame-queues-tx"
7674 +};
7675 +#ifdef CONFIG_FSL_DPAA_HOOKS
7676 +/* A set of callbacks for hooking into the fastpath at different points. */
7677 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
7678 +EXPORT_SYMBOL(dpaa_eth_hooks);
7679 +/* This function should only be called on the probe paths, since it makes no
7680 + * effort to guarantee consistency of the destination hooks structure.
7681 + */
7682 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
7683 +{
7684 + if (hooks)
7685 + dpaa_eth_hooks = *hooks;
7686 + else
7687 + pr_err("NULL pointer to hooks!\n");
7688 +}
7689 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
7690 +#endif
7691 +
7692 +int dpa_netdev_init(struct net_device *net_dev,
7693 + const uint8_t *mac_addr,
7694 + uint16_t tx_timeout)
7695 +{
7696 + int err;
7697 + struct dpa_priv_s *priv = netdev_priv(net_dev);
7698 + struct device *dev = net_dev->dev.parent;
7699 +
7700 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
7701 +
7702 + net_dev->features |= net_dev->hw_features;
7703 + net_dev->vlan_features = net_dev->features;
7704 +
7705 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
7706 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
7707 +
7708 + net_dev->ethtool_ops = &dpa_ethtool_ops;
7709 +
7710 + net_dev->needed_headroom = priv->tx_headroom;
7711 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
7712 +
7713 + err = register_netdev(net_dev);
7714 + if (err < 0) {
7715 + dev_err(dev, "register_netdev() = %d\n", err);
7716 + return err;
7717 + }
7718 +
7719 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
7720 + /* create debugfs entry for this net_device */
7721 + err = dpa_netdev_debugfs_create(net_dev);
7722 + if (err) {
7723 + unregister_netdev(net_dev);
7724 + return err;
7725 + }
7726 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
7727 +
7728 + return 0;
7729 +}
7730 +EXPORT_SYMBOL(dpa_netdev_init);
7731 +
7732 +int __cold dpa_start(struct net_device *net_dev)
7733 +{
7734 + int err, i;
7735 + struct dpa_priv_s *priv;
7736 + struct mac_device *mac_dev;
7737 +
7738 + priv = netdev_priv(net_dev);
7739 + mac_dev = priv->mac_dev;
7740 +
7741 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
7742 + if (err < 0) {
7743 + if (netif_msg_ifup(priv))
7744 + netdev_err(net_dev, "init_phy() = %d\n", err);
7745 + return err;
7746 + }
7747 +
7748 + for_each_port_device(i, mac_dev->port_dev) {
7749 + err = fm_port_enable(mac_dev->port_dev[i]);
7750 + if (err)
7751 + goto mac_start_failed;
7752 + }
7753 +
7754 + err = priv->mac_dev->start(mac_dev);
7755 + if (err < 0) {
7756 + if (netif_msg_ifup(priv))
7757 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
7758 + goto mac_start_failed;
7759 + }
7760 +
7761 + netif_tx_start_all_queues(net_dev);
7762 +
7763 + return 0;
7764 +
7765 +mac_start_failed:
7766 + for_each_port_device(i, mac_dev->port_dev)
7767 + fm_port_disable(mac_dev->port_dev[i]);
7768 +
7769 + return err;
7770 +}
7771 +EXPORT_SYMBOL(dpa_start);
7772 +
7773 +int __cold dpa_stop(struct net_device *net_dev)
7774 +{
7775 + int _errno, i, err;
7776 + struct dpa_priv_s *priv;
7777 + struct mac_device *mac_dev;
7778 +
7779 + priv = netdev_priv(net_dev);
7780 + mac_dev = priv->mac_dev;
7781 +
7782 + netif_tx_stop_all_queues(net_dev);
7783 + /* Allow the Fman (Tx) port to process in-flight frames before we
7784 + * try switching it off.
7785 + */
7786 + usleep_range(5000, 10000);
7787 +
7788 + _errno = mac_dev->stop(mac_dev);
7789 + if (unlikely(_errno < 0))
7790 + if (netif_msg_ifdown(priv))
7791 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
7792 + _errno);
7793 +
7794 + for_each_port_device(i, mac_dev->port_dev) {
7795 + err = fm_port_disable(mac_dev->port_dev[i]);
7796 + _errno = err ? err : _errno;
7797 + }
7798 +
7799 + if (mac_dev->phy_dev)
7800 + phy_disconnect(mac_dev->phy_dev);
7801 + mac_dev->phy_dev = NULL;
7802 +
7803 + return _errno;
7804 +}
7805 +EXPORT_SYMBOL(dpa_stop);
7806 +
7807 +void __cold dpa_timeout(struct net_device *net_dev)
7808 +{
7809 + const struct dpa_priv_s *priv;
7810 + struct dpa_percpu_priv_s *percpu_priv;
7811 +
7812 + priv = netdev_priv(net_dev);
7813 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
7814 +
7815 + if (netif_msg_timer(priv))
7816 + netdev_crit(net_dev, "Transmit timeout!\n");
7817 +
7818 + percpu_priv->stats.tx_errors++;
7819 +}
7820 +EXPORT_SYMBOL(dpa_timeout);
7821 +
7822 +/* net_device */
7823 +
7824 +/**
7825 + * @param net_dev the device for which statistics are calculated
7826 + * @param stats the function fills this structure with the device's statistics
7827 + * @return the address of the structure containing the statistics
7828 + *
7829 + * Calculates the statistics for the given device by adding the statistics
7830 + * collected by each CPU.
7831 + */
7832 +void __cold
7833 +dpa_get_stats64(struct net_device *net_dev,
7834 + struct rtnl_link_stats64 *stats)
7835 +{
7836 + struct dpa_priv_s *priv = netdev_priv(net_dev);
7837 + u64 *cpustats;
7838 + u64 *netstats = (u64 *)stats;
7839 + int i, j;
7840 + struct dpa_percpu_priv_s *percpu_priv;
7841 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
7842 +
7843 + for_each_possible_cpu(i) {
7844 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
7845 +
7846 + cpustats = (u64 *)&percpu_priv->stats;
7847 +
7848 + for (j = 0; j < numstats; j++)
7849 + netstats[j] += cpustats[j];
7850 + }
7851 +}
7852 +EXPORT_SYMBOL(dpa_get_stats64);
7853 +
7854 +/* .ndo_init callback */
7855 +int dpa_ndo_init(struct net_device *net_dev)
7856 +{
7857 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
7858 + * we choose conservatively and let the user explicitly set a higher
7859 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
7860 + * in the same LAN.
7861 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
7862 + * start with the maximum allowed.
7863 + */
7864 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
7865 +
7866 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
7867 + net_dev->mtu = init_mtu;
7868 +
7869 + return 0;
7870 +}
7871 +EXPORT_SYMBOL(dpa_ndo_init);
7872 +
7873 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
7874 +{
7875 + /* Not much to do here for now */
7876 + dev->features = features;
7877 + return 0;
7878 +}
7879 +EXPORT_SYMBOL(dpa_set_features);
7880 +
7881 +netdev_features_t dpa_fix_features(struct net_device *dev,
7882 + netdev_features_t features)
7883 +{
7884 + netdev_features_t unsupported_features = 0;
7885 +
7886 + /* In theory we should never be requested to enable features that
7887 + * we didn't set in netdev->features and netdev->hw_features at probe
7888 + * time, but double check just to be on the safe side.
7889 + * We don't support enabling Rx csum through ethtool yet
7890 + */
7891 + unsupported_features |= NETIF_F_RXCSUM;
7892 +
7893 + features &= ~unsupported_features;
7894 +
7895 + return features;
7896 +}
7897 +EXPORT_SYMBOL(dpa_fix_features);
7898 +
7899 +#ifdef CONFIG_FSL_DPAA_TS
7900 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
7901 + const void *data)
7902 +{
7903 + u64 *ts, ns;
7904 +
7905 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
7906 + data);
7907 +
7908 + if (!ts || *ts == 0)
7909 + return 0;
7910 +
7911 + be64_to_cpus(ts);
7912 +
7913 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
7914 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
7915 +
7916 + return ns;
7917 +}
7918 +
7919 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
7920 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
7921 +{
7922 + u64 ns;
7923 +
7924 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
7925 +
7926 + if (ns == 0)
7927 + return -EINVAL;
7928 +
7929 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
7930 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
7931 +
7932 + return 0;
7933 +}
7934 +
7935 +static void dpa_ts_tx_enable(struct net_device *dev)
7936 +{
7937 + struct dpa_priv_s *priv = netdev_priv(dev);
7938 + struct mac_device *mac_dev = priv->mac_dev;
7939 +
7940 + if (mac_dev->fm_rtc_enable)
7941 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
7942 + if (mac_dev->ptp_enable)
7943 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
7944 +
7945 + priv->ts_tx_en = true;
7946 +}
7947 +
7948 +static void dpa_ts_tx_disable(struct net_device *dev)
7949 +{
7950 + struct dpa_priv_s *priv = netdev_priv(dev);
7951 +
7952 +#if 0
7953 +/* the RTC might be needed by the Rx Ts, cannot disable here
7954 + * no separate ptp_disable API for Rx/Tx, cannot disable here
7955 + */
7956 + struct mac_device *mac_dev = priv->mac_dev;
7957 +
7958 + if (mac_dev->fm_rtc_disable)
7959 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
7960 +
7961 + if (mac_dev->ptp_disable)
7962 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
7963 +#endif
7964 +
7965 + priv->ts_tx_en = false;
7966 +}
7967 +
7968 +static void dpa_ts_rx_enable(struct net_device *dev)
7969 +{
7970 + struct dpa_priv_s *priv = netdev_priv(dev);
7971 + struct mac_device *mac_dev = priv->mac_dev;
7972 +
7973 + if (mac_dev->fm_rtc_enable)
7974 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
7975 + if (mac_dev->ptp_enable)
7976 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
7977 +
7978 + priv->ts_rx_en = true;
7979 +}
7980 +
7981 +static void dpa_ts_rx_disable(struct net_device *dev)
7982 +{
7983 + struct dpa_priv_s *priv = netdev_priv(dev);
7984 +
7985 +#if 0
7986 +/* the RTC might be needed by the Tx Ts, cannot disable here
7987 + * no separate ptp_disable API for Rx/Tx, cannot disable here
7988 + */
7989 + struct mac_device *mac_dev = priv->mac_dev;
7990 +
7991 + if (mac_dev->fm_rtc_disable)
7992 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
7993 +
7994 + if (mac_dev->ptp_disable)
7995 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
7996 +#endif
7997 +
7998 + priv->ts_rx_en = false;
7999 +}
8000 +
8001 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
8002 +{
8003 + struct hwtstamp_config config;
8004 +
8005 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
8006 + return -EFAULT;
8007 +
8008 + switch (config.tx_type) {
8009 + case HWTSTAMP_TX_OFF:
8010 + dpa_ts_tx_disable(dev);
8011 + break;
8012 + case HWTSTAMP_TX_ON:
8013 + dpa_ts_tx_enable(dev);
8014 + break;
8015 + default:
8016 + return -ERANGE;
8017 + }
8018 +
8019 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
8020 + dpa_ts_rx_disable(dev);
8021 + else {
8022 + dpa_ts_rx_enable(dev);
8023 + /* TS is set for all frame types, not only those requested */
8024 + config.rx_filter = HWTSTAMP_FILTER_ALL;
8025 + }
8026 +
8027 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
8028 + -EFAULT : 0;
8029 +}
8030 +#endif /* CONFIG_FSL_DPAA_TS */
8031 +
8032 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
8033 +{
8034 +#ifdef CONFIG_FSL_DPAA_1588
8035 + struct dpa_priv_s *priv = netdev_priv(dev);
8036 +#endif
8037 + int ret = -EINVAL;
8038 +
8039 + if (!netif_running(dev))
8040 + return -EINVAL;
8041 +
8042 + if (cmd == SIOCGMIIREG) {
8043 + if (!dev->phydev)
8044 + ret = -EINVAL;
8045 + else
8046 + ret = phy_mii_ioctl(dev->phydev, rq, cmd);
8047 + }
8048 +
8049 +#ifdef CONFIG_FSL_DPAA_TS
8050 + if (cmd == SIOCSHWTSTAMP)
8051 + return dpa_ts_ioctl(dev, rq, cmd);
8052 +#endif /* CONFIG_FSL_DPAA_TS */
8053 +
8054 +#ifdef CONFIG_FSL_DPAA_1588
8055 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
8056 + if (priv->tsu && priv->tsu->valid)
8057 + ret = dpa_ioctl_1588(dev, rq, cmd);
8058 + else
8059 + ret = -ENODEV;
8060 + }
8061 +#endif
8062 +
8063 + return ret;
8064 +}
8065 +EXPORT_SYMBOL(dpa_ioctl);
8066 +
8067 +int __cold dpa_remove(struct platform_device *of_dev)
8068 +{
8069 + int err;
8070 + struct device *dev;
8071 + struct net_device *net_dev;
8072 + struct dpa_priv_s *priv;
8073 +
8074 + dev = &of_dev->dev;
8075 + net_dev = dev_get_drvdata(dev);
8076 +
8077 + priv = netdev_priv(net_dev);
8078 +
8079 + dpaa_eth_sysfs_remove(dev);
8080 +
8081 + dev_set_drvdata(dev, NULL);
8082 + unregister_netdev(net_dev);
8083 +
8084 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
8085 +
8086 + qman_delete_cgr_safe(&priv->ingress_cgr);
8087 + qman_release_cgrid(priv->ingress_cgr.cgrid);
8088 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
8089 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
8090 +
8091 + dpa_private_napi_del(net_dev);
8092 +
8093 + dpa_bp_free(priv);
8094 +
8095 + if (priv->buf_layout)
8096 + devm_kfree(dev, priv->buf_layout);
8097 +
8098 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
8099 + /* remove debugfs entry for this net_device */
8100 + dpa_netdev_debugfs_remove(net_dev);
8101 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
8102 +
8103 +#ifdef CONFIG_FSL_DPAA_1588
8104 + if (priv->tsu && priv->tsu->valid)
8105 + dpa_ptp_cleanup(priv);
8106 +#endif
8107 +
8108 + free_netdev(net_dev);
8109 +
8110 + return err;
8111 +}
8112 +EXPORT_SYMBOL(dpa_remove);
8113 +
8114 +struct mac_device * __cold __must_check
8115 +__attribute__((nonnull))
8116 +dpa_mac_probe(struct platform_device *_of_dev)
8117 +{
8118 + struct device *dpa_dev, *dev;
8119 + struct device_node *mac_node;
8120 + struct platform_device *of_dev;
8121 + struct mac_device *mac_dev;
8122 +#ifdef CONFIG_FSL_DPAA_1588
8123 + int lenp;
8124 + const phandle *phandle_prop;
8125 + struct net_device *net_dev = NULL;
8126 + struct dpa_priv_s *priv = NULL;
8127 + struct device_node *timer_node;
8128 +#endif
8129 + dpa_dev = &_of_dev->dev;
8130 +
8131 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
8132 + if (unlikely(mac_node == NULL)) {
8133 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
8134 + return ERR_PTR(-EFAULT);
8135 + }
8136 +
8137 + of_dev = of_find_device_by_node(mac_node);
8138 + if (unlikely(of_dev == NULL)) {
8139 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
8140 + mac_node->full_name);
8141 + of_node_put(mac_node);
8142 + return ERR_PTR(-EINVAL);
8143 + }
8144 + of_node_put(mac_node);
8145 +
8146 + dev = &of_dev->dev;
8147 +
8148 + mac_dev = dev_get_drvdata(dev);
8149 + if (unlikely(mac_dev == NULL)) {
8150 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
8151 + dev_name(dev));
8152 + return ERR_PTR(-EINVAL);
8153 + }
8154 +
8155 +#ifdef CONFIG_FSL_DPAA_1588
8156 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
8157 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
8158 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
8159 + (mac_dev->speed == SPEED_1000)))) {
8160 + timer_node = of_find_node_by_phandle(*phandle_prop);
8161 + if (timer_node)
8162 + net_dev = dev_get_drvdata(dpa_dev);
8163 + if (timer_node && net_dev) {
8164 + priv = netdev_priv(net_dev);
8165 + if (!dpa_ptp_init(priv))
8166 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
8167 + mac_node->full_name);
8168 + }
8169 + }
8170 +#endif
8171 +
8172 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
8173 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
8174 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
8175 + (mac_dev->speed == SPEED_1000))) {
8176 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
8177 + if (ptp_priv.node) {
8178 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
8179 + if (unlikely(ptp_priv.of_dev == NULL)) {
8180 + dev_err(dpa_dev,
8181 + "Cannot find device represented by timer_node\n");
8182 + of_node_put(ptp_priv.node);
8183 + return ERR_PTR(-EINVAL);
8184 + }
8185 + ptp_priv.mac_dev = mac_dev;
8186 + }
8187 + }
8188 +#endif
8189 + return mac_dev;
8190 +}
8191 +EXPORT_SYMBOL(dpa_mac_probe);
8192 +
8193 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
8194 +{
8195 + const struct dpa_priv_s *priv;
8196 + int _errno;
8197 + struct mac_device *mac_dev;
8198 +
8199 + priv = netdev_priv(net_dev);
8200 +
8201 + _errno = eth_mac_addr(net_dev, addr);
8202 + if (_errno < 0) {
8203 + if (netif_msg_drv(priv))
8204 + netdev_err(net_dev,
8205 + "eth_mac_addr() = %d\n",
8206 + _errno);
8207 + return _errno;
8208 + }
8209 +
8210 + mac_dev = priv->mac_dev;
8211 +
8212 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8213 + net_dev->dev_addr);
8214 + if (_errno < 0) {
8215 + if (netif_msg_drv(priv))
8216 + netdev_err(net_dev,
8217 + "mac_dev->change_addr() = %d\n",
8218 + _errno);
8219 + return _errno;
8220 + }
8221 +
8222 + return 0;
8223 +}
8224 +EXPORT_SYMBOL(dpa_set_mac_address);
8225 +
8226 +void dpa_set_rx_mode(struct net_device *net_dev)
8227 +{
8228 + int _errno;
8229 + const struct dpa_priv_s *priv;
8230 +
8231 + priv = netdev_priv(net_dev);
8232 +
8233 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
8234 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
8235 + _errno = priv->mac_dev->set_promisc(
8236 + priv->mac_dev->get_mac_handle(priv->mac_dev),
8237 + priv->mac_dev->promisc);
8238 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
8239 + netdev_err(net_dev,
8240 + "mac_dev->set_promisc() = %d\n",
8241 + _errno);
8242 + }
8243 +
8244 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
8245 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
8246 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
8247 +}
8248 +EXPORT_SYMBOL(dpa_set_rx_mode);
8249 +
8250 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8251 + struct dpa_buffer_layout_s *layout)
8252 +{
8253 + struct fm_port_params params;
8254 +
8255 + /* Rx */
8256 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
8257 + layout[RX].parse_results = true;
8258 + layout[RX].hash_results = true;
8259 +#ifdef CONFIG_FSL_DPAA_TS
8260 + layout[RX].time_stamp = true;
8261 +#endif
8262 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
8263 + layout[RX].manip_extra_space = params.manip_extra_space;
8264 + /* a value of zero for data alignment means "don't care", so align to
8265 + * a non-zero value to prevent FMD from using its own default
8266 + */
8267 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
8268 +
8269 + /* Tx */
8270 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
8271 + layout[TX].parse_results = true;
8272 + layout[TX].hash_results = true;
8273 +#ifdef CONFIG_FSL_DPAA_TS
8274 + layout[TX].time_stamp = true;
8275 +#endif
8276 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
8277 + layout[TX].manip_extra_space = params.manip_extra_space;
8278 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
8279 +}
8280 +EXPORT_SYMBOL(dpa_set_buffers_layout);
8281 +
8282 +int __attribute__((nonnull))
8283 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev)
8284 +{
8285 + int err;
8286 + struct bman_pool_params bp_params;
8287 +
8288 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
8289 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
8290 + return -EINVAL;
8291 + }
8292 +
8293 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
8294 +#ifdef CONFIG_FMAN_PFC
8295 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
8296 + bp_params.thresholds[0] = bp_params.thresholds[2] =
8297 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
8298 + bp_params.thresholds[1] = bp_params.thresholds[3] =
8299 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
8300 +#endif
8301 +
8302 + /* If the pool is already specified, we only create one per bpid */
8303 + if (dpa_bpid2pool_use(dpa_bp->bpid))
8304 + return 0;
8305 +
8306 + if (dpa_bp->bpid == 0)
8307 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
8308 + else
8309 + bp_params.bpid = dpa_bp->bpid;
8310 +
8311 + dpa_bp->pool = bman_new_pool(&bp_params);
8312 + if (unlikely(dpa_bp->pool == NULL)) {
8313 + pr_err("bman_new_pool() failed\n");
8314 + return -ENODEV;
8315 + }
8316 +
8317 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
8318 +
8319 + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
8320 + if (err) {
8321 + pr_err("dma_coerce_mask_and_coherent() failed\n");
8322 + goto bman_free_pool;
8323 + }
8324 +
8325 + dpa_bp->dev = dev;
8326 +
8327 + if (dpa_bp->seed_cb) {
8328 + err = dpa_bp->seed_cb(dpa_bp);
8329 + if (err)
8330 + goto bman_free_pool;
8331 + }
8332 +
8333 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
8334 +
8335 + return 0;
8336 +
8337 +bman_free_pool:
8338 + bman_free_pool(dpa_bp->pool);
8339 +
8340 + return err;
8341 +}
8342 +EXPORT_SYMBOL(dpa_bp_alloc);
8343 +
8344 +void dpa_bp_drain(struct dpa_bp *bp)
8345 +{
8346 + int ret, num = 8;
8347 +
8348 + do {
8349 + struct bm_buffer bmb[8];
8350 + int i;
8351 +
8352 + ret = bman_acquire(bp->pool, bmb, num, 0);
8353 + if (ret < 0) {
8354 + if (num == 8) {
8355 + /* we have less than 8 buffers left;
8356 + * drain them one by one
8357 + */
8358 + num = 1;
8359 + ret = 1;
8360 + continue;
8361 + } else {
8362 + /* Pool is fully drained */
8363 + break;
8364 + }
8365 + }
8366 +
8367 + for (i = 0; i < num; i++) {
8368 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
8369 +
8370 + dma_unmap_single(bp->dev, addr, bp->size,
8371 + DMA_BIDIRECTIONAL);
8372 +
8373 + bp->free_buf_cb(phys_to_virt(addr));
8374 + }
8375 + } while (ret > 0);
8376 +}
8377 +EXPORT_SYMBOL(dpa_bp_drain);
8378 +
8379 +static void __cold __attribute__((nonnull))
8380 +_dpa_bp_free(struct dpa_bp *dpa_bp)
8381 +{
8382 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
8383 +
8384 + /* the mapping between bpid and dpa_bp is done very late in the
8385 + * allocation procedure; if something failed before the mapping, the bp
8386 + * was not configured, therefore we don't need the below instructions
8387 + */
8388 + if (!bp)
8389 + return;
8390 +
8391 + if (!atomic_dec_and_test(&bp->refs))
8392 + return;
8393 +
8394 + if (bp->free_buf_cb)
8395 + dpa_bp_drain(bp);
8396 +
8397 + dpa_bp_array[bp->bpid] = NULL;
8398 + bman_free_pool(bp->pool);
8399 +}
8400 +
8401 +void __cold __attribute__((nonnull))
8402 +dpa_bp_free(struct dpa_priv_s *priv)
8403 +{
8404 + int i;
8405 +
8406 + if (priv->dpa_bp)
8407 + for (i = 0; i < priv->bp_count; i++)
8408 + _dpa_bp_free(&priv->dpa_bp[i]);
8409 +}
8410 +EXPORT_SYMBOL(dpa_bp_free);
8411 +
8412 +struct dpa_bp *dpa_bpid2pool(int bpid)
8413 +{
8414 + return dpa_bp_array[bpid];
8415 +}
8416 +EXPORT_SYMBOL(dpa_bpid2pool);
8417 +
8418 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
8419 +{
8420 + dpa_bp_array[bpid] = dpa_bp;
8421 + atomic_set(&dpa_bp->refs, 1);
8422 +}
8423 +
8424 +bool dpa_bpid2pool_use(int bpid)
8425 +{
8426 + if (dpa_bpid2pool(bpid)) {
8427 + atomic_inc(&dpa_bp_array[bpid]->refs);
8428 + return true;
8429 + }
8430 +
8431 + return false;
8432 +}
8433 +
8434 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8435 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8436 + void *accel_priv, select_queue_fallback_t fallback)
8437 +{
8438 + return dpa_get_queue_mapping(skb);
8439 +}
8440 +EXPORT_SYMBOL(dpa_select_queue);
8441 +#endif
8442 +
8443 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8444 + u32 fq_start,
8445 + u32 fq_count,
8446 + struct list_head *list,
8447 + enum dpa_fq_type fq_type)
8448 +{
8449 + int i;
8450 + struct dpa_fq *dpa_fq;
8451 +
8452 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
8453 + if (dpa_fq == NULL)
8454 + return NULL;
8455 +
8456 + for (i = 0; i < fq_count; i++) {
8457 + dpa_fq[i].fq_type = fq_type;
8458 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
8459 + dpa_fq[i].fqid = fq_start ?
8460 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
8461 + else
8462 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
8463 +
8464 + list_add_tail(&dpa_fq[i].list, list);
8465 + }
8466 +
8467 +#ifdef CONFIG_FMAN_PFC
8468 + if (fq_type == FQ_TYPE_TX)
8469 + for (i = 0; i < fq_count; i++)
8470 + dpa_fq[i].wq = i / dpa_num_cpus;
8471 + else
8472 +#endif
8473 + for (i = 0; i < fq_count; i++)
8474 + _dpa_assign_wq(dpa_fq + i);
8475 +
8476 + return dpa_fq;
8477 +}
8478 +EXPORT_SYMBOL(dpa_fq_alloc);
8479 +
8480 +/* Probing of FQs for MACful ports */
8481 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8482 + struct fm_port_fqs *port_fqs,
8483 + bool alloc_tx_conf_fqs,
8484 + enum port_type ptype)
8485 +{
8486 + struct fqid_cell *fqids = NULL;
8487 + const void *fqids_off = NULL;
8488 + struct dpa_fq *dpa_fq = NULL;
8489 + struct device_node *np = dev->of_node;
8490 + int num_ranges;
8491 + int i, lenp;
8492 +
8493 + if (ptype == TX && alloc_tx_conf_fqs) {
8494 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
8495 + tx_confirm_fqids->count, list,
8496 + FQ_TYPE_TX_CONF_MQ))
8497 + goto fq_alloc_failed;
8498 + }
8499 +
8500 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
8501 + if (fqids_off == NULL) {
8502 + /* No dts definition, so use the defaults. */
8503 + fqids = default_fqids[ptype];
8504 + num_ranges = 3;
8505 + } else {
8506 + num_ranges = lenp / sizeof(*fqids);
8507 +
8508 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
8509 + GFP_KERNEL);
8510 + if (fqids == NULL)
8511 + goto fqids_alloc_failed;
8512 +
8513 + /* convert to CPU endianess */
8514 + for (i = 0; i < num_ranges; i++) {
8515 + fqids[i].start = be32_to_cpup(fqids_off +
8516 + i * sizeof(*fqids));
8517 + fqids[i].count = be32_to_cpup(fqids_off +
8518 + i * sizeof(*fqids) + sizeof(__be32));
8519 + }
8520 + }
8521 +
8522 + for (i = 0; i < num_ranges; i++) {
8523 + switch (i) {
8524 + case 0:
8525 + /* The first queue is the error queue */
8526 + if (fqids[i].count != 1)
8527 + goto invalid_error_queue;
8528 +
8529 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
8530 + fqids[i].count, list,
8531 + ptype == RX ?
8532 + FQ_TYPE_RX_ERROR :
8533 + FQ_TYPE_TX_ERROR);
8534 + if (dpa_fq == NULL)
8535 + goto fq_alloc_failed;
8536 +
8537 + if (ptype == RX)
8538 + port_fqs->rx_errq = &dpa_fq[0];
8539 + else
8540 + port_fqs->tx_errq = &dpa_fq[0];
8541 + break;
8542 + case 1:
8543 + /* the second queue is the default queue */
8544 + if (fqids[i].count != 1)
8545 + goto invalid_default_queue;
8546 +
8547 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
8548 + fqids[i].count, list,
8549 + ptype == RX ?
8550 + FQ_TYPE_RX_DEFAULT :
8551 + FQ_TYPE_TX_CONFIRM);
8552 + if (dpa_fq == NULL)
8553 + goto fq_alloc_failed;
8554 +
8555 + if (ptype == RX)
8556 + port_fqs->rx_defq = &dpa_fq[0];
8557 + else
8558 + port_fqs->tx_defq = &dpa_fq[0];
8559 + break;
8560 + default:
8561 + /* all subsequent queues are either RX* PCD or Tx */
8562 + if (ptype == RX) {
8563 + if (!dpa_fq_alloc(dev, fqids[i].start,
8564 + fqids[i].count, list,
8565 + FQ_TYPE_RX_PCD) ||
8566 + !dpa_fq_alloc(dev, fqids[i].start,
8567 + fqids[i].count, list,
8568 + FQ_TYPE_RX_PCD_HI_PRIO))
8569 + goto fq_alloc_failed;
8570 + } else {
8571 + if (!dpa_fq_alloc(dev, fqids[i].start,
8572 + fqids[i].count, list,
8573 + FQ_TYPE_TX))
8574 + goto fq_alloc_failed;
8575 + }
8576 + break;
8577 + }
8578 + }
8579 +
8580 + return 0;
8581 +
8582 +fq_alloc_failed:
8583 +fqids_alloc_failed:
8584 + dev_err(dev, "Cannot allocate memory for frame queues\n");
8585 + return -ENOMEM;
8586 +
8587 +invalid_default_queue:
8588 +invalid_error_queue:
8589 + dev_err(dev, "Too many default or error queues\n");
8590 + return -EINVAL;
8591 +}
8592 +EXPORT_SYMBOL(dpa_fq_probe_mac);
8593 +
8594 +static u32 rx_pool_channel;
8595 +static DEFINE_SPINLOCK(rx_pool_channel_init);
8596 +
8597 +int dpa_get_channel(void)
8598 +{
8599 + spin_lock(&rx_pool_channel_init);
8600 + if (!rx_pool_channel) {
8601 + u32 pool;
8602 + int ret = qman_alloc_pool(&pool);
8603 + if (!ret)
8604 + rx_pool_channel = pool;
8605 + }
8606 + spin_unlock(&rx_pool_channel_init);
8607 + if (!rx_pool_channel)
8608 + return -ENOMEM;
8609 + return rx_pool_channel;
8610 +}
8611 +EXPORT_SYMBOL(dpa_get_channel);
8612 +
8613 +void dpa_release_channel(void)
8614 +{
8615 + qman_release_pool(rx_pool_channel);
8616 +}
8617 +EXPORT_SYMBOL(dpa_release_channel);
8618 +
8619 +void dpaa_eth_add_channel(u16 channel)
8620 +{
8621 + const cpumask_t *cpus = qman_affine_cpus();
8622 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
8623 + int cpu;
8624 + struct qman_portal *portal;
8625 +
8626 + for_each_cpu(cpu, cpus) {
8627 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
8628 + qman_p_static_dequeue_add(portal, pool);
8629 + }
8630 +}
8631 +EXPORT_SYMBOL(dpaa_eth_add_channel);
8632 +
8633 +/**
8634 + * Congestion group state change notification callback.
8635 + * Stops the device's egress queues while they are congested and
8636 + * wakes them upon exiting congested state.
8637 + * Also updates some CGR-related stats.
8638 + */
8639 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
8640 +
8641 + int congested)
8642 +{
8643 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
8644 + struct dpa_priv_s, cgr_data.cgr);
8645 +
8646 + if (congested) {
8647 + priv->cgr_data.congestion_start_jiffies = jiffies;
8648 + netif_tx_stop_all_queues(priv->net_dev);
8649 + priv->cgr_data.cgr_congested_count++;
8650 + } else {
8651 + priv->cgr_data.congested_jiffies +=
8652 + (jiffies - priv->cgr_data.congestion_start_jiffies);
8653 + netif_tx_wake_all_queues(priv->net_dev);
8654 + }
8655 +}
8656 +
8657 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
8658 +{
8659 + struct qm_mcc_initcgr initcgr;
8660 + u32 cs_th;
8661 + int err;
8662 +
8663 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
8664 + if (err < 0) {
8665 + pr_err("Error %d allocating CGR ID\n", err);
8666 + goto out_error;
8667 + }
8668 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
8669 +
8670 + /* Enable Congestion State Change Notifications and CS taildrop */
8671 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
8672 + initcgr.cgr.cscn_en = QM_CGR_EN;
8673 +
8674 + /* Set different thresholds based on the MAC speed.
8675 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
8676 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
8677 + * In such cases, we ought to reconfigure the threshold, too.
8678 + */
8679 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
8680 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
8681 + else
8682 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
8683 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
8684 +
8685 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
8686 + initcgr.cgr.cstd_en = QM_CGR_EN;
8687 +
8688 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
8689 + &initcgr);
8690 + if (err < 0) {
8691 + pr_err("Error %d creating CGR with ID %d\n", err,
8692 + priv->cgr_data.cgr.cgrid);
8693 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
8694 + goto out_error;
8695 + }
8696 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
8697 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
8698 + priv->cgr_data.cgr.chan);
8699 +
8700 +out_error:
8701 + return err;
8702 +}
8703 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
8704 +
8705 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
8706 + struct dpa_fq *fq,
8707 + const struct qman_fq *template)
8708 +{
8709 + fq->fq_base = *template;
8710 + fq->net_dev = priv->net_dev;
8711 +
8712 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
8713 + fq->channel = priv->channel;
8714 +}
8715 +
8716 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
8717 + struct dpa_fq *fq,
8718 + struct fm_port *port,
8719 + const struct qman_fq *template)
8720 +{
8721 + fq->fq_base = *template;
8722 + fq->net_dev = priv->net_dev;
8723 +
8724 + if (port) {
8725 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
8726 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
8727 + } else {
8728 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
8729 + }
8730 +}
8731 +
8732 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8733 + struct fm_port *tx_port)
8734 +{
8735 + struct dpa_fq *fq;
8736 + uint16_t portals[NR_CPUS];
8737 + int cpu, portal_cnt = 0, num_portals = 0;
8738 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
8739 + const cpumask_t *affine_cpus = qman_affine_cpus();
8740 + int egress_cnt = 0, conf_cnt = 0;
8741 +
8742 + /* Prepare for PCD FQs init */
8743 + for_each_cpu(cpu, affine_cpus)
8744 + portals[num_portals++] = qman_affine_channel(cpu);
8745 + if (num_portals == 0)
8746 + dev_err(priv->net_dev->dev.parent,
8747 + "No Qman software (affine) channels found");
8748 +
8749 + pcd_fqid = (priv->mac_dev) ?
8750 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
8751 + pcd_fqid_hi_prio = (priv->mac_dev) ?
8752 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
8753 +
8754 + /* Initialize each FQ in the list */
8755 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
8756 + switch (fq->fq_type) {
8757 + case FQ_TYPE_RX_DEFAULT:
8758 + BUG_ON(!priv->mac_dev);
8759 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
8760 + break;
8761 + case FQ_TYPE_RX_ERROR:
8762 + BUG_ON(!priv->mac_dev);
8763 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
8764 + break;
8765 + case FQ_TYPE_RX_PCD:
8766 + /* For MACless we can't have dynamic Rx queues */
8767 + BUG_ON(!priv->mac_dev && !fq->fqid);
8768 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
8769 + if (!fq->fqid)
8770 + fq->fqid = pcd_fqid++;
8771 + fq->channel = portals[portal_cnt];
8772 + portal_cnt = (portal_cnt + 1) % num_portals;
8773 + break;
8774 + case FQ_TYPE_RX_PCD_HI_PRIO:
8775 + /* For MACless we can't have dynamic Hi Pri Rx queues */
8776 + BUG_ON(!priv->mac_dev && !fq->fqid);
8777 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
8778 + if (!fq->fqid)
8779 + fq->fqid = pcd_fqid_hi_prio++;
8780 + fq->channel = portals[portal_cnt];
8781 + portal_cnt = (portal_cnt + 1) % num_portals;
8782 + break;
8783 + case FQ_TYPE_TX:
8784 + dpa_setup_egress(priv, fq, tx_port,
8785 + &fq_cbs->egress_ern);
8786 + /* If we have more Tx queues than the number of cores,
8787 + * just ignore the extra ones.
8788 + */
8789 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
8790 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
8791 + break;
8792 + case FQ_TYPE_TX_CONFIRM:
8793 + BUG_ON(!priv->mac_dev);
8794 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
8795 + break;
8796 + case FQ_TYPE_TX_CONF_MQ:
8797 + BUG_ON(!priv->mac_dev);
8798 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
8799 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
8800 + break;
8801 + case FQ_TYPE_TX_ERROR:
8802 + BUG_ON(!priv->mac_dev);
8803 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
8804 + break;
8805 + default:
8806 + dev_warn(priv->net_dev->dev.parent,
8807 + "Unknown FQ type detected!\n");
8808 + break;
8809 + }
8810 + }
8811 +
8812 + /* The number of Tx queues may be smaller than the number of cores, if
8813 + * the Tx queue range is specified in the device tree instead of being
8814 + * dynamically allocated.
8815 + * Make sure all CPUs receive a corresponding Tx queue.
8816 + */
8817 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
8818 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
8819 + if (fq->fq_type != FQ_TYPE_TX)
8820 + continue;
8821 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
8822 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
8823 + break;
8824 + }
8825 + }
8826 +}
8827 +EXPORT_SYMBOL(dpa_fq_setup);
8828 +
8829 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
8830 +{
8831 + int _errno;
8832 + const struct dpa_priv_s *priv;
8833 + struct device *dev;
8834 + struct qman_fq *fq;
8835 + struct qm_mcc_initfq initfq;
8836 + struct qman_fq *confq;
8837 + int queue_id;
8838 +
8839 + priv = netdev_priv(dpa_fq->net_dev);
8840 + dev = dpa_fq->net_dev->dev.parent;
8841 +
8842 + if (dpa_fq->fqid == 0)
8843 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
8844 +
8845 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
8846 +
8847 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
8848 + if (_errno) {
8849 + dev_err(dev, "qman_create_fq() failed\n");
8850 + return _errno;
8851 + }
8852 + fq = &dpa_fq->fq_base;
8853 +
8854 + if (dpa_fq->init) {
8855 + memset(&initfq, 0, sizeof(initfq));
8856 +
8857 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
8858 + /* FIXME: why would we want to keep an empty FQ in cache? */
8859 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
8860 +
8861 + /* Try to reduce the number of portal interrupts for
8862 + * Tx Confirmation FQs.
8863 + */
8864 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
8865 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
8866 +
8867 + /* FQ placement */
8868 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
8869 +
8870 + initfq.fqd.dest.channel = dpa_fq->channel;
8871 + initfq.fqd.dest.wq = dpa_fq->wq;
8872 +
8873 + /* Put all egress queues in a congestion group of their own.
8874 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
8875 + * rather than Tx - but they nonetheless account for the
8876 + * memory footprint on behalf of egress traffic. We therefore
8877 + * place them in the netdev's CGR, along with the Tx FQs.
8878 + */
8879 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
8880 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
8881 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
8882 + initfq.we_mask |= QM_INITFQ_WE_CGID;
8883 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
8884 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
8885 + /* Set a fixed overhead accounting, in an attempt to
8886 + * reduce the impact of fixed-size skb shells and the
8887 + * driver's needed headroom on system memory. This is
8888 + * especially the case when the egress traffic is
8889 + * composed of small datagrams.
8890 + * Unfortunately, QMan's OAL value is capped to an
8891 + * insufficient value, but even that is better than
8892 + * no overhead accounting at all.
8893 + */
8894 + initfq.we_mask |= QM_INITFQ_WE_OAC;
8895 + initfq.fqd.oac_init.oac = QM_OAC_CG;
8896 + initfq.fqd.oac_init.oal =
8897 + (signed char)(min(sizeof(struct sk_buff) +
8898 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
8899 + }
8900 +
8901 + if (td_enable) {
8902 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
8903 + qm_fqd_taildrop_set(&initfq.fqd.td,
8904 + DPA_FQ_TD, 1);
8905 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
8906 + }
8907 +
8908 + /* Configure the Tx confirmation queue, now that we know
8909 + * which Tx queue it pairs with.
8910 + */
8911 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
8912 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
8913 + if (queue_id >= 0) {
8914 + confq = priv->conf_fqs[queue_id];
8915 + if (confq) {
8916 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
8917 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
8918 + * A2V=1 (contextA A2 field is valid)
8919 + * A0V=1 (contextA A0 field is valid)
8920 + * B0V=1 (contextB field is valid)
8921 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
8922 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
8923 + */
8924 + initfq.fqd.context_a.hi = 0x1e000000;
8925 + initfq.fqd.context_a.lo = 0x80000000;
8926 + }
8927 + }
8928 + }
8929 +
8930 + /* Put all *private* ingress queues in our "ingress CGR". */
8931 + if (priv->use_ingress_cgr &&
8932 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
8933 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
8934 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
8935 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
8936 + initfq.we_mask |= QM_INITFQ_WE_CGID;
8937 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
8938 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
8939 + /* Set a fixed overhead accounting, just like for the
8940 + * egress CGR.
8941 + */
8942 + initfq.we_mask |= QM_INITFQ_WE_OAC;
8943 + initfq.fqd.oac_init.oac = QM_OAC_CG;
8944 + initfq.fqd.oac_init.oal =
8945 + (signed char)(min(sizeof(struct sk_buff) +
8946 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
8947 + }
8948 +
8949 + /* Initialization common to all ingress queues */
8950 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
8951 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
8952 + initfq.fqd.fq_ctrl |=
8953 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
8954 + initfq.fqd.context_a.stashing.exclusive =
8955 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
8956 + QM_STASHING_EXCL_ANNOTATION;
8957 + initfq.fqd.context_a.stashing.data_cl = 2;
8958 + initfq.fqd.context_a.stashing.annotation_cl = 1;
8959 + initfq.fqd.context_a.stashing.context_cl =
8960 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
8961 + }
8962 +
8963 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
8964 + if (_errno < 0) {
8965 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
8966 + dpa_fq->init = 0;
8967 + } else {
8968 + dev_err(dev, "qman_init_fq(%u) = %d\n",
8969 + qman_fq_fqid(fq), _errno);
8970 + qman_destroy_fq(fq, 0);
8971 + }
8972 + return _errno;
8973 + }
8974 + }
8975 +
8976 + dpa_fq->fqid = qman_fq_fqid(fq);
8977 +
8978 + return 0;
8979 +}
8980 +EXPORT_SYMBOL(dpa_fq_init);
8981 +
8982 +int __cold __attribute__((nonnull))
8983 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
8984 +{
8985 + int _errno, __errno;
8986 + struct dpa_fq *dpa_fq;
8987 + const struct dpa_priv_s *priv;
8988 +
8989 + _errno = 0;
8990 +
8991 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
8992 + priv = netdev_priv(dpa_fq->net_dev);
8993 +
8994 + if (dpa_fq->init) {
8995 + _errno = qman_retire_fq(fq, NULL);
8996 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
8997 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
8998 + qman_fq_fqid(fq), _errno);
8999 +
9000 + __errno = qman_oos_fq(fq);
9001 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
9002 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
9003 + qman_fq_fqid(fq), __errno);
9004 + if (_errno >= 0)
9005 + _errno = __errno;
9006 + }
9007 + }
9008 +
9009 + qman_destroy_fq(fq, 0);
9010 + list_del(&dpa_fq->list);
9011 +
9012 + return _errno;
9013 +}
9014 +EXPORT_SYMBOL(_dpa_fq_free);
9015 +
9016 +int __cold __attribute__((nonnull))
9017 +dpa_fq_free(struct device *dev, struct list_head *list)
9018 +{
9019 + int _errno, __errno;
9020 + struct dpa_fq *dpa_fq, *tmp;
9021 +
9022 + _errno = 0;
9023 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
9024 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
9025 + if (unlikely(__errno < 0) && _errno >= 0)
9026 + _errno = __errno;
9027 + }
9028 +
9029 + return _errno;
9030 +}
9031 +EXPORT_SYMBOL(dpa_fq_free);
9032 +
9033 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
9034 +{
9035 + int _errno, __errno;
9036 + struct dpa_fq *dpa_fq, *tmp;
9037 + static bool print_msg __read_mostly;
9038 +
9039 + _errno = 0;
9040 + print_msg = true;
9041 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
9042 + __errno = dpa_fq_init(dpa_fq, td_enable);
9043 + if (unlikely(__errno < 0) && _errno >= 0) {
9044 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
9045 + if (print_msg) {
9046 + dev_warn(dev,
9047 + "Skip RX PCD High Priority FQs initialization\n");
9048 + print_msg = false;
9049 + }
9050 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
9051 + dev_warn(dev,
9052 + "Error freeing frame queues\n");
9053 + } else {
9054 + _errno = __errno;
9055 + break;
9056 + }
9057 + }
9058 + }
9059 +
9060 + return _errno;
9061 +}
9062 +EXPORT_SYMBOL(dpa_fqs_init);
9063 +static void
9064 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
9065 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
9066 +{
9067 + struct fm_port_params tx_port_param;
9068 + bool frag_enabled = false;
9069 +
9070 + memset(&tx_port_param, 0, sizeof(tx_port_param));
9071 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
9072 + buf_layout, frag_enabled);
9073 +}
9074 +
9075 +static void
9076 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
9077 + struct dpa_fq *errq, struct dpa_fq *defq,
9078 + struct dpa_buffer_layout_s *buf_layout)
9079 +{
9080 + struct fm_port_params rx_port_param;
9081 + int i;
9082 + bool frag_enabled = false;
9083 +
9084 + memset(&rx_port_param, 0, sizeof(rx_port_param));
9085 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
9086 + rx_port_param.num_pools = (uint8_t)count;
9087 + for (i = 0; i < count; i++) {
9088 + if (i >= rx_port_param.num_pools)
9089 + break;
9090 + rx_port_param.pool_param[i].id = bp[i].bpid;
9091 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
9092 + }
9093 +
9094 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
9095 + buf_layout, frag_enabled);
9096 +}
9097 +
9098 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
9099 +/* Defined as weak, to be implemented by fman pcd tester. */
9100 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
9101 +__attribute__((weak));
9102 +
9103 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
9104 +#else
9105 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
9106 +
9107 +int dpa_free_pcd_fqids(struct device *, uint32_t);
9108 +
9109 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
9110 +
9111 +
9112 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
9113 + uint8_t alignment, uint32_t *base_fqid)
9114 +{
9115 + dev_crit(dev, "callback not implemented!\n");
9116 +
9117 + return 0;
9118 +}
9119 +
9120 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
9121 +{
9122 +
9123 + dev_crit(dev, "callback not implemented!\n");
9124 +
9125 + return 0;
9126 +}
9127 +
9128 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
9129 + struct dpa_bp *bp, size_t count,
9130 + struct fm_port_fqs *port_fqs,
9131 + struct dpa_buffer_layout_s *buf_layout,
9132 + struct device *dev)
9133 +{
9134 + struct fm_port_pcd_param rx_port_pcd_param;
9135 + struct fm_port *rxport = mac_dev->port_dev[RX];
9136 + struct fm_port *txport = mac_dev->port_dev[TX];
9137 +
9138 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
9139 + port_fqs->tx_defq, &buf_layout[TX]);
9140 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
9141 + port_fqs->rx_defq, &buf_layout[RX]);
9142 +
9143 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
9144 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
9145 + rx_port_pcd_param.dev = dev;
9146 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
9147 +}
9148 +EXPORT_SYMBOL(dpaa_eth_init_ports);
9149 +
9150 +void dpa_release_sgt(struct qm_sg_entry *sgt)
9151 +{
9152 + struct dpa_bp *dpa_bp;
9153 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
9154 + uint8_t i = 0, j;
9155 +
9156 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
9157 +
9158 + do {
9159 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
9160 + DPA_BUG_ON(!dpa_bp);
9161 +
9162 + j = 0;
9163 + do {
9164 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9165 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
9166 +
9167 + j++; i++;
9168 + } while (j < ARRAY_SIZE(bmb) &&
9169 + !qm_sg_entry_get_final(&sgt[i-1]) &&
9170 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
9171 + qm_sg_entry_get_bpid(&sgt[i]));
9172 +
9173 + while (bman_release(dpa_bp->pool, bmb, j, 0))
9174 + cpu_relax();
9175 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
9176 +}
9177 +EXPORT_SYMBOL(dpa_release_sgt);
9178 +
9179 +void __attribute__((nonnull))
9180 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
9181 +{
9182 + struct qm_sg_entry *sgt;
9183 + struct dpa_bp *dpa_bp;
9184 + struct bm_buffer bmb;
9185 + dma_addr_t addr;
9186 + void *vaddr;
9187 +
9188 + bmb.opaque = 0;
9189 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
9190 +
9191 + dpa_bp = dpa_bpid2pool(fd->bpid);
9192 + DPA_BUG_ON(!dpa_bp);
9193 +
9194 + if (fd->format == qm_fd_sg) {
9195 + vaddr = phys_to_virt(qm_fd_addr(fd));
9196 + sgt = vaddr + dpa_fd_offset(fd);
9197 +
9198 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
9199 + DMA_BIDIRECTIONAL);
9200 +
9201 + dpa_release_sgt(sgt);
9202 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
9203 + DMA_BIDIRECTIONAL);
9204 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9205 + dev_err(dpa_bp->dev, "DMA mapping failed");
9206 + return;
9207 + }
9208 + bm_buffer_set64(&bmb, addr);
9209 + }
9210 +
9211 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
9212 + cpu_relax();
9213 +}
9214 +EXPORT_SYMBOL(dpa_fd_release);
9215 +
9216 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
9217 + const struct qm_mr_entry *msg)
9218 +{
9219 + switch (msg->ern.rc & QM_MR_RC_MASK) {
9220 + case QM_MR_RC_CGR_TAILDROP:
9221 + percpu_priv->ern_cnt.cg_tdrop++;
9222 + break;
9223 + case QM_MR_RC_WRED:
9224 + percpu_priv->ern_cnt.wred++;
9225 + break;
9226 + case QM_MR_RC_ERROR:
9227 + percpu_priv->ern_cnt.err_cond++;
9228 + break;
9229 + case QM_MR_RC_ORPWINDOW_EARLY:
9230 + percpu_priv->ern_cnt.early_window++;
9231 + break;
9232 + case QM_MR_RC_ORPWINDOW_LATE:
9233 + percpu_priv->ern_cnt.late_window++;
9234 + break;
9235 + case QM_MR_RC_FQ_TAILDROP:
9236 + percpu_priv->ern_cnt.fq_tdrop++;
9237 + break;
9238 + case QM_MR_RC_ORPWINDOW_RETIRED:
9239 + percpu_priv->ern_cnt.fq_retired++;
9240 + break;
9241 + case QM_MR_RC_ORP_ZERO:
9242 + percpu_priv->ern_cnt.orp_zero++;
9243 + break;
9244 + }
9245 +}
9246 +EXPORT_SYMBOL(count_ern);
9247 +
9248 +/**
9249 + * Turn on HW checksum computation for this outgoing frame.
9250 + * If the current protocol is not something we support in this regard
9251 + * (or if the stack has already computed the SW checksum), we do nothing.
9252 + *
9253 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
9254 + * otherwise.
9255 + *
9256 + * Note that this function may modify the fd->cmd field and the skb data buffer
9257 + * (the Parse Results area).
9258 + */
9259 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
9260 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
9261 +{
9262 + fm_prs_result_t *parse_result;
9263 + struct iphdr *iph;
9264 + struct ipv6hdr *ipv6h = NULL;
9265 + u8 l4_proto;
9266 + u16 ethertype = ntohs(skb->protocol);
9267 + int retval = 0;
9268 +
9269 + if (skb->ip_summed != CHECKSUM_PARTIAL)
9270 + return 0;
9271 +
9272 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
9273 + * L4 alone from the FM configuration anyway.
9274 + */
9275 +
9276 + /* Fill in some fields of the Parse Results array, so the FMan
9277 + * can find them as if they came from the FMan Parser.
9278 + */
9279 + parse_result = (fm_prs_result_t *)parse_results;
9280 +
9281 + /* If we're dealing with VLAN, get the real Ethernet type */
9282 + if (ethertype == ETH_P_8021Q) {
9283 + /* We can't always assume the MAC header is set correctly
9284 + * by the stack, so reset to beginning of skb->data
9285 + */
9286 + skb_reset_mac_header(skb);
9287 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
9288 + }
9289 +
9290 + /* Fill in the relevant L3 parse result fields
9291 + * and read the L4 protocol type
9292 + */
9293 + switch (ethertype) {
9294 + case ETH_P_IP:
9295 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
9296 + iph = ip_hdr(skb);
9297 + DPA_BUG_ON(iph == NULL);
9298 + l4_proto = iph->protocol;
9299 + break;
9300 + case ETH_P_IPV6:
9301 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
9302 + ipv6h = ipv6_hdr(skb);
9303 + DPA_BUG_ON(ipv6h == NULL);
9304 + l4_proto = ipv6h->nexthdr;
9305 + break;
9306 + default:
9307 + /* We shouldn't even be here */
9308 + if (netif_msg_tx_err(priv) && net_ratelimit())
9309 + netdev_alert(priv->net_dev,
9310 + "Can't compute HW csum for L3 proto 0x%x\n",
9311 + ntohs(skb->protocol));
9312 + retval = -EIO;
9313 + goto return_error;
9314 + }
9315 +
9316 + /* Fill in the relevant L4 parse result fields */
9317 + switch (l4_proto) {
9318 + case IPPROTO_UDP:
9319 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
9320 + break;
9321 + case IPPROTO_TCP:
9322 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
9323 + break;
9324 + default:
9325 + /* This can as well be a BUG() */
9326 + if (netif_msg_tx_err(priv) && net_ratelimit())
9327 + netdev_alert(priv->net_dev,
9328 + "Can't compute HW csum for L4 proto 0x%x\n",
9329 + l4_proto);
9330 + retval = -EIO;
9331 + goto return_error;
9332 + }
9333 +
9334 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
9335 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
9336 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
9337 +
9338 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
9339 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
9340 +
9341 + /* On P1023 and similar platforms fd->cmd interpretation could
9342 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
9343 + * is not set so we do not need to check; in the future, if/when
9344 + * using context_a we need to check this bit
9345 + */
9346 +
9347 +return_error:
9348 + return retval;
9349 +}
9350 +EXPORT_SYMBOL(dpa_enable_tx_csum);
9351 +
9352 +#ifdef CONFIG_FSL_DPAA_CEETM
9353 +void dpa_enable_ceetm(struct net_device *dev)
9354 +{
9355 + struct dpa_priv_s *priv = netdev_priv(dev);
9356 + priv->ceetm_en = true;
9357 +}
9358 +EXPORT_SYMBOL(dpa_enable_ceetm);
9359 +
9360 +void dpa_disable_ceetm(struct net_device *dev)
9361 +{
9362 + struct dpa_priv_s *priv = netdev_priv(dev);
9363 + priv->ceetm_en = false;
9364 +}
9365 +EXPORT_SYMBOL(dpa_disable_ceetm);
9366 +#endif
9367 --- /dev/null
9368 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
9369 @@ -0,0 +1,226 @@
9370 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
9371 + *
9372 + * Redistribution and use in source and binary forms, with or without
9373 + * modification, are permitted provided that the following conditions are met:
9374 + * * Redistributions of source code must retain the above copyright
9375 + * notice, this list of conditions and the following disclaimer.
9376 + * * Redistributions in binary form must reproduce the above copyright
9377 + * notice, this list of conditions and the following disclaimer in the
9378 + * documentation and/or other materials provided with the distribution.
9379 + * * Neither the name of Freescale Semiconductor nor the
9380 + * names of its contributors may be used to endorse or promote products
9381 + * derived from this software without specific prior written permission.
9382 + *
9383 + *
9384 + * ALTERNATIVELY, this software may be distributed under the terms of the
9385 + * GNU General Public License ("GPL") as published by the Free Software
9386 + * Foundation, either version 2 of that License or (at your option) any
9387 + * later version.
9388 + *
9389 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9390 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9391 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9392 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9393 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9394 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9395 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9396 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9397 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9398 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9399 + */
9400 +
9401 +#ifndef __DPAA_ETH_COMMON_H
9402 +#define __DPAA_ETH_COMMON_H
9403 +
9404 +#include <linux/etherdevice.h> /* struct net_device */
9405 +#include <linux/fsl_bman.h> /* struct bm_buffer */
9406 +#include <linux/of_platform.h> /* struct platform_device */
9407 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
9408 +
9409 +#include "dpaa_eth.h"
9410 +#include "lnxwrp_fsl_fman.h"
9411 +
9412 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
9413 + frag_enabled) \
9414 +{ \
9415 + param.errq = errq_id; \
9416 + param.defq = defq_id; \
9417 + param.priv_data_size = buf_layout->priv_data_size; \
9418 + param.parse_results = buf_layout->parse_results; \
9419 + param.hash_results = buf_layout->hash_results; \
9420 + param.frag_enable = frag_enabled; \
9421 + param.time_stamp = buf_layout->time_stamp; \
9422 + param.manip_extra_space = buf_layout->manip_extra_space; \
9423 + param.data_align = buf_layout->data_align; \
9424 + fm_set_##type##_port_params(port, &param); \
9425 +}
9426 +
9427 +/* The SGT needs to be 256 bytes long. Even if the table has only one entry,
9428 + * the FMan will read 256 bytes from its start.
9429 + */
9430 +#define DPA_SGT_SIZE 256
9431 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
9432 +
9433 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
9434 +
9435 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
9436 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
9437 + (_errno == -EIO))
9438 +/* return codes for the dpaa-eth hooks */
9439 +enum dpaa_eth_hook_result {
9440 + /* fd/skb was retained by the hook.
9441 + *
9442 + * On the Rx path, this means the Ethernet driver will _not_
9443 + * deliver the skb to the stack. Instead, the hook implementation
9444 + * is expected to properly dispose of the skb.
9445 + *
9446 + * On the Tx path, the Ethernet driver's dpa_tx() function will
9447 + * immediately return NETDEV_TX_OK. The hook implementation is expected
9448 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
9449 + * unless you know exactly what you're doing!
9450 + *
9451 + * On the confirmation/error paths, the Ethernet driver will _not_
9452 + * perform any fd cleanup, nor update the interface statistics.
9453 + */
9454 + DPAA_ETH_STOLEN,
9455 + /* fd/skb was returned to the Ethernet driver for regular processing.
9456 + * The hook is not allowed to, for instance, reallocate the skb (as if
9457 + * by linearizing, copying, cloning or reallocating the headroom).
9458 + */
9459 + DPAA_ETH_CONTINUE
9460 +};
9461 +
9462 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
9463 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
9464 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
9465 + struct sk_buff *skb, struct net_device *net_dev);
9466 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
9467 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
9468 +
9469 +/* used in napi related functions */
9470 +extern u16 qman_portal_max;
9471 +
9472 +/* from dpa_ethtool.c */
9473 +extern const struct ethtool_ops dpa_ethtool_ops;
9474 +
9475 +#ifdef CONFIG_FSL_DPAA_HOOKS
9476 +/* Various hooks used for unit-testing and/or fastpath optimizations.
9477 + * Currently only one set of such hooks is supported.
9478 + */
9479 +struct dpaa_eth_hooks_s {
9480 + /* Invoked on the Tx private path, immediately after receiving the skb
9481 + * from the stack.
9482 + */
9483 + dpaa_eth_egress_hook_t tx;
9484 +
9485 + /* Invoked on the Rx private path, right before passing the skb
9486 + * up the stack. At that point, the packet's protocol id has already
9487 + * been set. The skb's data pointer is now at the L3 header, and
9488 + * skb->mac_header points to the L2 header. skb->len has been adjusted
9489 + * to be the length of L3+payload (i.e., the length of the
9490 + * original frame minus the L2 header len).
9491 + * For more details on what the skb looks like, see eth_type_trans().
9492 + */
9493 + dpaa_eth_ingress_hook_t rx_default;
9494 +
9495 + /* Driver hook for the Rx error private path. */
9496 + dpaa_eth_confirm_hook_t rx_error;
9497 + /* Driver hook for the Tx confirmation private path. */
9498 + dpaa_eth_confirm_hook_t tx_confirm;
9499 + /* Driver hook for the Tx error private path. */
9500 + dpaa_eth_confirm_hook_t tx_error;
9501 +};
9502 +
9503 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
9504 +
9505 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
9506 +#endif
9507 +
9508 +int dpa_netdev_init(struct net_device *net_dev,
9509 + const uint8_t *mac_addr,
9510 + uint16_t tx_timeout);
9511 +int __cold dpa_start(struct net_device *net_dev);
9512 +int __cold dpa_stop(struct net_device *net_dev);
9513 +void __cold dpa_timeout(struct net_device *net_dev);
9514 +void __cold
9515 +dpa_get_stats64(struct net_device *net_dev,
9516 + struct rtnl_link_stats64 *stats);
9517 +int dpa_ndo_init(struct net_device *net_dev);
9518 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
9519 +netdev_features_t dpa_fix_features(struct net_device *dev,
9520 + netdev_features_t features);
9521 +#ifdef CONFIG_FSL_DPAA_TS
9522 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
9523 + enum port_type rx_tx, const void *data);
9524 +/* Updates the skb shared hw timestamp from the hardware timestamp */
9525 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
9526 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
9527 +#endif /* CONFIG_FSL_DPAA_TS */
9528 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
9529 +int __cold dpa_remove(struct platform_device *of_dev);
9530 +struct mac_device * __cold __must_check
9531 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
9532 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
9533 +void dpa_set_rx_mode(struct net_device *net_dev);
9534 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
9535 + struct dpa_buffer_layout_s *layout);
9536 +int __attribute__((nonnull))
9537 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev);
9538 +void __cold __attribute__((nonnull))
9539 +dpa_bp_free(struct dpa_priv_s *priv);
9540 +struct dpa_bp *dpa_bpid2pool(int bpid);
9541 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
9542 +bool dpa_bpid2pool_use(int bpid);
9543 +void dpa_bp_drain(struct dpa_bp *bp);
9544 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
9545 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
9546 + void *accel_priv, select_queue_fallback_t fallback);
9547 +#endif
9548 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
9549 + u32 fq_start,
9550 + u32 fq_count,
9551 + struct list_head *list,
9552 + enum dpa_fq_type fq_type);
9553 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
9554 + struct fm_port_fqs *port_fqs,
9555 + bool tx_conf_fqs_per_core,
9556 + enum port_type ptype);
9557 +int dpa_get_channel(void);
9558 +void dpa_release_channel(void);
9559 +void dpaa_eth_add_channel(u16 channel);
9560 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
9561 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
9562 + struct fm_port *tx_port);
9563 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
9564 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
9565 +int __cold __attribute__((nonnull))
9566 +dpa_fq_free(struct device *dev, struct list_head *list);
9567 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
9568 + struct dpa_bp *bp, size_t count,
9569 + struct fm_port_fqs *port_fqs,
9570 + struct dpa_buffer_layout_s *buf_layout,
9571 + struct device *dev);
9572 +void dpa_release_sgt(struct qm_sg_entry *sgt);
9573 +void __attribute__((nonnull))
9574 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
9575 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
9576 + const struct qm_mr_entry *msg);
9577 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
9578 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
9579 +#ifdef CONFIG_FSL_DPAA_CEETM
9580 +void dpa_enable_ceetm(struct net_device *dev);
9581 +void dpa_disable_ceetm(struct net_device *dev);
9582 +#endif
9583 +struct proxy_device {
9584 + struct mac_device *mac_dev;
9585 +};
9586 +
9587 +/* mac device control functions exposed by proxy interface*/
9588 +int dpa_proxy_start(struct net_device *net_dev);
9589 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
9590 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
9591 + struct net_device *net_dev);
9592 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
9593 + struct net_device *net_dev);
9594 +
9595 +#endif /* __DPAA_ETH_COMMON_H */
9596 --- /dev/null
9597 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
9598 @@ -0,0 +1,381 @@
9599 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
9600 + *
9601 + * Redistribution and use in source and binary forms, with or without
9602 + * modification, are permitted provided that the following conditions are met:
9603 + * * Redistributions of source code must retain the above copyright
9604 + * notice, this list of conditions and the following disclaimer.
9605 + * * Redistributions in binary form must reproduce the above copyright
9606 + * notice, this list of conditions and the following disclaimer in the
9607 + * documentation and/or other materials provided with the distribution.
9608 + * * Neither the name of Freescale Semiconductor nor the
9609 + * names of its contributors may be used to endorse or promote products
9610 + * derived from this software without specific prior written permission.
9611 + *
9612 + *
9613 + * ALTERNATIVELY, this software may be distributed under the terms of the
9614 + * GNU General Public License ("GPL") as published by the Free Software
9615 + * Foundation, either version 2 of that License or (at your option) any
9616 + * later version.
9617 + *
9618 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9619 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9620 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9621 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9622 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9623 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9624 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9625 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9626 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9627 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9628 + */
9629 +
9630 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
9631 +#define pr_fmt(fmt) \
9632 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
9633 + KBUILD_BASENAME".c", __LINE__, __func__
9634 +#else
9635 +#define pr_fmt(fmt) \
9636 + KBUILD_MODNAME ": " fmt
9637 +#endif
9638 +
9639 +#include <linux/init.h>
9640 +#include <linux/module.h>
9641 +#include <linux/of_platform.h>
9642 +#include "dpaa_eth.h"
9643 +#include "dpaa_eth_common.h"
9644 +#include "dpaa_eth_base.h"
9645 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
9646 +#include "mac.h"
9647 +
9648 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
9649 +
9650 +MODULE_LICENSE("Dual BSD/GPL");
9651 +
9652 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
9653 +
9654 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
9655 +#ifdef CONFIG_PM
9656 +
9657 +static int proxy_suspend(struct device *dev)
9658 +{
9659 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
9660 + struct mac_device *mac_dev = proxy_dev->mac_dev;
9661 + int err = 0;
9662 +
9663 + err = fm_port_suspend(mac_dev->port_dev[RX]);
9664 + if (err)
9665 + goto port_suspend_failed;
9666 +
9667 + err = fm_port_suspend(mac_dev->port_dev[TX]);
9668 + if (err)
9669 + err = fm_port_resume(mac_dev->port_dev[RX]);
9670 +
9671 +port_suspend_failed:
9672 + return err;
9673 +}
9674 +
9675 +static int proxy_resume(struct device *dev)
9676 +{
9677 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
9678 + struct mac_device *mac_dev = proxy_dev->mac_dev;
9679 + int err = 0;
9680 +
9681 + err = fm_port_resume(mac_dev->port_dev[TX]);
9682 + if (err)
9683 + goto port_resume_failed;
9684 +
9685 + err = fm_port_resume(mac_dev->port_dev[RX]);
9686 + if (err)
9687 + err = fm_port_suspend(mac_dev->port_dev[TX]);
9688 +
9689 +port_resume_failed:
9690 + return err;
9691 +}
9692 +
9693 +static const struct dev_pm_ops proxy_pm_ops = {
9694 + .suspend = proxy_suspend,
9695 + .resume = proxy_resume,
9696 +};
9697 +
9698 +#define PROXY_PM_OPS (&proxy_pm_ops)
9699 +
9700 +#else /* CONFIG_PM */
9701 +
9702 +#define PROXY_PM_OPS NULL
9703 +
9704 +#endif /* CONFIG_PM */
9705 +
9706 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
9707 +{
9708 + int err = 0, i;
9709 + struct device *dev;
9710 + struct device_node *dpa_node;
9711 + struct dpa_bp *dpa_bp;
9712 + struct list_head proxy_fq_list;
9713 + size_t count;
9714 + struct fm_port_fqs port_fqs;
9715 + struct dpa_buffer_layout_s *buf_layout = NULL;
9716 + struct mac_device *mac_dev;
9717 + struct proxy_device *proxy_dev;
9718 +
9719 + dev = &_of_dev->dev;
9720 +
9721 + dpa_node = dev->of_node;
9722 +
9723 + if (!of_device_is_available(dpa_node))
9724 + return -ENODEV;
9725 +
9726 + /* Get the buffer pools assigned to this interface */
9727 + dpa_bp = dpa_bp_probe(_of_dev, &count);
9728 + if (IS_ERR(dpa_bp))
9729 + return PTR_ERR(dpa_bp);
9730 +
9731 + mac_dev = dpa_mac_probe(_of_dev);
9732 + if (IS_ERR(mac_dev))
9733 + return PTR_ERR(mac_dev);
9734 +
9735 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
9736 + if (!proxy_dev) {
9737 + dev_err(dev, "devm_kzalloc() failed\n");
9738 + return -ENOMEM;
9739 + }
9740 +
9741 + proxy_dev->mac_dev = mac_dev;
9742 + dev_set_drvdata(dev, proxy_dev);
9743 +
9744 + /* We have physical ports, so we need to establish
9745 + * the buffer layout.
9746 + */
9747 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
9748 + GFP_KERNEL);
9749 + if (!buf_layout) {
9750 + dev_err(dev, "devm_kzalloc() failed\n");
9751 + return -ENOMEM;
9752 + }
9753 + dpa_set_buffers_layout(mac_dev, buf_layout);
9754 +
9755 + INIT_LIST_HEAD(&proxy_fq_list);
9756 +
9757 + memset(&port_fqs, 0, sizeof(port_fqs));
9758 +
9759 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
9760 + if (!err)
9761 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
9762 + TX);
9763 + if (err < 0) {
9764 + devm_kfree(dev, buf_layout);
9765 + return err;
9766 + }
9767 +
9768 + /* Proxy initializer - Just configures the MAC on behalf of
9769 + * another partition.
9770 + */
9771 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
9772 + buf_layout, dev);
9773 +
9774 + /* Proxy interfaces need to be started, and the allocated
9775 + * memory freed
9776 + */
9777 + devm_kfree(dev, buf_layout);
9778 + devm_kfree(dev, dpa_bp);
9779 +
9780 + /* Free FQ structures */
9781 + devm_kfree(dev, port_fqs.rx_defq);
9782 + devm_kfree(dev, port_fqs.rx_errq);
9783 + devm_kfree(dev, port_fqs.tx_defq);
9784 + devm_kfree(dev, port_fqs.tx_errq);
9785 +
9786 + for_each_port_device(i, mac_dev->port_dev) {
9787 + err = fm_port_enable(mac_dev->port_dev[i]);
9788 + if (err)
9789 + goto port_enable_fail;
9790 + }
9791 +
9792 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
9793 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
9794 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
9795 +
9796 + return 0; /* Proxy interface initialization ended */
9797 +
9798 +port_enable_fail:
9799 + for_each_port_device(i, mac_dev->port_dev)
9800 + fm_port_disable(mac_dev->port_dev[i]);
9801 + dpa_eth_proxy_remove(_of_dev);
9802 +
9803 + return err;
9804 +}
9805 +
9806 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
9807 + struct net_device *net_dev)
9808 +{
9809 + struct mac_device *mac_dev;
9810 + int _errno;
9811 +
9812 + mac_dev = proxy_dev->mac_dev;
9813 +
9814 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
9815 + net_dev->dev_addr);
9816 + if (_errno < 0)
9817 + return _errno;
9818 +
9819 + return 0;
9820 +}
9821 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
9822 +
9823 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
9824 + struct net_device *net_dev)
9825 +{
9826 + struct mac_device *mac_dev = proxy_dev->mac_dev;
9827 + int _errno;
9828 +
9829 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
9830 + mac_dev->promisc = !mac_dev->promisc;
9831 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
9832 + mac_dev->promisc);
9833 + if (unlikely(_errno < 0))
9834 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
9835 + _errno);
9836 + }
9837 +
9838 + _errno = mac_dev->set_multi(net_dev, mac_dev);
9839 + if (unlikely(_errno < 0))
9840 + return _errno;
9841 +
9842 + return 0;
9843 +}
9844 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
9845 +
9846 +int dpa_proxy_start(struct net_device *net_dev)
9847 +{
9848 + struct mac_device *mac_dev;
9849 + const struct dpa_priv_s *priv;
9850 + struct proxy_device *proxy_dev;
9851 + int _errno;
9852 + int i;
9853 +
9854 + priv = netdev_priv(net_dev);
9855 + proxy_dev = (struct proxy_device *)priv->peer;
9856 + mac_dev = proxy_dev->mac_dev;
9857 +
9858 + _errno = mac_dev->init_phy(net_dev, mac_dev);
9859 + if (_errno < 0) {
9860 + if (netif_msg_drv(priv))
9861 + netdev_err(net_dev, "init_phy() = %d\n",
9862 + _errno);
9863 + return _errno;
9864 + }
9865 +
9866 + for_each_port_device(i, mac_dev->port_dev) {
9867 + _errno = fm_port_enable(mac_dev->port_dev[i]);
9868 + if (_errno)
9869 + goto port_enable_fail;
9870 + }
9871 +
9872 + _errno = mac_dev->start(mac_dev);
9873 + if (_errno < 0) {
9874 + if (netif_msg_drv(priv))
9875 + netdev_err(net_dev, "mac_dev->start() = %d\n",
9876 + _errno);
9877 + goto port_enable_fail;
9878 + }
9879 +
9880 + return _errno;
9881 +
9882 +port_enable_fail:
9883 + for_each_port_device(i, mac_dev->port_dev)
9884 + fm_port_disable(mac_dev->port_dev[i]);
9885 +
9886 + return _errno;
9887 +}
9888 +EXPORT_SYMBOL(dpa_proxy_start);
9889 +
9890 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
9891 +{
9892 + struct mac_device *mac_dev = proxy_dev->mac_dev;
9893 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
9894 + int _errno, i, err;
9895 +
9896 + _errno = mac_dev->stop(mac_dev);
9897 + if (_errno < 0) {
9898 + if (netif_msg_drv(priv))
9899 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
9900 + _errno);
9901 + return _errno;
9902 + }
9903 +
9904 + for_each_port_device(i, mac_dev->port_dev) {
9905 + err = fm_port_disable(mac_dev->port_dev[i]);
9906 + _errno = err ? err : _errno;
9907 + }
9908 +
9909 + if (mac_dev->phy_dev)
9910 + phy_disconnect(mac_dev->phy_dev);
9911 + mac_dev->phy_dev = NULL;
9912 +
9913 + return _errno;
9914 +}
9915 +EXPORT_SYMBOL(dpa_proxy_stop);
9916 +
9917 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
9918 +{
9919 + struct device *dev = &of_dev->dev;
9920 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
9921 +
9922 + kfree(proxy_dev);
9923 +
9924 + dev_set_drvdata(dev, NULL);
9925 +
9926 + return 0;
9927 +}
9928 +
9929 +static const struct of_device_id dpa_proxy_match[] = {
9930 + {
9931 + .compatible = "fsl,dpa-ethernet-init"
9932 + },
9933 + {}
9934 +};
9935 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
9936 +
9937 +static struct platform_driver dpa_proxy_driver = {
9938 + .driver = {
9939 + .name = KBUILD_MODNAME "-proxy",
9940 + .of_match_table = dpa_proxy_match,
9941 + .owner = THIS_MODULE,
9942 + .pm = PROXY_PM_OPS,
9943 + },
9944 + .probe = dpaa_eth_proxy_probe,
9945 + .remove = dpa_eth_proxy_remove
9946 +};
9947 +
9948 +static int __init __cold dpa_proxy_load(void)
9949 +{
9950 + int _errno;
9951 +
9952 + pr_info(DPA_DESCRIPTION "\n");
9953 +
9954 + /* Initialize dpaa_eth mirror values */
9955 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
9956 + dpa_max_frm = fm_get_max_frm();
9957 +
9958 + _errno = platform_driver_register(&dpa_proxy_driver);
9959 + if (unlikely(_errno < 0)) {
9960 + pr_err(KBUILD_MODNAME
9961 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
9962 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
9963 + }
9964 +
9965 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
9966 + KBUILD_BASENAME".c", __func__);
9967 +
9968 + return _errno;
9969 +}
9970 +module_init(dpa_proxy_load);
9971 +
9972 +static void __exit __cold dpa_proxy_unload(void)
9973 +{
9974 + platform_driver_unregister(&dpa_proxy_driver);
9975 +
9976 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
9977 + KBUILD_BASENAME".c", __func__);
9978 +}
9979 +module_exit(dpa_proxy_unload);
9980 --- /dev/null
9981 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
9982 @@ -0,0 +1,1201 @@
9983 +/* Copyright 2012 Freescale Semiconductor Inc.
9984 + *
9985 + * Redistribution and use in source and binary forms, with or without
9986 + * modification, are permitted provided that the following conditions are met:
9987 + * * Redistributions of source code must retain the above copyright
9988 + * notice, this list of conditions and the following disclaimer.
9989 + * * Redistributions in binary form must reproduce the above copyright
9990 + * notice, this list of conditions and the following disclaimer in the
9991 + * documentation and/or other materials provided with the distribution.
9992 + * * Neither the name of Freescale Semiconductor nor the
9993 + * names of its contributors may be used to endorse or promote products
9994 + * derived from this software without specific prior written permission.
9995 + *
9996 + *
9997 + * ALTERNATIVELY, this software may be distributed under the terms of the
9998 + * GNU General Public License ("GPL") as published by the Free Software
9999 + * Foundation, either version 2 of that License or (at your option) any
10000 + * later version.
10001 + *
10002 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10003 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10004 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10005 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10006 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10007 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10008 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10009 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10010 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10011 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10012 + */
10013 +
10014 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10015 +#define pr_fmt(fmt) \
10016 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10017 + KBUILD_BASENAME".c", __LINE__, __func__
10018 +#else
10019 +#define pr_fmt(fmt) \
10020 + KBUILD_MODNAME ": " fmt
10021 +#endif
10022 +
10023 +#include <linux/init.h>
10024 +#include <linux/skbuff.h>
10025 +#include <linux/highmem.h>
10026 +#include <linux/fsl_bman.h>
10027 +#include <net/sock.h>
10028 +
10029 +#include "dpaa_eth.h"
10030 +#include "dpaa_eth_common.h"
10031 +#ifdef CONFIG_FSL_DPAA_1588
10032 +#include "dpaa_1588.h"
10033 +#endif
10034 +#ifdef CONFIG_FSL_DPAA_CEETM
10035 +#include "dpaa_eth_ceetm.h"
10036 +#endif
10037 +
10038 +/* DMA map and add a page frag back into the bpool.
10039 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
10040 + * specifically for fitting into @dpa_bp.
10041 + */
10042 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
10043 + int *count_ptr)
10044 +{
10045 + struct bm_buffer bmb;
10046 + dma_addr_t addr;
10047 +
10048 + bmb.opaque = 0;
10049 +
10050 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
10051 + DMA_BIDIRECTIONAL);
10052 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
10053 + dev_err(dpa_bp->dev, "DMA mapping failed");
10054 + return;
10055 + }
10056 +
10057 + bm_buffer_set64(&bmb, addr);
10058 +
10059 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
10060 + cpu_relax();
10061 +
10062 + (*count_ptr)++;
10063 +}
10064 +
10065 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
10066 +{
10067 + void *new_buf, *fman_buf;
10068 + struct bm_buffer bmb[8];
10069 + dma_addr_t addr;
10070 + uint8_t i;
10071 + struct device *dev = dpa_bp->dev;
10072 + struct sk_buff *skb, **skbh;
10073 +
10074 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
10075 +
10076 + for (i = 0; i < 8; i++) {
10077 + /* We'll prepend the skb back-pointer; can't use the DPA
10078 + * priv space, because FMan will overwrite it (from offset 0)
10079 + * if it ends up being the second, third, etc. fragment
10080 + * in a S/G frame.
10081 + *
10082 + * We only need enough space to store a pointer, but allocate
10083 + * an entire cacheline for performance reasons.
10084 + */
10085 +#ifndef CONFIG_PPC
10086 + if (unlikely(dpaa_errata_a010022)) {
10087 + struct page *new_page = alloc_page(GFP_ATOMIC);
10088 + if (unlikely(!new_page))
10089 + goto netdev_alloc_failed;
10090 + new_buf = page_address(new_page);
10091 + }
10092 + else
10093 +#endif
10094 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
10095 +
10096 + if (unlikely(!new_buf))
10097 + goto netdev_alloc_failed;
10098 + new_buf = PTR_ALIGN(new_buf, SMP_CACHE_BYTES);
10099 +
10100 + /* Apart from the buffer that will be used by the FMan, the
10101 + * skb also guarantees enough space to hold the backpointer
10102 + * in the headroom and the shared info at the end.
10103 + */
10104 + skb = build_skb(new_buf,
10105 + SMP_CACHE_BYTES + DPA_SKB_SIZE(dpa_bp->size) +
10106 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
10107 + if (unlikely(!skb)) {
10108 + put_page(virt_to_head_page(new_buf));
10109 + goto build_skb_failed;
10110 + }
10111 +
10112 + /* Reserve SMP_CACHE_BYTES in the skb's headroom to store the
10113 + * backpointer. This area will not be synced to, or
10114 + * overwritten by, the FMan.
10115 + */
10116 + skb_reserve(skb, SMP_CACHE_BYTES);
10117 +
10118 + /* We don't sync the first SMP_CACHE_BYTES of the buffer to
10119 + * the FMan. The skb backpointer is stored at the end of the
10120 + * reserved headroom. Otherwise it will be overwritten by the
10121 + * FMan.
10122 + * The buffer synced with the FMan starts right after the
10123 + * reserved headroom.
10124 + */
10125 + fman_buf = new_buf + SMP_CACHE_BYTES;
10126 + DPA_WRITE_SKB_PTR(skb, skbh, fman_buf, -1);
10127 +
10128 + addr = dma_map_single(dev, fman_buf,
10129 + dpa_bp->size, DMA_BIDIRECTIONAL);
10130 + if (unlikely(dma_mapping_error(dev, addr)))
10131 + goto dma_map_failed;
10132 +
10133 + bm_buffer_set64(&bmb[i], addr);
10134 + }
10135 +
10136 +release_bufs:
10137 + /* Release the buffers. In case bman is busy, keep trying
10138 + * until successful. bman_release() is guaranteed to succeed
10139 + * in a reasonable amount of time
10140 + */
10141 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
10142 + cpu_relax();
10143 + return i;
10144 +
10145 +dma_map_failed:
10146 + kfree_skb(skb);
10147 +
10148 +build_skb_failed:
10149 +netdev_alloc_failed:
10150 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
10151 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
10152 +
10153 + bm_buffer_set64(&bmb[i], 0);
10154 + /* Avoid releasing a completely null buffer; bman_release() requires
10155 + * at least one buffer.
10156 + */
10157 + if (likely(i))
10158 + goto release_bufs;
10159 +
10160 + return 0;
10161 +}
10162 +
10163 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
10164 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
10165 +{
10166 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
10167 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
10168 +}
10169 +
10170 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
10171 +{
10172 + int i;
10173 +
10174 + /* Give each CPU an allotment of "config_count" buffers */
10175 + for_each_possible_cpu(i) {
10176 + int j;
10177 +
10178 + /* Although we access another CPU's counters here
10179 + * we do it at boot time so it is safe
10180 + */
10181 + for (j = 0; j < dpa_bp->config_count; j += 8)
10182 + dpa_bp_add_8_bufs(dpa_bp, i);
10183 + }
10184 + return 0;
10185 +}
10186 +EXPORT_SYMBOL(dpa_bp_priv_seed);
10187 +
10188 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
10189 + * REFILL_THRESHOLD.
10190 + */
10191 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
10192 +{
10193 + int count = *countptr;
10194 + int new_bufs;
10195 +
10196 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
10197 + do {
10198 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
10199 + if (unlikely(!new_bufs)) {
10200 + /* Avoid looping forever if we've temporarily
10201 + * run out of memory. We'll try again at the
10202 + * next NAPI cycle.
10203 + */
10204 + break;
10205 + }
10206 + count += new_bufs;
10207 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
10208 +
10209 + *countptr = count;
10210 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
10211 + return -ENOMEM;
10212 + }
10213 +
10214 + return 0;
10215 +}
10216 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
10217 +
10218 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
10219 + * either contiguous frames or scatter/gather ones.
10220 + * Skb freeing is not handled here.
10221 + *
10222 + * This function may be called on error paths in the Tx function, so guard
10223 + * against cases when not all fd relevant fields were filled in.
10224 + *
10225 + * Return the skb backpointer, since for S/G frames the buffer containing it
10226 + * gets freed here.
10227 + */
10228 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
10229 + const struct qm_fd *fd)
10230 +{
10231 + const struct qm_sg_entry *sgt;
10232 + int i;
10233 + struct dpa_bp *dpa_bp = priv->dpa_bp;
10234 + dma_addr_t addr = qm_fd_addr(fd);
10235 + dma_addr_t sg_addr;
10236 + struct sk_buff **skbh;
10237 + struct sk_buff *skb = NULL;
10238 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
10239 + int nr_frags;
10240 + int sg_len;
10241 +
10242 + /* retrieve skb back pointer */
10243 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
10244 +
10245 + if (unlikely(fd->format == qm_fd_sg)) {
10246 + nr_frags = skb_shinfo(skb)->nr_frags;
10247 + dma_unmap_single(dpa_bp->dev, addr,
10248 + dpa_fd_offset(fd) + DPA_SGT_SIZE,
10249 + dma_dir);
10250 +
10251 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
10252 + * it's from lowmem.
10253 + */
10254 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
10255 +#ifdef CONFIG_FSL_DPAA_1588
10256 + if (priv->tsu && priv->tsu->valid &&
10257 + priv->tsu->hwts_tx_en_ioctl)
10258 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
10259 +#endif
10260 +#ifdef CONFIG_FSL_DPAA_TS
10261 + if (unlikely(priv->ts_tx_en &&
10262 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
10263 + struct skb_shared_hwtstamps shhwtstamps;
10264 +
10265 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
10266 + skb_tstamp_tx(skb, &shhwtstamps);
10267 + }
10268 +#endif /* CONFIG_FSL_DPAA_TS */
10269 +
10270 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
10271 + sg_addr = qm_sg_addr(&sgt[0]);
10272 + sg_len = qm_sg_entry_get_len(&sgt[0]);
10273 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
10274 +
10275 + /* remaining pages were mapped with dma_map_page() */
10276 + for (i = 1; i <= nr_frags; i++) {
10277 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
10278 + sg_addr = qm_sg_addr(&sgt[i]);
10279 + sg_len = qm_sg_entry_get_len(&sgt[i]);
10280 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
10281 + }
10282 +
10283 + /* Free the page frag that we allocated on Tx */
10284 + put_page(virt_to_head_page(sgt));
10285 + } else {
10286 + dma_unmap_single(dpa_bp->dev, addr,
10287 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
10288 +#ifdef CONFIG_FSL_DPAA_TS
10289 + /* get the timestamp for non-SG frames */
10290 +#ifdef CONFIG_FSL_DPAA_1588
10291 + if (priv->tsu && priv->tsu->valid &&
10292 + priv->tsu->hwts_tx_en_ioctl)
10293 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
10294 +#endif
10295 + if (unlikely(priv->ts_tx_en &&
10296 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
10297 + struct skb_shared_hwtstamps shhwtstamps;
10298 +
10299 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
10300 + skb_tstamp_tx(skb, &shhwtstamps);
10301 + }
10302 +#endif
10303 + }
10304 +
10305 + return skb;
10306 +}
10307 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
10308 +
10309 +#ifndef CONFIG_FSL_DPAA_TS
10310 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
10311 +{
10312 +#ifndef CONFIG_PPC
10313 + /* Do no recycle skbs realigned by the errata workaround */
10314 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
10315 + return false;
10316 +#endif
10317 +
10318 + /* No recycling possible if skb buffer is kmalloc'ed */
10319 + if (skb->head_frag == 0)
10320 + return false;
10321 +
10322 + /* or if it's an userspace buffer */
10323 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
10324 + return false;
10325 +
10326 + /* or if it's cloned or shared */
10327 + if (skb_shared(skb) || skb_cloned(skb) ||
10328 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
10329 + return false;
10330 +
10331 + return true;
10332 +}
10333 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
10334 +
10335 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
10336 + uint32_t min_size,
10337 + uint16_t min_offset,
10338 + unsigned char **new_buf_start)
10339 +{
10340 + unsigned char *new;
10341 +
10342 + /* In order to recycle a buffer, the following conditions must be met:
10343 + * - buffer size no less than the buffer pool size
10344 + * - buffer size no higher than an upper limit (to avoid moving too much
10345 + * system memory to the buffer pools)
10346 + * - buffer address aligned to cacheline bytes
10347 + * - offset of data from start of buffer no lower than a minimum value
10348 + * - offset of data from start of buffer no higher than a maximum value
10349 + * - the skb back-pointer is stored safely
10350 + */
10351 +
10352 + /* guarantee both the minimum size and the minimum data offset */
10353 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
10354 +
10355 + /* left align to the nearest cacheline */
10356 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
10357 +
10358 + /* Make sure there is enough space to store the skb back-pointer in
10359 + * the headroom, right before the start of the buffer.
10360 + *
10361 + * Guarantee that both maximum size and maximum data offsets aren't
10362 + * crossed.
10363 + */
10364 + if (likely(new >= (skb->head + sizeof(void *)) &&
10365 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
10366 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
10367 + *new_buf_start = new;
10368 + return true;
10369 + }
10370 +
10371 + return false;
10372 +}
10373 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
10374 +#endif
10375 +
10376 +/* Build a linear skb around the received buffer.
10377 + * We are guaranteed there is enough room at the end of the data buffer to
10378 + * accommodate the shared info area of the skb.
10379 + */
10380 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
10381 + const struct qm_fd *fd, int *use_gro)
10382 +{
10383 + dma_addr_t addr = qm_fd_addr(fd);
10384 + ssize_t fd_off = dpa_fd_offset(fd);
10385 + void *vaddr;
10386 + const fm_prs_result_t *parse_results;
10387 + struct sk_buff *skb = NULL, **skbh;
10388 +
10389 + vaddr = phys_to_virt(addr);
10390 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
10391 +
10392 + /* Retrieve the skb and adjust data and tail pointers, to make sure
10393 + * forwarded skbs will have enough space on Tx if extra headers
10394 + * are added.
10395 + */
10396 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
10397 +
10398 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
10399 + /* When using jumbo Rx buffers, we risk having frames dropped due to
10400 + * the socket backlog reaching its maximum allowed size.
10401 + * Use the frame length for the skb truesize instead of the buffer
10402 + * size, as this is the size of the data that actually gets copied to
10403 + * userspace.
10404 + * The stack may increase the payload. In this case, it will want to
10405 + * warn us that the frame length is larger than the truesize. We
10406 + * bypass the warning.
10407 + */
10408 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
10409 +#endif
10410 +
10411 + DPA_BUG_ON(fd_off != priv->rx_headroom);
10412 + skb_reserve(skb, fd_off);
10413 + skb_put(skb, dpa_fd_length(fd));
10414 +
10415 + /* Peek at the parse results for csum validation */
10416 + parse_results = (const fm_prs_result_t *)(vaddr +
10417 + DPA_RX_PRIV_DATA_SIZE);
10418 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
10419 +
10420 +#ifdef CONFIG_FSL_DPAA_1588
10421 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
10422 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
10423 +#endif
10424 +#ifdef CONFIG_FSL_DPAA_TS
10425 + if (priv->ts_rx_en)
10426 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
10427 +#endif /* CONFIG_FSL_DPAA_TS */
10428 +
10429 + return skb;
10430 +}
10431 +
10432 +
10433 +/* Build an skb with the data of the first S/G entry in the linear portion and
10434 + * the rest of the frame as skb fragments.
10435 + *
10436 + * The page fragment holding the S/G Table is recycled here.
10437 + */
10438 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
10439 + const struct qm_fd *fd, int *use_gro,
10440 + int *count_ptr)
10441 +{
10442 + const struct qm_sg_entry *sgt;
10443 + dma_addr_t addr = qm_fd_addr(fd);
10444 + ssize_t fd_off = dpa_fd_offset(fd);
10445 + dma_addr_t sg_addr;
10446 + void *vaddr, *sg_vaddr;
10447 + struct dpa_bp *dpa_bp;
10448 + struct page *page, *head_page;
10449 + int frag_offset, frag_len;
10450 + int page_offset;
10451 + int i;
10452 + const fm_prs_result_t *parse_results;
10453 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
10454 +
10455 + vaddr = phys_to_virt(addr);
10456 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
10457 +
10458 + dpa_bp = priv->dpa_bp;
10459 + /* Iterate through the SGT entries and add data buffers to the skb */
10460 + sgt = vaddr + fd_off;
10461 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
10462 + /* Extension bit is not supported */
10463 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
10464 +
10465 + /* We use a single global Rx pool */
10466 + DPA_BUG_ON(dpa_bp !=
10467 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
10468 +
10469 + sg_addr = qm_sg_addr(&sgt[i]);
10470 + sg_vaddr = phys_to_virt(sg_addr);
10471 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
10472 + SMP_CACHE_BYTES));
10473 +
10474 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
10475 + DMA_BIDIRECTIONAL);
10476 + if (i == 0) {
10477 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
10478 +#ifdef CONFIG_FSL_DPAA_1588
10479 + if (priv->tsu && priv->tsu->valid &&
10480 + priv->tsu->hwts_rx_en_ioctl)
10481 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
10482 +#endif
10483 +#ifdef CONFIG_FSL_DPAA_TS
10484 + if (priv->ts_rx_en)
10485 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
10486 +#endif /* CONFIG_FSL_DPAA_TS */
10487 +
10488 + /* In the case of a SG frame, FMan stores the Internal
10489 + * Context in the buffer containing the sgt.
10490 + * Inspect the parse results before anything else.
10491 + */
10492 + parse_results = (const fm_prs_result_t *)(vaddr +
10493 + DPA_RX_PRIV_DATA_SIZE);
10494 + _dpa_process_parse_results(parse_results, fd, skb,
10495 + use_gro);
10496 +
10497 + /* Make sure forwarded skbs will have enough space
10498 + * on Tx, if extra headers are added.
10499 + */
10500 + DPA_BUG_ON(fd_off != priv->rx_headroom);
10501 + skb_reserve(skb, fd_off);
10502 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
10503 + } else {
10504 + /* Not the first S/G entry; all data from buffer will
10505 + * be added in an skb fragment; fragment index is offset
10506 + * by one since first S/G entry was incorporated in the
10507 + * linear part of the skb.
10508 + *
10509 + * Caution: 'page' may be a tail page.
10510 + */
10511 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
10512 + page = virt_to_page(sg_vaddr);
10513 + head_page = virt_to_head_page(sg_vaddr);
10514 +
10515 + /* Free (only) the skbuff shell because its data buffer
10516 + * is already a frag in the main skb.
10517 + */
10518 + get_page(head_page);
10519 + dev_kfree_skb(skb_tmp);
10520 +
10521 + /* Compute offset in (possibly tail) page */
10522 + page_offset = ((unsigned long)sg_vaddr &
10523 + (PAGE_SIZE - 1)) +
10524 + (page_address(page) - page_address(head_page));
10525 + /* page_offset only refers to the beginning of sgt[i];
10526 + * but the buffer itself may have an internal offset.
10527 + */
10528 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
10529 + page_offset;
10530 + frag_len = qm_sg_entry_get_len(&sgt[i]);
10531 + /* skb_add_rx_frag() does no checking on the page; if
10532 + * we pass it a tail page, we'll end up with
10533 + * bad page accounting and eventually with segafults.
10534 + */
10535 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
10536 + frag_len, dpa_bp->size);
10537 + }
10538 + /* Update the pool count for the current {cpu x bpool} */
10539 + (*count_ptr)--;
10540 +
10541 + if (qm_sg_entry_get_final(&sgt[i]))
10542 + break;
10543 + }
10544 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
10545 +
10546 + /* recycle the SGT fragment */
10547 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
10548 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
10549 + return skb;
10550 +}
10551 +
10552 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
10553 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
10554 + struct sk_buff *skb)
10555 +{
10556 + if (unlikely(priv->loop_to < 0))
10557 + return 0; /* loop disabled by default */
10558 +
10559 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
10560 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
10561 +
10562 + return 1; /* Frame Tx on the selected interface */
10563 +}
10564 +#endif
10565 +
10566 +void __hot _dpa_rx(struct net_device *net_dev,
10567 + struct qman_portal *portal,
10568 + const struct dpa_priv_s *priv,
10569 + struct dpa_percpu_priv_s *percpu_priv,
10570 + const struct qm_fd *fd,
10571 + u32 fqid,
10572 + int *count_ptr)
10573 +{
10574 + struct dpa_bp *dpa_bp;
10575 + struct sk_buff *skb;
10576 + dma_addr_t addr = qm_fd_addr(fd);
10577 + u32 fd_status = fd->status;
10578 + unsigned int skb_len;
10579 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
10580 + int use_gro = net_dev->features & NETIF_F_GRO;
10581 +
10582 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
10583 + if (netif_msg_hw(priv) && net_ratelimit())
10584 + netdev_warn(net_dev, "FD status = 0x%08x\n",
10585 + fd_status & FM_FD_STAT_RX_ERRORS);
10586 +
10587 + percpu_stats->rx_errors++;
10588 + goto _release_frame;
10589 + }
10590 +
10591 + dpa_bp = priv->dpa_bp;
10592 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
10593 +
10594 + /* prefetch the first 64 bytes of the frame or the SGT start */
10595 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
10596 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
10597 +
10598 + /* The only FD types that we may receive are contig and S/G */
10599 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
10600 +
10601 + if (likely(fd->format == qm_fd_contig)) {
10602 +#ifdef CONFIG_FSL_DPAA_HOOKS
10603 + /* Execute the Rx processing hook, if it exists. */
10604 + if (dpaa_eth_hooks.rx_default &&
10605 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
10606 + fqid) == DPAA_ETH_STOLEN) {
10607 + /* won't count the rx bytes in */
10608 + return;
10609 + }
10610 +#endif
10611 + skb = contig_fd_to_skb(priv, fd, &use_gro);
10612 + } else {
10613 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
10614 + percpu_priv->rx_sg++;
10615 + }
10616 +
10617 + /* Account for either the contig buffer or the SGT buffer (depending on
10618 + * which case we were in) having been removed from the pool.
10619 + */
10620 + (*count_ptr)--;
10621 + skb->protocol = eth_type_trans(skb, net_dev);
10622 +
10623 + skb_len = skb->len;
10624 +
10625 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
10626 + if (dpa_skb_loop(priv, skb)) {
10627 + percpu_stats->rx_packets++;
10628 + percpu_stats->rx_bytes += skb_len;
10629 + return;
10630 + }
10631 +#endif
10632 +
10633 + if (use_gro) {
10634 + gro_result_t gro_result;
10635 + const struct qman_portal_config *pc =
10636 + qman_p_get_portal_config(portal);
10637 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
10638 +
10639 + np->p = portal;
10640 + gro_result = napi_gro_receive(&np->napi, skb);
10641 + /* If frame is dropped by the stack, rx_dropped counter is
10642 + * incremented automatically, so no need for us to update it
10643 + */
10644 + if (unlikely(gro_result == GRO_DROP))
10645 + goto packet_dropped;
10646 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
10647 + goto packet_dropped;
10648 +
10649 + percpu_stats->rx_packets++;
10650 + percpu_stats->rx_bytes += skb_len;
10651 +
10652 +packet_dropped:
10653 + return;
10654 +
10655 +_release_frame:
10656 + dpa_fd_release(net_dev, fd);
10657 +}
10658 +
10659 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
10660 + struct sk_buff *skb, struct qm_fd *fd,
10661 + int *count_ptr, int *offset)
10662 +{
10663 + struct sk_buff **skbh;
10664 + dma_addr_t addr;
10665 + struct dpa_bp *dpa_bp = priv->dpa_bp;
10666 + struct net_device *net_dev = priv->net_dev;
10667 + int err;
10668 + enum dma_data_direction dma_dir;
10669 + unsigned char *buffer_start;
10670 + int dma_map_size;
10671 +
10672 +#ifndef CONFIG_FSL_DPAA_TS
10673 + /* Check recycling conditions; only if timestamp support is not
10674 + * enabled, otherwise we need the fd back on tx confirmation
10675 + */
10676 +
10677 + /* We can recycle the buffer if:
10678 + * - the pool is not full
10679 + * - the buffer meets the skb recycling conditions
10680 + * - the buffer meets our own (size, offset, align) conditions
10681 + */
10682 + if (likely((*count_ptr < dpa_bp->target_count) &&
10683 + dpa_skb_is_recyclable(skb) &&
10684 + dpa_buf_is_recyclable(skb, dpa_bp->size,
10685 + priv->tx_headroom, &buffer_start))) {
10686 + /* Buffer is recyclable; use the new start address
10687 + * and set fd parameters and DMA mapping direction
10688 + */
10689 + fd->bpid = dpa_bp->bpid;
10690 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
10691 + fd->offset = (uint16_t)(skb->data - buffer_start);
10692 + dma_dir = DMA_BIDIRECTIONAL;
10693 + dma_map_size = dpa_bp->size;
10694 +
10695 + /* Store the skb back-pointer before the start of the buffer.
10696 + * Otherwise it will be overwritten by the FMan.
10697 + */
10698 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
10699 + *offset = skb_headroom(skb) - fd->offset;
10700 + } else
10701 +#endif
10702 + {
10703 + /* Not recyclable.
10704 + * We are guaranteed to have at least tx_headroom bytes
10705 + * available, so just use that for offset.
10706 + */
10707 + fd->bpid = 0xff;
10708 + buffer_start = skb->data - priv->tx_headroom;
10709 + fd->offset = priv->tx_headroom;
10710 + dma_dir = DMA_TO_DEVICE;
10711 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
10712 +
10713 + /* The buffer will be Tx-confirmed, but the TxConf cb must
10714 + * necessarily look at our Tx private data to retrieve the
10715 + * skbuff. Store the back-pointer inside the buffer.
10716 + */
10717 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
10718 + }
10719 +
10720 + /* Enable L3/L4 hardware checksum computation.
10721 + *
10722 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
10723 + * need to write into the skb.
10724 + */
10725 + err = dpa_enable_tx_csum(priv, skb, fd,
10726 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
10727 + if (unlikely(err < 0)) {
10728 + if (netif_msg_tx_err(priv) && net_ratelimit())
10729 + netdev_err(net_dev, "HW csum error: %d\n", err);
10730 + return err;
10731 + }
10732 +
10733 + /* Fill in the rest of the FD fields */
10734 + fd->format = qm_fd_contig;
10735 + fd->length20 = skb->len;
10736 + fd->cmd |= FM_FD_CMD_FCO;
10737 +
10738 + /* Map the entire buffer size that may be seen by FMan, but no more */
10739 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
10740 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
10741 + if (netif_msg_tx_err(priv) && net_ratelimit())
10742 + netdev_err(net_dev, "dma_map_single() failed\n");
10743 + return -EINVAL;
10744 + }
10745 + qm_fd_addr_set64(fd, addr);
10746 +
10747 + return 0;
10748 +}
10749 +EXPORT_SYMBOL(skb_to_contig_fd);
10750 +
10751 +#ifndef CONFIG_PPC
10752 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
10753 + * 16 bytes and 4K memory address crossings.
10754 + */
10755 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
10756 +{
10757 + int nr_frags, i = 0;
10758 + skb_frag_t *frag;
10759 +
10760 + /* Check if the headroom is aligned */
10761 + if (((uintptr_t)skb->data - priv->tx_headroom) %
10762 + priv->buf_layout[TX].data_align != 0)
10763 + return true;
10764 +
10765 + /* Check if the headroom crosses a boundary */
10766 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
10767 + return true;
10768 +
10769 + /* Check if the non-paged data crosses a boundary */
10770 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
10771 + return true;
10772 +
10773 + /* Check if the entire linear skb crosses a boundary */
10774 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
10775 + return true;
10776 +
10777 + nr_frags = skb_shinfo(skb)->nr_frags;
10778 +
10779 + while (i < nr_frags) {
10780 + frag = &skb_shinfo(skb)->frags[i];
10781 +
10782 + /* Check if a paged fragment crosses a boundary from its
10783 + * offset to its end.
10784 + */
10785 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
10786 + return true;
10787 +
10788 + i++;
10789 + }
10790 +
10791 + return false;
10792 +}
10793 +
10794 +/* Realign the skb by copying its contents at the start of a newly allocated
10795 + * page. Build a new skb around the new buffer and release the old one.
10796 + * A performance drop should be expected.
10797 + */
10798 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
10799 + struct dpa_priv_s *priv)
10800 +{
10801 + int trans_offset = skb_transport_offset(skb);
10802 + int net_offset = skb_network_offset(skb);
10803 + int nsize, headroom, npage_order;
10804 + struct sk_buff *nskb = NULL;
10805 + struct page *npage;
10806 + void *npage_addr;
10807 +
10808 + headroom = DPAA_A010022_HEADROOM;
10809 +
10810 + /* For the new skb we only need the old one's data (both non-paged and
10811 + * paged). We can skip the old tailroom.
10812 + *
10813 + * Make sure the skb_shinfo is cache-line aligned.
10814 + */
10815 + nsize = SMP_CACHE_BYTES + DPA_SKB_SIZE(headroom + skb->len) +
10816 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
10817 +
10818 + /* Reserve enough memory to accommodate Jumbo frames */
10819 + npage_order = (nsize - 1) / PAGE_SIZE;
10820 + npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order);
10821 + if (unlikely(!npage)) {
10822 + WARN_ONCE(1, "Memory allocation failure\n");
10823 + return NULL;
10824 + }
10825 + npage_addr = page_address(npage);
10826 +
10827 + nskb = build_skb(npage_addr, nsize);
10828 + if (unlikely(!nskb))
10829 + goto err;
10830 +
10831 + /* Reserve only the needed headroom in order to guarantee the data's
10832 + * alignment.
10833 + * Code borrowed and adapted from skb_copy().
10834 + */
10835 + skb_reserve(nskb, headroom);
10836 + skb_put(nskb, skb->len);
10837 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
10838 + WARN_ONCE(1, "skb parsing failure\n");
10839 + goto err;
10840 + }
10841 + copy_skb_header(nskb, skb);
10842 +
10843 +#ifdef CONFIG_FSL_DPAA_TS
10844 + /* Copy relevant timestamp info from the old skb to the new */
10845 + if (priv->ts_tx_en) {
10846 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
10847 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
10848 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
10849 + if (skb->sk)
10850 + skb_set_owner_w(nskb, skb->sk);
10851 + }
10852 +#endif
10853 + /* We move the headroom when we align it so we have to reset the
10854 + * network and transport header offsets relative to the new data
10855 + * pointer. The checksum offload relies on these offsets.
10856 + */
10857 + skb_set_network_header(nskb, net_offset);
10858 + skb_set_transport_header(nskb, trans_offset);
10859 +
10860 + /* We don't want the buffer to be recycled so we mark it accordingly */
10861 + nskb->mark = NONREC_MARK;
10862 +
10863 + dev_kfree_skb(skb);
10864 + return nskb;
10865 +
10866 +err:
10867 + if (nskb)
10868 + dev_kfree_skb(nskb);
10869 + put_page(npage);
10870 + return NULL;
10871 +}
10872 +#endif
10873 +
10874 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
10875 + struct sk_buff *skb, struct qm_fd *fd)
10876 +{
10877 + struct dpa_bp *dpa_bp = priv->dpa_bp;
10878 + dma_addr_t addr;
10879 + dma_addr_t sg_addr;
10880 + struct sk_buff **skbh;
10881 + struct net_device *net_dev = priv->net_dev;
10882 + int sg_len, sgt_size;
10883 + int err;
10884 +
10885 + struct qm_sg_entry *sgt;
10886 + void *sgt_buf;
10887 + skb_frag_t *frag;
10888 + int i = 0, j = 0;
10889 + int nr_frags;
10890 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
10891 +
10892 + nr_frags = skb_shinfo(skb)->nr_frags;
10893 + fd->format = qm_fd_sg;
10894 +
10895 + /* The FMan reads 256 bytes from the start of the SGT regardless of
10896 + * its size. In accordance, we reserve the same amount of memory as
10897 + * well.
10898 + */
10899 + sgt_size = DPA_SGT_SIZE;
10900 +
10901 + /* Get a page frag to store the SGTable, or a full page if the errata
10902 + * is in place and we need to avoid crossing a 4k boundary.
10903 + */
10904 +#ifndef CONFIG_PPC
10905 + if (unlikely(dpaa_errata_a010022))
10906 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
10907 + else
10908 +#endif
10909 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
10910 + if (unlikely(!sgt_buf)) {
10911 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
10912 + return -ENOMEM;
10913 + }
10914 +
10915 + /* it seems that the memory allocator does not zero the allocated mem */
10916 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
10917 +
10918 + /* Enable L3/L4 hardware checksum computation.
10919 + *
10920 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
10921 + * need to write into the skb.
10922 + */
10923 + err = dpa_enable_tx_csum(priv, skb, fd,
10924 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
10925 + if (unlikely(err < 0)) {
10926 + if (netif_msg_tx_err(priv) && net_ratelimit())
10927 + netdev_err(net_dev, "HW csum error: %d\n", err);
10928 + goto csum_failed;
10929 + }
10930 +
10931 + /* Assign the data from skb->data to the first SG list entry */
10932 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
10933 + sg_len = skb_headlen(skb);
10934 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
10935 + qm_sg_entry_set_offset(&sgt[0], 0);
10936 + qm_sg_entry_set_len(&sgt[0], sg_len);
10937 + qm_sg_entry_set_ext(&sgt[0], 0);
10938 + qm_sg_entry_set_final(&sgt[0], 0);
10939 +
10940 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
10941 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
10942 + dev_err(dpa_bp->dev, "DMA mapping failed");
10943 + err = -EINVAL;
10944 + goto sg0_map_failed;
10945 + }
10946 +
10947 + qm_sg_entry_set64(&sgt[0], addr);
10948 +
10949 + /* populate the rest of SGT entries */
10950 + for (i = 1; i <= nr_frags; i++) {
10951 + frag = &skb_shinfo(skb)->frags[i - 1];
10952 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
10953 + qm_sg_entry_set_offset(&sgt[i], 0);
10954 + qm_sg_entry_set_len(&sgt[i], frag->size);
10955 + qm_sg_entry_set_ext(&sgt[i], 0);
10956 +
10957 + if (i == nr_frags)
10958 + qm_sg_entry_set_final(&sgt[i], 1);
10959 + else
10960 + qm_sg_entry_set_final(&sgt[i], 0);
10961 +
10962 + DPA_BUG_ON(!skb_frag_page(frag));
10963 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
10964 + dma_dir);
10965 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
10966 + dev_err(dpa_bp->dev, "DMA mapping failed");
10967 + err = -EINVAL;
10968 + goto sg_map_failed;
10969 + }
10970 +
10971 + /* keep the offset in the address */
10972 + qm_sg_entry_set64(&sgt[i], addr);
10973 + }
10974 +
10975 + fd->length20 = skb->len;
10976 + fd->offset = priv->tx_headroom;
10977 +
10978 + /* DMA map the SGT page
10979 + *
10980 + * It's safe to store the skb back-pointer inside the buffer since
10981 + * S/G frames are non-recyclable.
10982 + */
10983 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
10984 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
10985 + priv->tx_headroom + sgt_size,
10986 + dma_dir);
10987 +
10988 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
10989 + dev_err(dpa_bp->dev, "DMA mapping failed");
10990 + err = -EINVAL;
10991 + goto sgt_map_failed;
10992 + }
10993 +
10994 + qm_fd_addr_set64(fd, addr);
10995 + fd->bpid = 0xff;
10996 + fd->cmd |= FM_FD_CMD_FCO;
10997 +
10998 + return 0;
10999 +
11000 +sgt_map_failed:
11001 +sg_map_failed:
11002 + for (j = 0; j < i; j++) {
11003 + sg_addr = qm_sg_addr(&sgt[j]);
11004 + dma_unmap_page(dpa_bp->dev, sg_addr,
11005 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
11006 + }
11007 +sg0_map_failed:
11008 +csum_failed:
11009 + put_page(virt_to_head_page(sgt_buf));
11010 +
11011 + return err;
11012 +}
11013 +EXPORT_SYMBOL(skb_to_sg_fd);
11014 +
11015 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
11016 +{
11017 + struct dpa_priv_s *priv;
11018 + const int queue_mapping = dpa_get_queue_mapping(skb);
11019 + struct qman_fq *egress_fq, *conf_fq;
11020 +
11021 +#ifdef CONFIG_FSL_DPAA_HOOKS
11022 + /* If there is a Tx hook, run it. */
11023 + if (dpaa_eth_hooks.tx &&
11024 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
11025 + /* won't update any Tx stats */
11026 + return NETDEV_TX_OK;
11027 +#endif
11028 +
11029 + priv = netdev_priv(net_dev);
11030 +
11031 +#ifdef CONFIG_FSL_DPAA_CEETM
11032 + if (priv->ceetm_en)
11033 + return ceetm_tx(skb, net_dev);
11034 +#endif
11035 +
11036 + egress_fq = priv->egress_fqs[queue_mapping];
11037 + conf_fq = priv->conf_fqs[queue_mapping];
11038 +
11039 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
11040 +}
11041 +
11042 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
11043 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
11044 +{
11045 + struct dpa_priv_s *priv;
11046 + struct qm_fd fd;
11047 + struct dpa_percpu_priv_s *percpu_priv;
11048 + struct rtnl_link_stats64 *percpu_stats;
11049 + int err = 0;
11050 + bool nonlinear;
11051 + int *countptr, offset = 0;
11052 +
11053 + priv = netdev_priv(net_dev);
11054 + /* Non-migratable context, safe to use raw_cpu_ptr */
11055 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
11056 + percpu_stats = &percpu_priv->stats;
11057 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
11058 +
11059 + clear_fd(&fd);
11060 +
11061 +#ifndef CONFIG_PPC
11062 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
11063 + skb = a010022_realign_skb(skb, priv);
11064 + if (!skb)
11065 + goto skb_to_fd_failed;
11066 + }
11067 +#endif
11068 +
11069 + nonlinear = skb_is_nonlinear(skb);
11070 +
11071 +#ifdef CONFIG_FSL_DPAA_1588
11072 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
11073 + fd.cmd |= FM_FD_CMD_UPD;
11074 +#endif
11075 +#ifdef CONFIG_FSL_DPAA_TS
11076 + if (unlikely(priv->ts_tx_en &&
11077 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
11078 + fd.cmd |= FM_FD_CMD_UPD;
11079 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
11080 +#endif /* CONFIG_FSL_DPAA_TS */
11081 +
11082 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
11083 + * we don't feed FMan with more fragments than it supports.
11084 + * Btw, we're using the first sgt entry to store the linear part of
11085 + * the skb, so we're one extra frag short.
11086 + */
11087 + if (nonlinear &&
11088 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
11089 + /* Just create a S/G fd based on the skb */
11090 + err = skb_to_sg_fd(priv, skb, &fd);
11091 + percpu_priv->tx_frag_skbuffs++;
11092 + } else {
11093 + /* Make sure we have enough headroom to accommodate private
11094 + * data, parse results, etc. Normally this shouldn't happen if
11095 + * we're here via the standard kernel stack.
11096 + */
11097 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
11098 + struct sk_buff *skb_new;
11099 +
11100 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
11101 + if (unlikely(!skb_new)) {
11102 + dev_kfree_skb(skb);
11103 + percpu_stats->tx_errors++;
11104 + return NETDEV_TX_OK;
11105 + }
11106 +
11107 + /* propagate the skb ownership information */
11108 + if (skb->sk)
11109 + skb_set_owner_w(skb_new, skb->sk);
11110 +
11111 + dev_kfree_skb(skb);
11112 + skb = skb_new;
11113 + }
11114 +
11115 + /* We're going to store the skb backpointer at the beginning
11116 + * of the data buffer, so we need a privately owned skb
11117 + */
11118 +
11119 + /* Code borrowed from skb_unshare(). */
11120 + if (skb_cloned(skb)) {
11121 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
11122 + kfree_skb(skb);
11123 + skb = nskb;
11124 +#ifndef CONFIG_PPC
11125 + if (unlikely(dpaa_errata_a010022) &&
11126 + a010022_check_skb(skb, priv)) {
11127 + skb = a010022_realign_skb(skb, priv);
11128 + if (!skb)
11129 + goto skb_to_fd_failed;
11130 + }
11131 +#endif
11132 + /* skb_copy() has now linearized the skbuff. */
11133 + } else if (unlikely(nonlinear)) {
11134 + /* We are here because the egress skb contains
11135 + * more fragments than we support. In this case,
11136 + * we have no choice but to linearize it ourselves.
11137 + */
11138 + err = __skb_linearize(skb);
11139 + }
11140 + if (unlikely(!skb || err < 0))
11141 + /* Common out-of-memory error path */
11142 + goto enomem;
11143 +
11144 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
11145 + }
11146 + if (unlikely(err < 0))
11147 + goto skb_to_fd_failed;
11148 +
11149 + if (fd.bpid != 0xff) {
11150 + skb_recycle(skb);
11151 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
11152 + * but we need the skb to look as if returned by build_skb().
11153 + * We need to manually adjust the tailptr as well.
11154 + */
11155 + skb->data = skb->head + offset;
11156 + skb_reset_tail_pointer(skb);
11157 +
11158 + (*countptr)++;
11159 + percpu_priv->tx_returned++;
11160 + }
11161 +
11162 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
11163 + goto xmit_failed;
11164 +
11165 + netif_trans_update(net_dev);
11166 + return NETDEV_TX_OK;
11167 +
11168 +xmit_failed:
11169 + if (fd.bpid != 0xff) {
11170 + (*countptr)--;
11171 + percpu_priv->tx_returned--;
11172 + dpa_fd_release(net_dev, &fd);
11173 + percpu_stats->tx_errors++;
11174 + return NETDEV_TX_OK;
11175 + }
11176 + _dpa_cleanup_tx_fd(priv, &fd);
11177 +skb_to_fd_failed:
11178 +enomem:
11179 + percpu_stats->tx_errors++;
11180 + dev_kfree_skb(skb);
11181 + return NETDEV_TX_OK;
11182 +}
11183 +EXPORT_SYMBOL(dpa_tx_extended);
11184 --- /dev/null
11185 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
11186 @@ -0,0 +1,278 @@
11187 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
11188 + *
11189 + * Redistribution and use in source and binary forms, with or without
11190 + * modification, are permitted provided that the following conditions are met:
11191 + * * Redistributions of source code must retain the above copyright
11192 + * notice, this list of conditions and the following disclaimer.
11193 + * * Redistributions in binary form must reproduce the above copyright
11194 + * notice, this list of conditions and the following disclaimer in the
11195 + * documentation and/or other materials provided with the distribution.
11196 + * * Neither the name of Freescale Semiconductor nor the
11197 + * names of its contributors may be used to endorse or promote products
11198 + * derived from this software without specific prior written permission.
11199 + *
11200 + *
11201 + * ALTERNATIVELY, this software may be distributed under the terms of the
11202 + * GNU General Public License ("GPL") as published by the Free Software
11203 + * Foundation, either version 2 of that License or (at your option) any
11204 + * later version.
11205 + *
11206 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11207 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11208 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11209 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11210 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11211 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11212 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11213 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11214 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11215 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11216 + */
11217 +
11218 +#include <linux/init.h>
11219 +#include <linux/module.h>
11220 +#include <linux/kthread.h>
11221 +#include <linux/io.h>
11222 +#include <linux/of_net.h>
11223 +#include "dpaa_eth.h"
11224 +#include "mac.h" /* struct mac_device */
11225 +#ifdef CONFIG_FSL_DPAA_1588
11226 +#include "dpaa_1588.h"
11227 +#endif
11228 +
11229 +static ssize_t dpaa_eth_show_addr(struct device *dev,
11230 + struct device_attribute *attr, char *buf)
11231 +{
11232 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11233 + struct mac_device *mac_dev = priv->mac_dev;
11234 +
11235 + if (mac_dev)
11236 + return sprintf(buf, "%llx",
11237 + (unsigned long long)mac_dev->res->start);
11238 + else
11239 + return sprintf(buf, "none");
11240 +}
11241 +
11242 +static ssize_t dpaa_eth_show_type(struct device *dev,
11243 + struct device_attribute *attr, char *buf)
11244 +{
11245 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11246 + ssize_t res = 0;
11247 +
11248 + if (priv)
11249 + res = sprintf(buf, "%s", priv->if_type);
11250 +
11251 + return res;
11252 +}
11253 +
11254 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
11255 + struct device_attribute *attr, char *buf)
11256 +{
11257 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11258 + ssize_t bytes = 0;
11259 + int i = 0;
11260 + char *str;
11261 + struct dpa_fq *fq;
11262 + struct dpa_fq *tmp;
11263 + struct dpa_fq *prev = NULL;
11264 + u32 first_fqid = 0;
11265 + u32 last_fqid = 0;
11266 + char *prevstr = NULL;
11267 +
11268 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
11269 + switch (fq->fq_type) {
11270 + case FQ_TYPE_RX_DEFAULT:
11271 + str = "Rx default";
11272 + break;
11273 + case FQ_TYPE_RX_ERROR:
11274 + str = "Rx error";
11275 + break;
11276 + case FQ_TYPE_RX_PCD:
11277 + str = "Rx PCD";
11278 + break;
11279 + case FQ_TYPE_TX_CONFIRM:
11280 + str = "Tx default confirmation";
11281 + break;
11282 + case FQ_TYPE_TX_CONF_MQ:
11283 + str = "Tx confirmation (mq)";
11284 + break;
11285 + case FQ_TYPE_TX_ERROR:
11286 + str = "Tx error";
11287 + break;
11288 + case FQ_TYPE_TX:
11289 + str = "Tx";
11290 + break;
11291 + case FQ_TYPE_RX_PCD_HI_PRIO:
11292 + str ="Rx PCD High Priority";
11293 + break;
11294 + default:
11295 + str = "Unknown";
11296 + }
11297 +
11298 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
11299 + str != prevstr)) {
11300 + if (last_fqid == first_fqid)
11301 + bytes += sprintf(buf + bytes,
11302 + "%s: %d\n", prevstr, prev->fqid);
11303 + else
11304 + bytes += sprintf(buf + bytes,
11305 + "%s: %d - %d\n", prevstr,
11306 + first_fqid, last_fqid);
11307 + }
11308 +
11309 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
11310 + last_fqid = fq->fqid;
11311 + else
11312 + first_fqid = last_fqid = fq->fqid;
11313 +
11314 + prev = fq;
11315 + prevstr = str;
11316 + i++;
11317 + }
11318 +
11319 + if (prev) {
11320 + if (last_fqid == first_fqid)
11321 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
11322 + prev->fqid);
11323 + else
11324 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
11325 + first_fqid, last_fqid);
11326 + }
11327 +
11328 + return bytes;
11329 +}
11330 +
11331 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
11332 + struct device_attribute *attr, char *buf)
11333 +{
11334 + ssize_t bytes = 0;
11335 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11336 + struct dpa_bp *dpa_bp = priv->dpa_bp;
11337 + int i = 0;
11338 +
11339 + for (i = 0; i < priv->bp_count; i++)
11340 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
11341 + dpa_bp[i].bpid);
11342 +
11343 + return bytes;
11344 +}
11345 +
11346 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
11347 + struct device_attribute *attr, char *buf)
11348 +{
11349 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11350 + struct mac_device *mac_dev = priv->mac_dev;
11351 + int n = 0;
11352 +
11353 + if (mac_dev)
11354 + n = fm_mac_dump_regs(mac_dev, buf, n);
11355 + else
11356 + return sprintf(buf, "no mac registers\n");
11357 +
11358 + return n;
11359 +}
11360 +
11361 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
11362 + struct device_attribute *attr, char *buf)
11363 +{
11364 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11365 + struct mac_device *mac_dev = priv->mac_dev;
11366 + int n = 0;
11367 +
11368 + if (mac_dev)
11369 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
11370 + else
11371 + return sprintf(buf, "no mac rx stats\n");
11372 +
11373 + return n;
11374 +}
11375 +
11376 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
11377 + struct device_attribute *attr, char *buf)
11378 +{
11379 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11380 + struct mac_device *mac_dev = priv->mac_dev;
11381 + int n = 0;
11382 +
11383 + if (mac_dev)
11384 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
11385 + else
11386 + return sprintf(buf, "no mac tx stats\n");
11387 +
11388 + return n;
11389 +}
11390 +
11391 +#ifdef CONFIG_FSL_DPAA_1588
11392 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
11393 + struct device_attribute *attr, char *buf)
11394 +{
11395 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11396 +
11397 + if (priv->tsu && priv->tsu->valid)
11398 + return sprintf(buf, "1\n");
11399 + else
11400 + return sprintf(buf, "0\n");
11401 +}
11402 +
11403 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
11404 + struct device_attribute *attr,
11405 + const char *buf, size_t count)
11406 +{
11407 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11408 + unsigned int num;
11409 + unsigned long flags;
11410 +
11411 + if (kstrtouint(buf, 0, &num) < 0)
11412 + return -EINVAL;
11413 +
11414 + local_irq_save(flags);
11415 +
11416 + if (num) {
11417 + if (priv->tsu)
11418 + priv->tsu->valid = TRUE;
11419 + } else {
11420 + if (priv->tsu)
11421 + priv->tsu->valid = FALSE;
11422 + }
11423 +
11424 + local_irq_restore(flags);
11425 +
11426 + return count;
11427 +}
11428 +#endif
11429 +
11430 +static struct device_attribute dpaa_eth_attrs[] = {
11431 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
11432 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
11433 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
11434 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
11435 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
11436 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
11437 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
11438 +#ifdef CONFIG_FSL_DPAA_1588
11439 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
11440 + dpaa_eth_set_ptp_1588),
11441 +#endif
11442 +};
11443 +
11444 +void dpaa_eth_sysfs_init(struct device *dev)
11445 +{
11446 + int i;
11447 +
11448 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
11449 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
11450 + dev_err(dev, "Error creating sysfs file\n");
11451 + while (i > 0)
11452 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
11453 + return;
11454 + }
11455 +}
11456 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
11457 +
11458 +void dpaa_eth_sysfs_remove(struct device *dev)
11459 +{
11460 + int i;
11461 +
11462 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
11463 + device_remove_file(dev, &dpaa_eth_attrs[i]);
11464 +}
11465 --- /dev/null
11466 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
11467 @@ -0,0 +1,144 @@
11468 +/* Copyright 2013 Freescale Semiconductor Inc.
11469 + *
11470 + * Redistribution and use in source and binary forms, with or without
11471 + * modification, are permitted provided that the following conditions are met:
11472 + * * Redistributions of source code must retain the above copyright
11473 + * notice, this list of conditions and the following disclaimer.
11474 + * * Redistributions in binary form must reproduce the above copyright
11475 + * notice, this list of conditions and the following disclaimer in the
11476 + * documentation and/or other materials provided with the distribution.
11477 + * * Neither the name of Freescale Semiconductor nor the
11478 + * names of its contributors may be used to endorse or promote products
11479 + * derived from this software without specific prior written permission.
11480 + *
11481 + *
11482 + * ALTERNATIVELY, this software may be distributed under the terms of the
11483 + * GNU General Public License ("GPL") as published by the Free Software
11484 + * Foundation, either version 2 of that License or (at your option) any
11485 + * later version.
11486 + *
11487 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11488 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11489 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11490 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11491 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11492 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11493 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11494 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11495 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11496 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11497 + */
11498 +
11499 +#undef TRACE_SYSTEM
11500 +#define TRACE_SYSTEM dpaa_eth
11501 +
11502 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
11503 +#define _DPAA_ETH_TRACE_H
11504 +
11505 +#include <linux/skbuff.h>
11506 +#include <linux/netdevice.h>
11507 +#include "dpaa_eth.h"
11508 +#include <linux/tracepoint.h>
11509 +
11510 +#define fd_format_name(format) { qm_fd_##format, #format }
11511 +#define fd_format_list \
11512 + fd_format_name(contig), \
11513 + fd_format_name(sg)
11514 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
11515 + " status=0x%08x"
11516 +
11517 +/* This is used to declare a class of events.
11518 + * individual events of this type will be defined below.
11519 + */
11520 +
11521 +/* Store details about a frame descriptor and the FQ on which it was
11522 + * transmitted/received.
11523 + */
11524 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
11525 + /* Trace function prototype */
11526 + TP_PROTO(struct net_device *netdev,
11527 + struct qman_fq *fq,
11528 + const struct qm_fd *fd),
11529 +
11530 + /* Repeat argument list here */
11531 + TP_ARGS(netdev, fq, fd),
11532 +
11533 + /* A structure containing the relevant information we want to record.
11534 + * Declare name and type for each normal element, name, type and size
11535 + * for arrays. Use __string for variable length strings.
11536 + */
11537 + TP_STRUCT__entry(
11538 + __field(u32, fqid)
11539 + __field(u64, fd_addr)
11540 + __field(u8, fd_format)
11541 + __field(u16, fd_offset)
11542 + __field(u32, fd_length)
11543 + __field(u32, fd_status)
11544 + __string(name, netdev->name)
11545 + ),
11546 +
11547 + /* The function that assigns values to the above declared fields */
11548 + TP_fast_assign(
11549 + __entry->fqid = fq->fqid;
11550 + __entry->fd_addr = qm_fd_addr_get64(fd);
11551 + __entry->fd_format = fd->format;
11552 + __entry->fd_offset = dpa_fd_offset(fd);
11553 + __entry->fd_length = dpa_fd_length(fd);
11554 + __entry->fd_status = fd->status;
11555 + __assign_str(name, netdev->name);
11556 + ),
11557 +
11558 + /* This is what gets printed when the trace event is triggered */
11559 + /* TODO: print the status using __print_flags() */
11560 + TP_printk(TR_FMT,
11561 + __get_str(name), __entry->fqid, __entry->fd_addr,
11562 + __print_symbolic(__entry->fd_format, fd_format_list),
11563 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
11564 +);
11565 +
11566 +/* Now declare events of the above type. Format is:
11567 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
11568 + */
11569 +
11570 +/* Tx (egress) fd */
11571 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
11572 +
11573 + TP_PROTO(struct net_device *netdev,
11574 + struct qman_fq *fq,
11575 + const struct qm_fd *fd),
11576 +
11577 + TP_ARGS(netdev, fq, fd)
11578 +);
11579 +
11580 +/* Rx fd */
11581 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
11582 +
11583 + TP_PROTO(struct net_device *netdev,
11584 + struct qman_fq *fq,
11585 + const struct qm_fd *fd),
11586 +
11587 + TP_ARGS(netdev, fq, fd)
11588 +);
11589 +
11590 +/* Tx confirmation fd */
11591 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
11592 +
11593 + TP_PROTO(struct net_device *netdev,
11594 + struct qman_fq *fq,
11595 + const struct qm_fd *fd),
11596 +
11597 + TP_ARGS(netdev, fq, fd)
11598 +);
11599 +
11600 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
11601 + * The syntax is the same as for DECLARE_EVENT_CLASS().
11602 + */
11603 +
11604 +#endif /* _DPAA_ETH_TRACE_H */
11605 +
11606 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
11607 +#undef TRACE_INCLUDE_PATH
11608 +#define TRACE_INCLUDE_PATH .
11609 +#undef TRACE_INCLUDE_FILE
11610 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
11611 +#include <trace/define_trace.h>
11612 --- /dev/null
11613 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
11614 @@ -0,0 +1,542 @@
11615 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11616 + *
11617 + * Redistribution and use in source and binary forms, with or without
11618 + * modification, are permitted provided that the following conditions are met:
11619 + * * Redistributions of source code must retain the above copyright
11620 + * notice, this list of conditions and the following disclaimer.
11621 + * * Redistributions in binary form must reproduce the above copyright
11622 + * notice, this list of conditions and the following disclaimer in the
11623 + * documentation and/or other materials provided with the distribution.
11624 + * * Neither the name of Freescale Semiconductor nor the
11625 + * names of its contributors may be used to endorse or promote products
11626 + * derived from this software without specific prior written permission.
11627 + *
11628 + *
11629 + * ALTERNATIVELY, this software may be distributed under the terms of the
11630 + * GNU General Public License ("GPL") as published by the Free Software
11631 + * Foundation, either version 2 of that License or (at your option) any
11632 + * later version.
11633 + *
11634 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11635 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11636 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11637 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11638 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11639 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11640 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11641 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11642 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11643 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11644 + */
11645 +
11646 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11647 +#define pr_fmt(fmt) \
11648 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11649 + KBUILD_BASENAME".c", __LINE__, __func__
11650 +#else
11651 +#define pr_fmt(fmt) \
11652 + KBUILD_MODNAME ": " fmt
11653 +#endif
11654 +
11655 +#include <linux/string.h>
11656 +
11657 +#include "dpaa_eth.h"
11658 +#include "mac.h" /* struct mac_device */
11659 +#include "dpaa_eth_common.h"
11660 +
11661 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
11662 + "interrupts",
11663 + "rx packets",
11664 + "tx packets",
11665 + "tx recycled",
11666 + "tx confirm",
11667 + "tx S/G",
11668 + "rx S/G",
11669 + "tx error",
11670 + "rx error",
11671 + "bp count"
11672 +};
11673 +
11674 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
11675 + /* dpa rx errors */
11676 + "rx dma error",
11677 + "rx frame physical error",
11678 + "rx frame size error",
11679 + "rx header error",
11680 + "rx csum error",
11681 +
11682 + /* demultiplexing errors */
11683 + "qman cg_tdrop",
11684 + "qman wred",
11685 + "qman error cond",
11686 + "qman early window",
11687 + "qman late window",
11688 + "qman fq tdrop",
11689 + "qman fq retired",
11690 + "qman orp disabled",
11691 +
11692 + /* congestion related stats */
11693 + "congestion time (ms)",
11694 + "entered congestion",
11695 + "congested (0/1)"
11696 +};
11697 +
11698 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
11699 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
11700 +
11701 +static int __cold dpa_get_ksettings(struct net_device *net_dev,
11702 + struct ethtool_link_ksettings *cmd)
11703 +{
11704 + int _errno;
11705 + struct dpa_priv_s *priv;
11706 +
11707 + priv = netdev_priv(net_dev);
11708 +
11709 + if (priv->mac_dev == NULL) {
11710 + netdev_info(net_dev, "This is a MAC-less interface\n");
11711 + return -ENODEV;
11712 + }
11713 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
11714 + netdev_dbg(net_dev, "phy device not initialized\n");
11715 + return 0;
11716 + }
11717 +
11718 + phy_ethtool_ksettings_get(priv->mac_dev->phy_dev, cmd);
11719 +
11720 + return _errno;
11721 +}
11722 +
11723 +static int __cold dpa_set_ksettings(struct net_device *net_dev,
11724 + const struct ethtool_link_ksettings *cmd)
11725 +{
11726 + int _errno;
11727 + struct dpa_priv_s *priv;
11728 +
11729 + priv = netdev_priv(net_dev);
11730 +
11731 + if (priv->mac_dev == NULL) {
11732 + netdev_info(net_dev, "This is a MAC-less interface\n");
11733 + return -ENODEV;
11734 + }
11735 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
11736 + netdev_err(net_dev, "phy device not initialized\n");
11737 + return -ENODEV;
11738 + }
11739 +
11740 + _errno = phy_ethtool_ksettings_set(priv->mac_dev->phy_dev, cmd);
11741 + if (unlikely(_errno < 0))
11742 + netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", _errno);
11743 +
11744 + return _errno;
11745 +}
11746 +
11747 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
11748 + struct ethtool_drvinfo *drvinfo)
11749 +{
11750 + int _errno;
11751 +
11752 + strncpy(drvinfo->driver, KBUILD_MODNAME,
11753 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
11754 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
11755 + "%X", 0);
11756 +
11757 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
11758 + /* Truncated output */
11759 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
11760 + } else if (unlikely(_errno < 0)) {
11761 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
11762 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
11763 + }
11764 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
11765 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
11766 +}
11767 +
11768 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
11769 +{
11770 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
11771 +}
11772 +
11773 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
11774 + uint32_t msg_enable)
11775 +{
11776 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
11777 +}
11778 +
11779 +static int __cold dpa_nway_reset(struct net_device *net_dev)
11780 +{
11781 + int _errno;
11782 + struct dpa_priv_s *priv;
11783 +
11784 + priv = netdev_priv(net_dev);
11785 +
11786 + if (priv->mac_dev == NULL) {
11787 + netdev_info(net_dev, "This is a MAC-less interface\n");
11788 + return -ENODEV;
11789 + }
11790 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
11791 + netdev_err(net_dev, "phy device not initialized\n");
11792 + return -ENODEV;
11793 + }
11794 +
11795 + _errno = 0;
11796 + if (priv->mac_dev->phy_dev->autoneg) {
11797 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
11798 + if (unlikely(_errno < 0))
11799 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
11800 + _errno);
11801 + }
11802 +
11803 + return _errno;
11804 +}
11805 +
11806 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
11807 + struct ethtool_pauseparam *epause)
11808 +{
11809 + struct dpa_priv_s *priv;
11810 + struct mac_device *mac_dev;
11811 + struct phy_device *phy_dev;
11812 +
11813 + priv = netdev_priv(net_dev);
11814 + mac_dev = priv->mac_dev;
11815 +
11816 + if (mac_dev == NULL) {
11817 + netdev_info(net_dev, "This is a MAC-less interface\n");
11818 + return;
11819 + }
11820 +
11821 + phy_dev = mac_dev->phy_dev;
11822 + if (unlikely(phy_dev == NULL)) {
11823 + netdev_err(net_dev, "phy device not initialized\n");
11824 + return;
11825 + }
11826 +
11827 + epause->autoneg = mac_dev->autoneg_pause;
11828 + epause->rx_pause = mac_dev->rx_pause_active;
11829 + epause->tx_pause = mac_dev->tx_pause_active;
11830 +}
11831 +
11832 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
11833 + struct ethtool_pauseparam *epause)
11834 +{
11835 + struct dpa_priv_s *priv;
11836 + struct mac_device *mac_dev;
11837 + struct phy_device *phy_dev;
11838 + int _errno;
11839 + u32 newadv, oldadv;
11840 + bool rx_pause, tx_pause;
11841 +
11842 + priv = netdev_priv(net_dev);
11843 + mac_dev = priv->mac_dev;
11844 +
11845 + if (mac_dev == NULL) {
11846 + netdev_info(net_dev, "This is a MAC-less interface\n");
11847 + return -ENODEV;
11848 + }
11849 +
11850 + phy_dev = mac_dev->phy_dev;
11851 + if (unlikely(phy_dev == NULL)) {
11852 + netdev_err(net_dev, "phy device not initialized\n");
11853 + return -ENODEV;
11854 + }
11855 +
11856 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
11857 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
11858 + (epause->rx_pause != epause->tx_pause)))
11859 + return -EINVAL;
11860 +
11861 + /* The MAC should know how to handle PAUSE frame autonegotiation before
11862 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
11863 + * settings.
11864 + */
11865 + mac_dev->autoneg_pause = !!epause->autoneg;
11866 + mac_dev->rx_pause_req = !!epause->rx_pause;
11867 + mac_dev->tx_pause_req = !!epause->tx_pause;
11868 +
11869 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
11870 + * rx/tx pause settings.
11871 + */
11872 + newadv = 0;
11873 + if (epause->rx_pause)
11874 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
11875 + if (epause->tx_pause)
11876 + newadv |= ADVERTISED_Asym_Pause;
11877 +
11878 + oldadv = phy_dev->advertising &
11879 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
11880 +
11881 + /* If there are differences between the old and the new advertised
11882 + * values, restart PHY autonegotiation and advertise the new values.
11883 + */
11884 + if (oldadv != newadv) {
11885 + phy_dev->advertising &= ~(ADVERTISED_Pause
11886 + | ADVERTISED_Asym_Pause);
11887 + phy_dev->advertising |= newadv;
11888 + if (phy_dev->autoneg) {
11889 + _errno = phy_start_aneg(phy_dev);
11890 + if (unlikely(_errno < 0))
11891 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
11892 + _errno);
11893 + }
11894 + }
11895 +
11896 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11897 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11898 + if (unlikely(_errno < 0))
11899 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11900 +
11901 + return _errno;
11902 +}
11903 +
11904 +#ifdef CONFIG_PM
11905 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
11906 +{
11907 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11908 +
11909 + wol->supported = 0;
11910 + wol->wolopts = 0;
11911 +
11912 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
11913 + return;
11914 +
11915 + if (priv->wol & DPAA_WOL_MAGIC) {
11916 + wol->supported = WAKE_MAGIC;
11917 + wol->wolopts = WAKE_MAGIC;
11918 + }
11919 +}
11920 +
11921 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
11922 +{
11923 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11924 +
11925 + if (priv->mac_dev == NULL) {
11926 + netdev_info(net_dev, "This is a MAC-less interface\n");
11927 + return -ENODEV;
11928 + }
11929 +
11930 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
11931 + netdev_dbg(net_dev, "phy device not initialized\n");
11932 + return -ENODEV;
11933 + }
11934 +
11935 + if (!device_can_wakeup(net_dev->dev.parent) ||
11936 + (wol->wolopts & ~WAKE_MAGIC))
11937 + return -EOPNOTSUPP;
11938 +
11939 + priv->wol = 0;
11940 +
11941 + if (wol->wolopts & WAKE_MAGIC) {
11942 + priv->wol = DPAA_WOL_MAGIC;
11943 + device_set_wakeup_enable(net_dev->dev.parent, 1);
11944 + } else {
11945 + device_set_wakeup_enable(net_dev->dev.parent, 0);
11946 + }
11947 +
11948 + return 0;
11949 +}
11950 +#endif
11951 +
11952 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
11953 +{
11954 + struct dpa_priv_s *priv;
11955 +
11956 + priv = netdev_priv(net_dev);
11957 + if (priv->mac_dev == NULL) {
11958 + netdev_info(net_dev, "This is a MAC-less interface\n");
11959 + return -ENODEV;
11960 + }
11961 +
11962 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
11963 + netdev_err(net_dev, "phy device not initialized\n");
11964 + return -ENODEV;
11965 + }
11966 +
11967 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
11968 +}
11969 +
11970 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
11971 +{
11972 + struct dpa_priv_s *priv;
11973 +
11974 + priv = netdev_priv(net_dev);
11975 + if (priv->mac_dev == NULL) {
11976 + netdev_info(net_dev, "This is a MAC-less interface\n");
11977 + return -ENODEV;
11978 + }
11979 +
11980 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
11981 + netdev_err(net_dev, "phy device not initialized\n");
11982 + return -ENODEV;
11983 + }
11984 +
11985 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
11986 +}
11987 +
11988 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
11989 +{
11990 + unsigned int total_stats, num_stats;
11991 +
11992 + num_stats = num_online_cpus() + 1;
11993 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
11994 +
11995 + switch (type) {
11996 + case ETH_SS_STATS:
11997 + return total_stats;
11998 + default:
11999 + return -EOPNOTSUPP;
12000 + }
12001 +}
12002 +
12003 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
12004 + int crr_cpu, u64 bp_count, u64 *data)
12005 +{
12006 + int num_stat_values = num_cpus + 1;
12007 + int crr_stat = 0;
12008 +
12009 + /* update current CPU's stats and also add them to the total values */
12010 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
12011 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
12012 +
12013 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
12014 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
12015 +
12016 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
12017 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
12018 +
12019 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
12020 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
12021 +
12022 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
12023 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
12024 +
12025 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
12026 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
12027 +
12028 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
12029 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
12030 +
12031 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
12032 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
12033 +
12034 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
12035 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
12036 +
12037 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
12038 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
12039 +}
12040 +
12041 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
12042 + struct ethtool_stats *stats, u64 *data)
12043 +{
12044 + u64 bp_count, cg_time, cg_num, cg_status;
12045 + struct dpa_percpu_priv_s *percpu_priv;
12046 + struct qm_mcr_querycgr query_cgr;
12047 + struct dpa_rx_errors rx_errors;
12048 + struct dpa_ern_cnt ern_cnt;
12049 + struct dpa_priv_s *priv;
12050 + unsigned int num_cpus, offset;
12051 + struct dpa_bp *dpa_bp;
12052 + int total_stats, i;
12053 +
12054 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
12055 + priv = netdev_priv(net_dev);
12056 + dpa_bp = priv->dpa_bp;
12057 + num_cpus = num_online_cpus();
12058 + bp_count = 0;
12059 +
12060 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
12061 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
12062 + memset(data, 0, total_stats * sizeof(u64));
12063 +
12064 + for_each_online_cpu(i) {
12065 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
12066 +
12067 + if (dpa_bp->percpu_count)
12068 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
12069 +
12070 + rx_errors.dme += percpu_priv->rx_errors.dme;
12071 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
12072 + rx_errors.fse += percpu_priv->rx_errors.fse;
12073 + rx_errors.phe += percpu_priv->rx_errors.phe;
12074 + rx_errors.cse += percpu_priv->rx_errors.cse;
12075 +
12076 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
12077 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
12078 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
12079 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
12080 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
12081 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
12082 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
12083 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
12084 +
12085 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
12086 + }
12087 +
12088 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
12089 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
12090 +
12091 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
12092 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
12093 +
12094 + /* gather congestion related counters */
12095 + cg_num = 0;
12096 + cg_status = 0;
12097 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
12098 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
12099 + cg_num = priv->cgr_data.cgr_congested_count;
12100 + cg_status = query_cgr.cgr.cs;
12101 +
12102 + /* reset congestion stats (like QMan API does */
12103 + priv->cgr_data.congested_jiffies = 0;
12104 + priv->cgr_data.cgr_congested_count = 0;
12105 + }
12106 +
12107 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
12108 + data[offset++] = cg_time;
12109 + data[offset++] = cg_num;
12110 + data[offset++] = cg_status;
12111 +}
12112 +
12113 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
12114 +{
12115 + unsigned int i, j, num_cpus, size;
12116 + char stat_string_cpu[ETH_GSTRING_LEN];
12117 + u8 *strings;
12118 +
12119 + strings = data;
12120 + num_cpus = num_online_cpus();
12121 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
12122 +
12123 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
12124 + for (j = 0; j < num_cpus; j++) {
12125 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
12126 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
12127 + strings += ETH_GSTRING_LEN;
12128 + }
12129 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
12130 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
12131 + strings += ETH_GSTRING_LEN;
12132 + }
12133 + memcpy(strings, dpa_stats_global, size);
12134 +}
12135 +
12136 +const struct ethtool_ops dpa_ethtool_ops = {
12137 + .get_link_ksettings = dpa_get_ksettings,
12138 + .set_link_ksettings = dpa_set_ksettings,
12139 + .get_drvinfo = dpa_get_drvinfo,
12140 + .get_msglevel = dpa_get_msglevel,
12141 + .set_msglevel = dpa_set_msglevel,
12142 + .nway_reset = dpa_nway_reset,
12143 + .get_pauseparam = dpa_get_pauseparam,
12144 + .set_pauseparam = dpa_set_pauseparam,
12145 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
12146 + .get_link = ethtool_op_get_link,
12147 + .get_eee = dpa_get_eee,
12148 + .set_eee = dpa_set_eee,
12149 + .get_sset_count = dpa_get_sset_count,
12150 + .get_ethtool_stats = dpa_get_ethtool_stats,
12151 + .get_strings = dpa_get_strings,
12152 +#ifdef CONFIG_PM
12153 + .get_wol = dpa_get_wol,
12154 + .set_wol = dpa_set_wol,
12155 +#endif
12156 +};
12157 --- /dev/null
12158 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
12159 @@ -0,0 +1,291 @@
12160 +/*
12161 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
12162 + *
12163 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
12164 + *
12165 + * Copyright 2014 Freescale Semiconductor, Inc.
12166 + *
12167 + * This program is free software; you can redistribute it and/or modify it
12168 + * under the terms of the GNU General Public License as published by the
12169 + * Free Software Foundation; either version 2 of the License, or (at your
12170 + * option) any later version.
12171 +*/
12172 +
12173 +#include <linux/device.h>
12174 +#include <linux/hrtimer.h>
12175 +#include <linux/init.h>
12176 +#include <linux/interrupt.h>
12177 +#include <linux/kernel.h>
12178 +#include <linux/module.h>
12179 +#include <linux/of.h>
12180 +#include <linux/of_platform.h>
12181 +#include <linux/timex.h>
12182 +#include <linux/io.h>
12183 +
12184 +#include <linux/ptp_clock_kernel.h>
12185 +
12186 +#include "dpaa_eth.h"
12187 +#include "mac.h"
12188 +
12189 +static struct mac_device *mac_dev;
12190 +static u32 freqCompensation;
12191 +
12192 +/* Bit definitions for the TMR_CTRL register */
12193 +#define ALM1P (1<<31) /* Alarm1 output polarity */
12194 +#define ALM2P (1<<30) /* Alarm2 output polarity */
12195 +#define FS (1<<28) /* FIPER start indication */
12196 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
12197 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
12198 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
12199 +#define TCLK_PERIOD_MASK (0x3ff)
12200 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
12201 +#define FRD (1<<14) /* FIPER Realignment Disable */
12202 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
12203 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
12204 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
12205 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
12206 +#define COPH (1<<7) /* Generated clock output phase. */
12207 +#define CIPH (1<<6) /* External oscillator input clock phase */
12208 +#define TMSR (1<<5) /* Timer soft reset. */
12209 +#define BYP (1<<3) /* Bypass drift compensated clock */
12210 +#define TE (1<<2) /* 1588 timer enable. */
12211 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
12212 +#define CKSEL_MASK (0x3)
12213 +
12214 +/* Bit definitions for the TMR_TEVENT register */
12215 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
12216 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
12217 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
12218 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
12219 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
12220 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
12221 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
12222 +
12223 +/* Bit definitions for the TMR_TEMASK register */
12224 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
12225 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
12226 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
12227 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
12228 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
12229 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
12230 +
12231 +/* Bit definitions for the TMR_PEVENT register */
12232 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
12233 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
12234 +#define RXP (1<<0) /* PTP frame has been received */
12235 +
12236 +/* Bit definitions for the TMR_PEMASK register */
12237 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
12238 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
12239 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
12240 +
12241 +/* Bit definitions for the TMR_STAT register */
12242 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
12243 +#define STAT_VEC_MASK (0x3f)
12244 +
12245 +/* Bit definitions for the TMR_PRSC register */
12246 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
12247 +#define PRSC_OCK_MASK (0xffff)
12248 +
12249 +
12250 +#define N_EXT_TS 2
12251 +
12252 +static void set_alarm(void)
12253 +{
12254 + u64 ns;
12255 +
12256 + if (mac_dev->fm_rtc_get_cnt)
12257 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
12258 + ns += 1500000000ULL;
12259 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
12260 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
12261 + if (mac_dev->fm_rtc_set_alarm)
12262 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
12263 +}
12264 +
12265 +static void set_fipers(void)
12266 +{
12267 + u64 fiper;
12268 +
12269 + if (mac_dev->fm_rtc_disable)
12270 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
12271 +
12272 + set_alarm();
12273 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
12274 + if (mac_dev->fm_rtc_set_fiper)
12275 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
12276 +
12277 + if (mac_dev->fm_rtc_enable)
12278 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
12279 +}
12280 +
12281 +/* PTP clock operations */
12282 +
12283 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
12284 +{
12285 + u64 adj;
12286 + u32 diff, tmr_add;
12287 + int neg_adj = 0;
12288 +
12289 + if (ppb < 0) {
12290 + neg_adj = 1;
12291 + ppb = -ppb;
12292 + }
12293 +
12294 + tmr_add = freqCompensation;
12295 + adj = tmr_add;
12296 + adj *= ppb;
12297 + diff = div_u64(adj, 1000000000ULL);
12298 +
12299 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
12300 +
12301 + if (mac_dev->fm_rtc_set_drift)
12302 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
12303 +
12304 + return 0;
12305 +}
12306 +
12307 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
12308 +{
12309 + s64 now;
12310 +
12311 + if (mac_dev->fm_rtc_get_cnt)
12312 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
12313 +
12314 + now += delta;
12315 +
12316 + if (mac_dev->fm_rtc_set_cnt)
12317 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
12318 + set_fipers();
12319 +
12320 + return 0;
12321 +}
12322 +
12323 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
12324 +{
12325 + u64 ns;
12326 + u32 remainder;
12327 +
12328 + if (mac_dev->fm_rtc_get_cnt)
12329 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
12330 +
12331 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
12332 + ts->tv_nsec = remainder;
12333 + return 0;
12334 +}
12335 +
12336 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
12337 + const struct timespec64 *ts)
12338 +{
12339 + u64 ns;
12340 +
12341 + ns = ts->tv_sec * 1000000000ULL;
12342 + ns += ts->tv_nsec;
12343 +
12344 + if (mac_dev->fm_rtc_set_cnt)
12345 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
12346 + set_fipers();
12347 + return 0;
12348 +}
12349 +
12350 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
12351 + struct ptp_clock_request *rq, int on)
12352 +{
12353 + u32 bit;
12354 +
12355 + switch (rq->type) {
12356 + case PTP_CLK_REQ_EXTTS:
12357 + switch (rq->extts.index) {
12358 + case 0:
12359 + bit = ETS1EN;
12360 + break;
12361 + case 1:
12362 + bit = ETS2EN;
12363 + break;
12364 + default:
12365 + return -EINVAL;
12366 + }
12367 + if (on) {
12368 + if (mac_dev->fm_rtc_enable_interrupt)
12369 + mac_dev->fm_rtc_enable_interrupt(
12370 + mac_dev->fm_dev, bit);
12371 + } else {
12372 + if (mac_dev->fm_rtc_disable_interrupt)
12373 + mac_dev->fm_rtc_disable_interrupt(
12374 + mac_dev->fm_dev, bit);
12375 + }
12376 + return 0;
12377 +
12378 + case PTP_CLK_REQ_PPS:
12379 + if (on) {
12380 + if (mac_dev->fm_rtc_enable_interrupt)
12381 + mac_dev->fm_rtc_enable_interrupt(
12382 + mac_dev->fm_dev, PP1EN);
12383 + } else {
12384 + if (mac_dev->fm_rtc_disable_interrupt)
12385 + mac_dev->fm_rtc_disable_interrupt(
12386 + mac_dev->fm_dev, PP1EN);
12387 + }
12388 + return 0;
12389 +
12390 + default:
12391 + break;
12392 + }
12393 +
12394 + return -EOPNOTSUPP;
12395 +}
12396 +
12397 +static struct ptp_clock_info ptp_dpa_caps = {
12398 + .owner = THIS_MODULE,
12399 + .name = "dpaa clock",
12400 + .max_adj = 512000,
12401 + .n_alarm = 0,
12402 + .n_ext_ts = N_EXT_TS,
12403 + .n_per_out = 0,
12404 + .pps = 1,
12405 + .adjfreq = ptp_dpa_adjfreq,
12406 + .adjtime = ptp_dpa_adjtime,
12407 + .gettime64 = ptp_dpa_gettime,
12408 + .settime64 = ptp_dpa_settime,
12409 + .enable = ptp_dpa_enable,
12410 +};
12411 +
12412 +static int __init __cold dpa_ptp_load(void)
12413 +{
12414 + struct device *ptp_dev;
12415 + struct timespec64 now;
12416 + struct ptp_clock *clock = ptp_priv.clock;
12417 + int dpa_phc_index;
12418 + int err;
12419 +
12420 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
12421 + return -ENODEV;
12422 +
12423 + ptp_dev = &ptp_priv.of_dev->dev;
12424 + mac_dev = ptp_priv.mac_dev;
12425 +
12426 + if (mac_dev->fm_rtc_get_drift)
12427 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
12428 +
12429 + getnstimeofday64(&now);
12430 + ptp_dpa_settime(&ptp_dpa_caps, &now);
12431 +
12432 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
12433 + if (IS_ERR(clock)) {
12434 + err = PTR_ERR(clock);
12435 + return err;
12436 + }
12437 + dpa_phc_index = ptp_clock_index(clock);
12438 + return 0;
12439 +}
12440 +module_init(dpa_ptp_load);
12441 +
12442 +static void __exit __cold dpa_ptp_unload(void)
12443 +{
12444 + struct ptp_clock *clock = ptp_priv.clock;
12445 +
12446 + if (mac_dev->fm_rtc_disable_interrupt)
12447 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
12448 + ptp_clock_unregister(clock);
12449 +}
12450 +module_exit(dpa_ptp_unload);
12451 --- /dev/null
12452 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
12453 @@ -0,0 +1,931 @@
12454 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
12455 + *
12456 + * Redistribution and use in source and binary forms, with or without
12457 + * modification, are permitted provided that the following conditions are met:
12458 + * * Redistributions of source code must retain the above copyright
12459 + * notice, this list of conditions and the following disclaimer.
12460 + * * Redistributions in binary form must reproduce the above copyright
12461 + * notice, this list of conditions and the following disclaimer in the
12462 + * documentation and/or other materials provided with the distribution.
12463 + * * Neither the name of Freescale Semiconductor nor the
12464 + * names of its contributors may be used to endorse or promote products
12465 + * derived from this software without specific prior written permission.
12466 + *
12467 + *
12468 + * ALTERNATIVELY, this software may be distributed under the terms of the
12469 + * GNU General Public License ("GPL") as published by the Free Software
12470 + * Foundation, either version 2 of that License or (at your option) any
12471 + * later version.
12472 + *
12473 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12474 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12475 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12476 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12477 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12478 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12479 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12480 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12481 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12482 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12483 + */
12484 +
12485 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12486 +#define pr_fmt(fmt) \
12487 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12488 + KBUILD_BASENAME".c", __LINE__, __func__
12489 +#else
12490 +#define pr_fmt(fmt) \
12491 + KBUILD_MODNAME ": " fmt
12492 +#endif
12493 +
12494 +#include <linux/init.h>
12495 +#include <linux/module.h>
12496 +#include <linux/io.h>
12497 +#include <linux/of_platform.h>
12498 +#include <linux/of_mdio.h>
12499 +#include <linux/phy.h>
12500 +#include <linux/netdevice.h>
12501 +
12502 +#include "dpaa_eth.h"
12503 +#include "mac.h"
12504 +#include "lnxwrp_fsl_fman.h"
12505 +
12506 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
12507 +
12508 +#include "fsl_fman_dtsec.h"
12509 +#include "fsl_fman_tgec.h"
12510 +#include "fsl_fman_memac.h"
12511 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
12512 +
12513 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
12514 +
12515 +MODULE_LICENSE("Dual BSD/GPL");
12516 +
12517 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
12518 +
12519 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
12520 +
12521 +struct mac_priv_s {
12522 + struct fm_mac_dev *fm_mac;
12523 +};
12524 +
12525 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
12526 +const size_t mac_sizeof_priv[] = {
12527 + [DTSEC] = sizeof(struct mac_priv_s),
12528 + [XGMAC] = sizeof(struct mac_priv_s),
12529 + [MEMAC] = sizeof(struct mac_priv_s)
12530 +};
12531 +
12532 +static const enet_mode_t _100[] = {
12533 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
12534 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
12535 +};
12536 +
12537 +static const enet_mode_t _1000[] = {
12538 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
12539 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
12540 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
12541 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
12542 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
12543 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
12544 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
12545 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
12546 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
12547 +};
12548 +
12549 +static enet_mode_t __cold __attribute__((nonnull))
12550 +macdev2enetinterface(const struct mac_device *mac_dev)
12551 +{
12552 + switch (mac_dev->max_speed) {
12553 + case SPEED_100:
12554 + return _100[mac_dev->phy_if];
12555 + case SPEED_1000:
12556 + return _1000[mac_dev->phy_if];
12557 + case SPEED_2500:
12558 + return e_ENET_MODE_SGMII_2500;
12559 + case SPEED_10000:
12560 + return e_ENET_MODE_XGMII_10000;
12561 + default:
12562 + return e_ENET_MODE_MII_100;
12563 + }
12564 +}
12565 +
12566 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
12567 +{
12568 + struct mac_device *mac_dev;
12569 +
12570 + mac_dev = (struct mac_device *)_mac_dev;
12571 +
12572 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
12573 + /* don't flag RX FIFO after the first */
12574 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
12575 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
12576 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
12577 + exception);
12578 + }
12579 +
12580 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
12581 + exception);
12582 +}
12583 +
12584 +static int __cold init(struct mac_device *mac_dev)
12585 +{
12586 + int _errno;
12587 + struct mac_priv_s *priv;
12588 + t_FmMacParams param;
12589 + uint32_t version;
12590 +
12591 + priv = macdev_priv(mac_dev);
12592 +
12593 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
12594 + mac_dev->dev, mac_dev->res->start, 0x2000);
12595 + param.enetMode = macdev2enetinterface(mac_dev);
12596 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
12597 + sizeof(mac_dev->addr)));
12598 + param.macId = mac_dev->cell_index;
12599 + param.h_Fm = (handle_t)mac_dev->fm;
12600 + param.mdioIrq = NO_IRQ;
12601 + param.f_Exception = mac_exception;
12602 + param.f_Event = mac_exception;
12603 + param.h_App = mac_dev;
12604 +
12605 + priv->fm_mac = fm_mac_config(&param);
12606 + if (unlikely(priv->fm_mac == NULL)) {
12607 + _errno = -EINVAL;
12608 + goto _return;
12609 + }
12610 +
12611 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
12612 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
12613 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
12614 +
12615 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
12616 + fm_get_max_frm());
12617 + if (unlikely(_errno < 0))
12618 + goto _return_fm_mac_free;
12619 +
12620 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
12621 + /* 10G always works with pad and CRC */
12622 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
12623 + if (unlikely(_errno < 0))
12624 + goto _return_fm_mac_free;
12625 +
12626 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
12627 + mac_dev->half_duplex);
12628 + if (unlikely(_errno < 0))
12629 + goto _return_fm_mac_free;
12630 + } else {
12631 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
12632 + if (unlikely(_errno < 0))
12633 + goto _return_fm_mac_free;
12634 + }
12635 +
12636 + _errno = fm_mac_init(priv->fm_mac);
12637 + if (unlikely(_errno < 0))
12638 + goto _return_fm_mac_free;
12639 +
12640 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
12641 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
12642 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
12643 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
12644 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
12645 + if (unlikely(_errno < 0))
12646 + goto _return_fm_mac_free;
12647 + }
12648 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
12649 +
12650 + /* For 10G MAC, disable Tx ECC exception */
12651 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
12652 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
12653 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
12654 + if (unlikely(_errno < 0))
12655 + goto _return_fm_mac_free;
12656 + }
12657 +
12658 + _errno = fm_mac_get_version(priv->fm_mac, &version);
12659 + if (unlikely(_errno < 0))
12660 + goto _return_fm_mac_free;
12661 +
12662 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
12663 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
12664 + "dTSEC" : "XGEC"), version);
12665 +
12666 + goto _return;
12667 +
12668 +
12669 +_return_fm_mac_free:
12670 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
12671 +
12672 +_return:
12673 + return _errno;
12674 +}
12675 +
12676 +static int __cold memac_init(struct mac_device *mac_dev)
12677 +{
12678 + int _errno;
12679 + struct mac_priv_s *priv;
12680 + t_FmMacParams param;
12681 +
12682 + priv = macdev_priv(mac_dev);
12683 +
12684 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
12685 + mac_dev->dev, mac_dev->res->start, 0x2000);
12686 + param.enetMode = macdev2enetinterface(mac_dev);
12687 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
12688 + param.macId = mac_dev->cell_index;
12689 + param.h_Fm = (handle_t)mac_dev->fm;
12690 + param.mdioIrq = NO_IRQ;
12691 + param.f_Exception = mac_exception;
12692 + param.f_Event = mac_exception;
12693 + param.h_App = mac_dev;
12694 +
12695 + priv->fm_mac = fm_mac_config(&param);
12696 + if (unlikely(priv->fm_mac == NULL)) {
12697 + _errno = -EINVAL;
12698 + goto _return;
12699 + }
12700 +
12701 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
12702 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
12703 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
12704 +
12705 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
12706 + if (unlikely(_errno < 0))
12707 + goto _return_fm_mac_free;
12708 +
12709 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
12710 + if (unlikely(_errno < 0))
12711 + goto _return_fm_mac_free;
12712 +
12713 + _errno = fm_mac_init(priv->fm_mac);
12714 + if (unlikely(_errno < 0))
12715 + goto _return_fm_mac_free;
12716 +
12717 + dev_info(mac_dev->dev, "FMan MEMAC\n");
12718 +
12719 + goto _return;
12720 +
12721 +_return_fm_mac_free:
12722 + fm_mac_free(priv->fm_mac);
12723 +
12724 +_return:
12725 + return _errno;
12726 +}
12727 +
12728 +static int __cold start(struct mac_device *mac_dev)
12729 +{
12730 + int _errno;
12731 + struct phy_device *phy_dev = mac_dev->phy_dev;
12732 +
12733 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
12734 +
12735 + if (!_errno && phy_dev)
12736 + phy_start(phy_dev);
12737 +
12738 + return _errno;
12739 +}
12740 +
12741 +static int __cold stop(struct mac_device *mac_dev)
12742 +{
12743 + if (mac_dev->phy_dev)
12744 + phy_stop(mac_dev->phy_dev);
12745 +
12746 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
12747 +}
12748 +
12749 +static int __cold set_multi(struct net_device *net_dev,
12750 + struct mac_device *mac_dev)
12751 +{
12752 + struct mac_priv_s *mac_priv;
12753 + struct mac_address *old_addr, *tmp;
12754 + struct netdev_hw_addr *ha;
12755 + int _errno;
12756 +
12757 + mac_priv = macdev_priv(mac_dev);
12758 +
12759 + /* Clear previous address list */
12760 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
12761 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
12762 + (t_EnetAddr *)old_addr->addr);
12763 + if (_errno < 0)
12764 + return _errno;
12765 +
12766 + list_del(&old_addr->list);
12767 + kfree(old_addr);
12768 + }
12769 +
12770 + /* Add all the addresses from the new list */
12771 + netdev_for_each_mc_addr(ha, net_dev) {
12772 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
12773 + (t_EnetAddr *)ha->addr);
12774 + if (_errno < 0)
12775 + return _errno;
12776 +
12777 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
12778 + if (!tmp) {
12779 + dev_err(mac_dev->dev, "Out of memory\n");
12780 + return -ENOMEM;
12781 + }
12782 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
12783 + list_add(&tmp->list, &mac_dev->mc_addr_list);
12784 + }
12785 + return 0;
12786 +}
12787 +
12788 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
12789 + * active PAUSE settings. Otherwise, the new active settings should be reflected
12790 + * in FMan.
12791 + */
12792 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
12793 +{
12794 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
12795 + int _errno = 0;
12796 +
12797 + if (unlikely(rx != mac_dev->rx_pause_active)) {
12798 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
12799 + if (likely(_errno == 0))
12800 + mac_dev->rx_pause_active = rx;
12801 + }
12802 +
12803 + if (unlikely(tx != mac_dev->tx_pause_active)) {
12804 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
12805 + if (likely(_errno == 0))
12806 + mac_dev->tx_pause_active = tx;
12807 + }
12808 +
12809 + return _errno;
12810 +}
12811 +EXPORT_SYMBOL(set_mac_active_pause);
12812 +
12813 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
12814 + * autonegotiation or values set by eththool.
12815 + */
12816 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
12817 +{
12818 + struct phy_device *phy_dev = mac_dev->phy_dev;
12819 + u16 lcl_adv, rmt_adv;
12820 + u8 flowctrl;
12821 +
12822 + *rx_pause = *tx_pause = false;
12823 +
12824 + if (!phy_dev->duplex)
12825 + return;
12826 +
12827 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
12828 + * are those set by ethtool.
12829 + */
12830 + if (!mac_dev->autoneg_pause) {
12831 + *rx_pause = mac_dev->rx_pause_req;
12832 + *tx_pause = mac_dev->tx_pause_req;
12833 + return;
12834 + }
12835 +
12836 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
12837 + * settings depend on the result of the link negotiation.
12838 + */
12839 +
12840 + /* get local capabilities */
12841 + lcl_adv = 0;
12842 + if (phy_dev->advertising & ADVERTISED_Pause)
12843 + lcl_adv |= ADVERTISE_PAUSE_CAP;
12844 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
12845 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
12846 +
12847 + /* get link partner capabilities */
12848 + rmt_adv = 0;
12849 + if (phy_dev->pause)
12850 + rmt_adv |= LPA_PAUSE_CAP;
12851 + if (phy_dev->asym_pause)
12852 + rmt_adv |= LPA_PAUSE_ASYM;
12853 +
12854 + /* Calculate TX/RX settings based on local and peer advertised
12855 + * symmetric/asymmetric PAUSE capabilities.
12856 + */
12857 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
12858 + if (flowctrl & FLOW_CTRL_RX)
12859 + *rx_pause = true;
12860 + if (flowctrl & FLOW_CTRL_TX)
12861 + *tx_pause = true;
12862 +}
12863 +EXPORT_SYMBOL(get_pause_cfg);
12864 +
12865 +static void adjust_link_void(struct net_device *net_dev)
12866 +{
12867 +}
12868 +
12869 +static void adjust_link(struct net_device *net_dev)
12870 +{
12871 + struct dpa_priv_s *priv = netdev_priv(net_dev);
12872 + struct mac_device *mac_dev = priv->mac_dev;
12873 + struct phy_device *phy_dev = mac_dev->phy_dev;
12874 + struct fm_mac_dev *fm_mac_dev;
12875 + bool rx_pause, tx_pause;
12876 + int _errno;
12877 +
12878 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
12879 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
12880 + phy_dev->duplex);
12881 +
12882 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
12883 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
12884 + if (unlikely(_errno < 0))
12885 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
12886 +}
12887 +
12888 +/* Initializes driver's PHY state, and attaches to the PHY.
12889 + * Returns 0 on success.
12890 + */
12891 +static int dtsec_init_phy(struct net_device *net_dev,
12892 + struct mac_device *mac_dev)
12893 +{
12894 + struct phy_device *phy_dev;
12895 +
12896 + if (of_phy_is_fixed_link(mac_dev->phy_node))
12897 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
12898 + 0, mac_dev->phy_if);
12899 + else
12900 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
12901 + &adjust_link, 0, mac_dev->phy_if);
12902 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
12903 + netdev_err(net_dev, "Could not connect to PHY %s\n",
12904 + mac_dev->phy_node ?
12905 + mac_dev->phy_node->full_name :
12906 + mac_dev->fixed_bus_id);
12907 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
12908 + }
12909 +
12910 + /* Remove any features not supported by the controller */
12911 + phy_dev->supported &= mac_dev->if_support;
12912 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
12913 + * as most of the PHY drivers do not enable them by default.
12914 + */
12915 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
12916 + phy_dev->advertising = phy_dev->supported;
12917 +
12918 + mac_dev->phy_dev = phy_dev;
12919 +
12920 + return 0;
12921 +}
12922 +
12923 +static int xgmac_init_phy(struct net_device *net_dev,
12924 + struct mac_device *mac_dev)
12925 +{
12926 + struct phy_device *phy_dev;
12927 +
12928 + if (of_phy_is_fixed_link(mac_dev->phy_node))
12929 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
12930 + 0, mac_dev->phy_if);
12931 + else
12932 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
12933 + &adjust_link_void, 0, mac_dev->phy_if);
12934 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
12935 + netdev_err(net_dev, "Could not attach to PHY %s\n",
12936 + mac_dev->phy_node ?
12937 + mac_dev->phy_node->full_name :
12938 + mac_dev->fixed_bus_id);
12939 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
12940 + }
12941 +
12942 + phy_dev->supported &= mac_dev->if_support;
12943 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
12944 + * as most of the PHY drivers do not enable them by default.
12945 + */
12946 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
12947 + phy_dev->advertising = phy_dev->supported;
12948 +
12949 + mac_dev->phy_dev = phy_dev;
12950 +
12951 + return 0;
12952 +}
12953 +
12954 +static int memac_init_phy(struct net_device *net_dev,
12955 + struct mac_device *mac_dev)
12956 +{
12957 + struct phy_device *phy_dev;
12958 + void (*adjust_link_handler)(struct net_device *);
12959 +
12960 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
12961 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500)) {
12962 + /* Pass a void link state handler to the PHY state machine
12963 + * for XGMII (10G) and SGMII 2.5G, as the hardware does not
12964 + * permit dynamic link speed adjustments. */
12965 + adjust_link_handler = adjust_link_void;
12966 + } else if (macdev2enetinterface(mac_dev) & e_ENET_IF_RGMII) {
12967 + /* Regular RGMII ports connected to a PHY, as well as
12968 + * ports that are marked as "fixed-link" in the DTS,
12969 + * will have the adjust_link callback. This calls
12970 + * fman_memac_adjust_link in order to configure the
12971 + * IF_MODE register, which is needed in both cases.
12972 + */
12973 + adjust_link_handler = adjust_link;
12974 + } else if (of_phy_is_fixed_link(mac_dev->phy_node)) {
12975 + /* Pass a void link state handler for fixed-link
12976 + * interfaces that are not RGMII. Only RGMII has been
12977 + * tested and confirmed to work with fixed-link. Other
12978 + * MII interfaces may need further work.
12979 + * TODO: Change this as needed.
12980 + */
12981 + adjust_link_handler = adjust_link_void;
12982 + } else {
12983 + /* MII, RMII, SMII, GMII, SGMII, BASEX ports,
12984 + * that are NOT fixed-link.
12985 + * TODO: May not be needed for interfaces that
12986 + * pass through the SerDes block (*SGMII, XFI).
12987 + */
12988 + adjust_link_handler = adjust_link;
12989 + }
12990 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
12991 + adjust_link_handler, 0,
12992 + mac_dev->phy_if);
12993 +
12994 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
12995 + netdev_err(net_dev, "Could not connect to PHY %s\n",
12996 + mac_dev->phy_node ?
12997 + mac_dev->phy_node->full_name :
12998 + mac_dev->fixed_bus_id);
12999 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
13000 + }
13001 +
13002 + /* Remove any features not supported by the controller */
13003 + phy_dev->supported &= mac_dev->if_support;
13004 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
13005 + * as most of the PHY drivers do not enable them by default.
13006 + */
13007 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
13008 + phy_dev->advertising = phy_dev->supported;
13009 +
13010 + mac_dev->phy_dev = phy_dev;
13011 +
13012 + return 0;
13013 +}
13014 +
13015 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
13016 +{
13017 + int _errno, __errno;
13018 +
13019 + _errno = fm_mac_disable(fm_mac_dev);
13020 + __errno = fm_mac_free(fm_mac_dev);
13021 +
13022 + if (unlikely(__errno < 0))
13023 + _errno = __errno;
13024 +
13025 + return _errno;
13026 +}
13027 +
13028 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
13029 +{
13030 + const struct mac_priv_s *priv;
13031 + priv = macdev_priv(mac_dev);
13032 + return priv->fm_mac;
13033 +}
13034 +
13035 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13036 +{
13037 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
13038 + int i = 0, n = nn;
13039 +
13040 + FM_DMP_SUBTITLE(buf, n, "\n");
13041 +
13042 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
13043 +
13044 + FM_DMP_V32(buf, n, p_mm, tsec_id);
13045 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
13046 + FM_DMP_V32(buf, n, p_mm, ievent);
13047 + FM_DMP_V32(buf, n, p_mm, imask);
13048 + FM_DMP_V32(buf, n, p_mm, ecntrl);
13049 + FM_DMP_V32(buf, n, p_mm, ptv);
13050 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
13051 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
13052 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
13053 + FM_DMP_V32(buf, n, p_mm, tctrl);
13054 + FM_DMP_V32(buf, n, p_mm, rctrl);
13055 + FM_DMP_V32(buf, n, p_mm, maccfg1);
13056 + FM_DMP_V32(buf, n, p_mm, maccfg2);
13057 + FM_DMP_V32(buf, n, p_mm, ipgifg);
13058 + FM_DMP_V32(buf, n, p_mm, hafdup);
13059 + FM_DMP_V32(buf, n, p_mm, maxfrm);
13060 +
13061 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
13062 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
13063 +
13064 + for (i = 0; i < 7; ++i) {
13065 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
13066 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
13067 + }
13068 +
13069 + FM_DMP_V32(buf, n, p_mm, car1);
13070 + FM_DMP_V32(buf, n, p_mm, car2);
13071 +
13072 + return n;
13073 +}
13074 +
13075 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13076 +{
13077 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
13078 + int n = nn;
13079 +
13080 + FM_DMP_SUBTITLE(buf, n, "\n");
13081 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
13082 +
13083 + FM_DMP_V32(buf, n, p_mm, tgec_id);
13084 + FM_DMP_V32(buf, n, p_mm, command_config);
13085 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
13086 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
13087 + FM_DMP_V32(buf, n, p_mm, maxfrm);
13088 + FM_DMP_V32(buf, n, p_mm, pause_quant);
13089 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
13090 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
13091 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
13092 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
13093 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
13094 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
13095 + FM_DMP_V32(buf, n, p_mm, mdio_command);
13096 + FM_DMP_V32(buf, n, p_mm, mdio_data);
13097 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
13098 + FM_DMP_V32(buf, n, p_mm, status);
13099 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
13100 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
13101 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
13102 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
13103 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
13104 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
13105 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
13106 + FM_DMP_V32(buf, n, p_mm, imask);
13107 + FM_DMP_V32(buf, n, p_mm, ievent);
13108 +
13109 + return n;
13110 +}
13111 +
13112 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13113 +{
13114 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
13115 + int i = 0, n = nn;
13116 +
13117 + FM_DMP_SUBTITLE(buf, n, "\n");
13118 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
13119 +
13120 + FM_DMP_V32(buf, n, p_mm, command_config);
13121 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
13122 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
13123 + FM_DMP_V32(buf, n, p_mm, maxfrm);
13124 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
13125 + FM_DMP_V32(buf, n, p_mm, ievent);
13126 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
13127 + FM_DMP_V32(buf, n, p_mm, imask);
13128 +
13129 + for (i = 0; i < 4; ++i)
13130 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
13131 +
13132 + for (i = 0; i < 4; ++i)
13133 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
13134 +
13135 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
13136 +
13137 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
13138 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
13139 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
13140 + }
13141 +
13142 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
13143 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
13144 + FM_DMP_V32(buf, n, p_mm, statn_config);
13145 + FM_DMP_V32(buf, n, p_mm, if_mode);
13146 + FM_DMP_V32(buf, n, p_mm, if_status);
13147 + FM_DMP_V32(buf, n, p_mm, hg_config);
13148 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
13149 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
13150 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
13151 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
13152 + FM_DMP_V32(buf, n, p_mm, rhm);
13153 + FM_DMP_V32(buf, n, p_mm, thm);
13154 +
13155 + return n;
13156 +}
13157 +
13158 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
13159 +{
13160 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
13161 + int n = nn;
13162 +
13163 + FM_DMP_SUBTITLE(buf, n, "\n");
13164 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
13165 +
13166 + /* Rx Statistics Counter */
13167 + FM_DMP_V32(buf, n, p_mm, reoct_l);
13168 + FM_DMP_V32(buf, n, p_mm, reoct_u);
13169 + FM_DMP_V32(buf, n, p_mm, roct_l);
13170 + FM_DMP_V32(buf, n, p_mm, roct_u);
13171 + FM_DMP_V32(buf, n, p_mm, raln_l);
13172 + FM_DMP_V32(buf, n, p_mm, raln_u);
13173 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
13174 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
13175 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
13176 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
13177 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
13178 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
13179 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
13180 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
13181 + FM_DMP_V32(buf, n, p_mm, rerr_l);
13182 + FM_DMP_V32(buf, n, p_mm, rerr_u);
13183 + FM_DMP_V32(buf, n, p_mm, ruca_l);
13184 + FM_DMP_V32(buf, n, p_mm, ruca_u);
13185 + FM_DMP_V32(buf, n, p_mm, rmca_l);
13186 + FM_DMP_V32(buf, n, p_mm, rmca_u);
13187 + FM_DMP_V32(buf, n, p_mm, rbca_l);
13188 + FM_DMP_V32(buf, n, p_mm, rbca_u);
13189 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
13190 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
13191 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
13192 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
13193 + FM_DMP_V32(buf, n, p_mm, rund_l);
13194 + FM_DMP_V32(buf, n, p_mm, rund_u);
13195 + FM_DMP_V32(buf, n, p_mm, r64_l);
13196 + FM_DMP_V32(buf, n, p_mm, r64_u);
13197 + FM_DMP_V32(buf, n, p_mm, r127_l);
13198 + FM_DMP_V32(buf, n, p_mm, r127_u);
13199 + FM_DMP_V32(buf, n, p_mm, r255_l);
13200 + FM_DMP_V32(buf, n, p_mm, r255_u);
13201 + FM_DMP_V32(buf, n, p_mm, r511_l);
13202 + FM_DMP_V32(buf, n, p_mm, r511_u);
13203 + FM_DMP_V32(buf, n, p_mm, r1023_l);
13204 + FM_DMP_V32(buf, n, p_mm, r1023_u);
13205 + FM_DMP_V32(buf, n, p_mm, r1518_l);
13206 + FM_DMP_V32(buf, n, p_mm, r1518_u);
13207 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
13208 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
13209 + FM_DMP_V32(buf, n, p_mm, rovr_l);
13210 + FM_DMP_V32(buf, n, p_mm, rovr_u);
13211 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
13212 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
13213 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
13214 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
13215 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
13216 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
13217 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
13218 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
13219 +
13220 + return n;
13221 +}
13222 +
13223 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
13224 +{
13225 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
13226 + int n = nn;
13227 +
13228 + FM_DMP_SUBTITLE(buf, n, "\n");
13229 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
13230 +
13231 +
13232 + /* Tx Statistics Counter */
13233 + FM_DMP_V32(buf, n, p_mm, teoct_l);
13234 + FM_DMP_V32(buf, n, p_mm, teoct_u);
13235 + FM_DMP_V32(buf, n, p_mm, toct_l);
13236 + FM_DMP_V32(buf, n, p_mm, toct_u);
13237 + FM_DMP_V32(buf, n, p_mm, txpf_l);
13238 + FM_DMP_V32(buf, n, p_mm, txpf_u);
13239 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
13240 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
13241 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
13242 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
13243 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
13244 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
13245 + FM_DMP_V32(buf, n, p_mm, terr_l);
13246 + FM_DMP_V32(buf, n, p_mm, terr_u);
13247 + FM_DMP_V32(buf, n, p_mm, tuca_l);
13248 + FM_DMP_V32(buf, n, p_mm, tuca_u);
13249 + FM_DMP_V32(buf, n, p_mm, tmca_l);
13250 + FM_DMP_V32(buf, n, p_mm, tmca_u);
13251 + FM_DMP_V32(buf, n, p_mm, tbca_l);
13252 + FM_DMP_V32(buf, n, p_mm, tbca_u);
13253 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
13254 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
13255 + FM_DMP_V32(buf, n, p_mm, tund_l);
13256 + FM_DMP_V32(buf, n, p_mm, tund_u);
13257 + FM_DMP_V32(buf, n, p_mm, t64_l);
13258 + FM_DMP_V32(buf, n, p_mm, t64_u);
13259 + FM_DMP_V32(buf, n, p_mm, t127_l);
13260 + FM_DMP_V32(buf, n, p_mm, t127_u);
13261 + FM_DMP_V32(buf, n, p_mm, t255_l);
13262 + FM_DMP_V32(buf, n, p_mm, t255_u);
13263 + FM_DMP_V32(buf, n, p_mm, t511_l);
13264 + FM_DMP_V32(buf, n, p_mm, t511_u);
13265 + FM_DMP_V32(buf, n, p_mm, t1023_l);
13266 + FM_DMP_V32(buf, n, p_mm, t1023_u);
13267 + FM_DMP_V32(buf, n, p_mm, t1518_l);
13268 + FM_DMP_V32(buf, n, p_mm, t1518_u);
13269 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
13270 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
13271 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
13272 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
13273 +
13274 + return n;
13275 +}
13276 +
13277 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13278 +{
13279 + int n = nn;
13280 +
13281 + n = h_mac->dump_mac_regs(h_mac, buf, n);
13282 +
13283 + return n;
13284 +}
13285 +EXPORT_SYMBOL(fm_mac_dump_regs);
13286 +
13287 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
13288 +{
13289 + int n = nn;
13290 +
13291 + if(h_mac->dump_mac_rx_stats)
13292 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
13293 +
13294 + return n;
13295 +}
13296 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
13297 +
13298 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
13299 +{
13300 + int n = nn;
13301 +
13302 + if(h_mac->dump_mac_tx_stats)
13303 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
13304 +
13305 + return n;
13306 +}
13307 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
13308 +
13309 +static void __cold setup_dtsec(struct mac_device *mac_dev)
13310 +{
13311 + mac_dev->init_phy = dtsec_init_phy;
13312 + mac_dev->init = init;
13313 + mac_dev->start = start;
13314 + mac_dev->stop = stop;
13315 + mac_dev->set_promisc = fm_mac_set_promiscuous;
13316 + mac_dev->change_addr = fm_mac_modify_mac_addr;
13317 + mac_dev->set_multi = set_multi;
13318 + mac_dev->uninit = uninit;
13319 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
13320 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
13321 + mac_dev->get_mac_handle = get_mac_handle;
13322 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
13323 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
13324 + mac_dev->fm_rtc_enable = fm_rtc_enable;
13325 + mac_dev->fm_rtc_disable = fm_rtc_disable;
13326 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
13327 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
13328 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
13329 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
13330 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
13331 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
13332 + mac_dev->set_wol = fm_mac_set_wol;
13333 + mac_dev->dump_mac_regs = dtsec_dump_regs;
13334 +}
13335 +
13336 +static void __cold setup_xgmac(struct mac_device *mac_dev)
13337 +{
13338 + mac_dev->init_phy = xgmac_init_phy;
13339 + mac_dev->init = init;
13340 + mac_dev->start = start;
13341 + mac_dev->stop = stop;
13342 + mac_dev->set_promisc = fm_mac_set_promiscuous;
13343 + mac_dev->change_addr = fm_mac_modify_mac_addr;
13344 + mac_dev->set_multi = set_multi;
13345 + mac_dev->uninit = uninit;
13346 + mac_dev->get_mac_handle = get_mac_handle;
13347 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
13348 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
13349 + mac_dev->set_wol = fm_mac_set_wol;
13350 + mac_dev->dump_mac_regs = xgmac_dump_regs;
13351 +}
13352 +
13353 +static void __cold setup_memac(struct mac_device *mac_dev)
13354 +{
13355 + mac_dev->init_phy = memac_init_phy;
13356 + mac_dev->init = memac_init;
13357 + mac_dev->start = start;
13358 + mac_dev->stop = stop;
13359 + mac_dev->set_promisc = fm_mac_set_promiscuous;
13360 + mac_dev->change_addr = fm_mac_modify_mac_addr;
13361 + mac_dev->set_multi = set_multi;
13362 + mac_dev->uninit = uninit;
13363 + mac_dev->get_mac_handle = get_mac_handle;
13364 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
13365 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
13366 + mac_dev->fm_rtc_enable = fm_rtc_enable;
13367 + mac_dev->fm_rtc_disable = fm_rtc_disable;
13368 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
13369 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
13370 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
13371 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
13372 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
13373 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
13374 + mac_dev->set_wol = fm_mac_set_wol;
13375 + mac_dev->dump_mac_regs = memac_dump_regs;
13376 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
13377 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
13378 +}
13379 +
13380 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
13381 + [DTSEC] = setup_dtsec,
13382 + [XGMAC] = setup_xgmac,
13383 + [MEMAC] = setup_memac
13384 +};
13385 --- /dev/null
13386 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
13387 @@ -0,0 +1,489 @@
13388 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
13389 + *
13390 + * Redistribution and use in source and binary forms, with or without
13391 + * modification, are permitted provided that the following conditions are met:
13392 + * * Redistributions of source code must retain the above copyright
13393 + * notice, this list of conditions and the following disclaimer.
13394 + * * Redistributions in binary form must reproduce the above copyright
13395 + * notice, this list of conditions and the following disclaimer in the
13396 + * documentation and/or other materials provided with the distribution.
13397 + * * Neither the name of Freescale Semiconductor nor the
13398 + * names of its contributors may be used to endorse or promote products
13399 + * derived from this software without specific prior written permission.
13400 + *
13401 + *
13402 + * ALTERNATIVELY, this software may be distributed under the terms of the
13403 + * GNU General Public License ("GPL") as published by the Free Software
13404 + * Foundation, either version 2 of that License or (at your option) any
13405 + * later version.
13406 + *
13407 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13408 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13409 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13410 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13411 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13412 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13413 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13414 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13415 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13416 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13417 + */
13418 +
13419 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
13420 +#define pr_fmt(fmt) \
13421 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
13422 + KBUILD_BASENAME".c", __LINE__, __func__
13423 +#else
13424 +#define pr_fmt(fmt) \
13425 + KBUILD_MODNAME ": " fmt
13426 +#endif
13427 +
13428 +#include <linux/init.h>
13429 +#include <linux/module.h>
13430 +#include <linux/of_address.h>
13431 +#include <linux/of_platform.h>
13432 +#include <linux/of_net.h>
13433 +#include <linux/of_mdio.h>
13434 +#include <linux/phy_fixed.h>
13435 +#include <linux/device.h>
13436 +#include <linux/phy.h>
13437 +#include <linux/io.h>
13438 +
13439 +#include "lnxwrp_fm_ext.h"
13440 +
13441 +#include "mac.h"
13442 +
13443 +#define DTSEC_SUPPORTED \
13444 + (SUPPORTED_10baseT_Half \
13445 + | SUPPORTED_10baseT_Full \
13446 + | SUPPORTED_100baseT_Half \
13447 + | SUPPORTED_100baseT_Full \
13448 + | SUPPORTED_Autoneg \
13449 + | SUPPORTED_Pause \
13450 + | SUPPORTED_Asym_Pause \
13451 + | SUPPORTED_MII)
13452 +
13453 +static const char phy_str[][11] = {
13454 + [PHY_INTERFACE_MODE_MII] = "mii",
13455 + [PHY_INTERFACE_MODE_GMII] = "gmii",
13456 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
13457 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
13458 + [PHY_INTERFACE_MODE_TBI] = "tbi",
13459 + [PHY_INTERFACE_MODE_RMII] = "rmii",
13460 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
13461 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
13462 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
13463 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
13464 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
13465 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
13466 + [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500",
13467 +};
13468 +
13469 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
13470 +{
13471 + int i;
13472 +
13473 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
13474 + if (strcmp(str, phy_str[i]) == 0)
13475 + return (phy_interface_t)i;
13476 +
13477 + return PHY_INTERFACE_MODE_MII;
13478 +}
13479 +
13480 +static const uint16_t phy2speed[] = {
13481 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
13482 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
13483 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
13484 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
13485 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
13486 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
13487 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
13488 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
13489 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
13490 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
13491 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
13492 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
13493 + [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500,
13494 +};
13495 +
13496 +static struct mac_device * __cold
13497 +alloc_macdev(struct device *dev, size_t sizeof_priv,
13498 + void (*setup)(struct mac_device *mac_dev))
13499 +{
13500 + struct mac_device *mac_dev;
13501 +
13502 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
13503 + if (unlikely(mac_dev == NULL))
13504 + mac_dev = ERR_PTR(-ENOMEM);
13505 + else {
13506 + mac_dev->dev = dev;
13507 + dev_set_drvdata(dev, mac_dev);
13508 + setup(mac_dev);
13509 + }
13510 +
13511 + return mac_dev;
13512 +}
13513 +
13514 +static int __cold free_macdev(struct mac_device *mac_dev)
13515 +{
13516 + dev_set_drvdata(mac_dev->dev, NULL);
13517 +
13518 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
13519 +}
13520 +
13521 +static const struct of_device_id mac_match[] = {
13522 + [DTSEC] = {
13523 + .compatible = "fsl,fman-dtsec"
13524 + },
13525 + [XGMAC] = {
13526 + .compatible = "fsl,fman-xgec"
13527 + },
13528 + [MEMAC] = {
13529 + .compatible = "fsl,fman-memac"
13530 + },
13531 + {}
13532 +};
13533 +MODULE_DEVICE_TABLE(of, mac_match);
13534 +
13535 +static int __cold mac_probe(struct platform_device *_of_dev)
13536 +{
13537 + int _errno, i;
13538 + struct device *dev;
13539 + struct device_node *mac_node, *dev_node;
13540 + struct mac_device *mac_dev;
13541 + struct platform_device *of_dev;
13542 + struct resource res;
13543 + const uint8_t *mac_addr;
13544 + const char *char_prop;
13545 + int nph;
13546 + u32 cell_index;
13547 + const struct of_device_id *match;
13548 +
13549 + dev = &_of_dev->dev;
13550 + mac_node = dev->of_node;
13551 +
13552 + match = of_match_device(mac_match, dev);
13553 + if (!match)
13554 + return -EINVAL;
13555 +
13556 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
13557 + i++)
13558 + ;
13559 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
13560 +
13561 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
13562 + if (IS_ERR(mac_dev)) {
13563 + _errno = PTR_ERR(mac_dev);
13564 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
13565 + goto _return;
13566 + }
13567 +
13568 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
13569 +
13570 + /* Get the FM node */
13571 + dev_node = of_get_parent(mac_node);
13572 + if (unlikely(dev_node == NULL)) {
13573 + dev_err(dev, "of_get_parent(%s) failed\n",
13574 + mac_node->full_name);
13575 + _errno = -EINVAL;
13576 + goto _return_dev_set_drvdata;
13577 + }
13578 +
13579 + of_dev = of_find_device_by_node(dev_node);
13580 + if (unlikely(of_dev == NULL)) {
13581 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
13582 + dev_node->full_name);
13583 + _errno = -EINVAL;
13584 + goto _return_of_node_put;
13585 + }
13586 +
13587 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
13588 + if (unlikely(mac_dev->fm_dev == NULL)) {
13589 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
13590 + _errno = -ENODEV;
13591 + goto _return_of_node_put;
13592 + }
13593 +
13594 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
13595 + of_node_put(dev_node);
13596 +
13597 + /* Get the address of the memory mapped registers */
13598 + _errno = of_address_to_resource(mac_node, 0, &res);
13599 + if (unlikely(_errno < 0)) {
13600 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
13601 + mac_node->full_name, _errno);
13602 + goto _return_dev_set_drvdata;
13603 + }
13604 +
13605 + mac_dev->res = __devm_request_region(
13606 + dev,
13607 + fm_get_mem_region(mac_dev->fm_dev),
13608 + res.start, res.end + 1 - res.start, "mac");
13609 + if (unlikely(mac_dev->res == NULL)) {
13610 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
13611 + _errno = -EBUSY;
13612 + goto _return_dev_set_drvdata;
13613 + }
13614 +
13615 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
13616 + mac_dev->res->end + 1
13617 + - mac_dev->res->start);
13618 + if (unlikely(mac_dev->vaddr == NULL)) {
13619 + dev_err(dev, "devm_ioremap() failed\n");
13620 + _errno = -EIO;
13621 + goto _return_dev_set_drvdata;
13622 + }
13623 +
13624 +#define TBIPA_OFFSET 0x1c
13625 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
13626 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
13627 + if (mac_dev->tbi_node) {
13628 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
13629 + const __be32 *tbi_reg;
13630 + void __iomem *addr;
13631 +
13632 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
13633 + if (tbi_reg)
13634 + tbiaddr = be32_to_cpup(tbi_reg);
13635 + addr = mac_dev->vaddr + TBIPA_OFFSET;
13636 + /* TODO: out_be32 does not exist on ARM */
13637 + out_be32(addr, tbiaddr);
13638 + }
13639 +
13640 + if (!of_device_is_available(mac_node)) {
13641 + devm_iounmap(dev, mac_dev->vaddr);
13642 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
13643 + res.start, res.end + 1 - res.start);
13644 + fm_unbind(mac_dev->fm_dev);
13645 + devm_kfree(dev, mac_dev);
13646 + dev_set_drvdata(dev, NULL);
13647 + return -ENODEV;
13648 + }
13649 +
13650 + /* Get the cell-index */
13651 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
13652 + if (unlikely(_errno)) {
13653 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
13654 + mac_node->full_name);
13655 + goto _return_dev_set_drvdata;
13656 + }
13657 + mac_dev->cell_index = (uint8_t)cell_index;
13658 + if (mac_dev->cell_index >= 8)
13659 + mac_dev->cell_index -= 8;
13660 +
13661 + /* Get the MAC address */
13662 + mac_addr = of_get_mac_address(mac_node);
13663 + if (unlikely(mac_addr == NULL)) {
13664 + dev_err(dev, "of_get_mac_address(%s) failed\n",
13665 + mac_node->full_name);
13666 + _errno = -EINVAL;
13667 + goto _return_dev_set_drvdata;
13668 + }
13669 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
13670 +
13671 + /* Verify the number of port handles */
13672 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
13673 + if (unlikely(nph < 0)) {
13674 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
13675 + mac_node->full_name);
13676 + _errno = nph;
13677 + goto _return_dev_set_drvdata;
13678 + }
13679 +
13680 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
13681 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
13682 + mac_node->full_name);
13683 + _errno = -EINVAL;
13684 + goto _return_dev_set_drvdata;
13685 + }
13686 +
13687 + for_each_port_device(i, mac_dev->port_dev) {
13688 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
13689 + if (unlikely(dev_node == NULL)) {
13690 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
13691 + mac_node->full_name);
13692 + _errno = -EINVAL;
13693 + goto _return_of_node_put;
13694 + }
13695 +
13696 + of_dev = of_find_device_by_node(dev_node);
13697 + if (unlikely(of_dev == NULL)) {
13698 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
13699 + dev_node->full_name);
13700 + _errno = -EINVAL;
13701 + goto _return_of_node_put;
13702 + }
13703 +
13704 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
13705 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
13706 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
13707 + dev_node->full_name);
13708 + _errno = -EINVAL;
13709 + goto _return_of_node_put;
13710 + }
13711 + of_node_put(dev_node);
13712 + }
13713 +
13714 + /* Get the PHY connection type */
13715 + _errno = of_property_read_string(mac_node, "phy-connection-type",
13716 + &char_prop);
13717 + if (unlikely(_errno)) {
13718 + dev_warn(dev,
13719 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
13720 + mac_node->full_name);
13721 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
13722 + } else
13723 + mac_dev->phy_if = str2phy(char_prop);
13724 +
13725 + mac_dev->link = false;
13726 + mac_dev->half_duplex = false;
13727 + mac_dev->speed = phy2speed[mac_dev->phy_if];
13728 + mac_dev->max_speed = mac_dev->speed;
13729 + mac_dev->if_support = DTSEC_SUPPORTED;
13730 + /* We don't support half-duplex in SGMII mode */
13731 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
13732 + strstr(char_prop, "sgmii-2500"))
13733 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
13734 + SUPPORTED_100baseT_Half);
13735 +
13736 + /* Gigabit support (no half-duplex) */
13737 + if (mac_dev->max_speed == SPEED_1000 ||
13738 + mac_dev->max_speed == SPEED_2500)
13739 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
13740 +
13741 + /* The 10G interface only supports one mode */
13742 + if (strstr(char_prop, "xgmii"))
13743 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
13744 +
13745 + /* Get the rest of the PHY information */
13746 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
13747 + if (!mac_dev->phy_node) {
13748 + struct phy_device *phy;
13749 +
13750 + if (!of_phy_is_fixed_link(mac_node)) {
13751 + dev_err(dev, "Wrong PHY information of mac node %s\n",
13752 + mac_node->full_name);
13753 + goto _return_dev_set_drvdata;
13754 + }
13755 +
13756 + _errno = of_phy_register_fixed_link(mac_node);
13757 + if (_errno)
13758 + goto _return_dev_set_drvdata;
13759 +
13760 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
13761 + sizeof(*mac_dev->fixed_link),
13762 + GFP_KERNEL);
13763 + if (!mac_dev->fixed_link)
13764 + goto _return_dev_set_drvdata;
13765 +
13766 + mac_dev->phy_node = of_node_get(mac_node);
13767 + phy = of_phy_find_device(mac_dev->phy_node);
13768 + if (!phy)
13769 + goto _return_dev_set_drvdata;
13770 +
13771 + mac_dev->fixed_link->link = phy->link;
13772 + mac_dev->fixed_link->speed = phy->speed;
13773 + mac_dev->fixed_link->duplex = phy->duplex;
13774 + mac_dev->fixed_link->pause = phy->pause;
13775 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
13776 + }
13777 +
13778 + _errno = mac_dev->init(mac_dev);
13779 + if (unlikely(_errno < 0)) {
13780 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
13781 + goto _return_dev_set_drvdata;
13782 + }
13783 +
13784 + /* pause frame autonegotiation enabled*/
13785 + mac_dev->autoneg_pause = true;
13786 +
13787 + /* by intializing the values to false, force FMD to enable PAUSE frames
13788 + * on RX and TX
13789 + */
13790 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
13791 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
13792 + _errno = set_mac_active_pause(mac_dev, true, true);
13793 + if (unlikely(_errno < 0))
13794 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
13795 +
13796 + dev_info(dev,
13797 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
13798 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
13799 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
13800 +
13801 + goto _return;
13802 +
13803 +_return_of_node_put:
13804 + of_node_put(dev_node);
13805 +_return_dev_set_drvdata:
13806 + dev_set_drvdata(dev, NULL);
13807 +_return:
13808 + return _errno;
13809 +}
13810 +
13811 +static int __cold mac_remove(struct platform_device *of_dev)
13812 +{
13813 + int i, _errno;
13814 + struct device *dev;
13815 + struct mac_device *mac_dev;
13816 +
13817 + dev = &of_dev->dev;
13818 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
13819 +
13820 + for_each_port_device(i, mac_dev->port_dev)
13821 + fm_port_unbind(mac_dev->port_dev[i]);
13822 +
13823 + fm_unbind(mac_dev->fm_dev);
13824 +
13825 + _errno = free_macdev(mac_dev);
13826 +
13827 + return _errno;
13828 +}
13829 +
13830 +static struct platform_driver mac_driver = {
13831 + .driver = {
13832 + .name = KBUILD_MODNAME,
13833 + .of_match_table = mac_match,
13834 + .owner = THIS_MODULE,
13835 + },
13836 + .probe = mac_probe,
13837 + .remove = mac_remove
13838 +};
13839 +
13840 +static int __init __cold mac_load(void)
13841 +{
13842 + int _errno;
13843 +
13844 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13845 + KBUILD_BASENAME".c", __func__);
13846 +
13847 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
13848 +
13849 + _errno = platform_driver_register(&mac_driver);
13850 + if (unlikely(_errno < 0)) {
13851 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
13852 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13853 + goto _return;
13854 + }
13855 +
13856 + goto _return;
13857 +
13858 +_return:
13859 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13860 + KBUILD_BASENAME".c", __func__);
13861 +
13862 + return _errno;
13863 +}
13864 +module_init(mac_load);
13865 +
13866 +static void __exit __cold mac_unload(void)
13867 +{
13868 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13869 + KBUILD_BASENAME".c", __func__);
13870 +
13871 + platform_driver_unregister(&mac_driver);
13872 +
13873 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13874 + KBUILD_BASENAME".c", __func__);
13875 +}
13876 +module_exit(mac_unload);
13877 --- /dev/null
13878 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
13879 @@ -0,0 +1,135 @@
13880 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
13881 + *
13882 + * Redistribution and use in source and binary forms, with or without
13883 + * modification, are permitted provided that the following conditions are met:
13884 + * * Redistributions of source code must retain the above copyright
13885 + * notice, this list of conditions and the following disclaimer.
13886 + * * Redistributions in binary form must reproduce the above copyright
13887 + * notice, this list of conditions and the following disclaimer in the
13888 + * documentation and/or other materials provided with the distribution.
13889 + * * Neither the name of Freescale Semiconductor nor the
13890 + * names of its contributors may be used to endorse or promote products
13891 + * derived from this software without specific prior written permission.
13892 + *
13893 + *
13894 + * ALTERNATIVELY, this software may be distributed under the terms of the
13895 + * GNU General Public License ("GPL") as published by the Free Software
13896 + * Foundation, either version 2 of that License or (at your option) any
13897 + * later version.
13898 + *
13899 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13900 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13901 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13902 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13903 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13904 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13905 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13906 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13907 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13908 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13909 + */
13910 +
13911 +#ifndef __MAC_H
13912 +#define __MAC_H
13913 +
13914 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
13915 +#include <linux/if_ether.h> /* ETH_ALEN */
13916 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
13917 +#include <linux/list.h>
13918 +
13919 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
13920 +
13921 +enum {DTSEC, XGMAC, MEMAC};
13922 +
13923 +struct mac_device {
13924 + struct device *dev;
13925 + void *priv;
13926 + uint8_t cell_index;
13927 + struct resource *res;
13928 + void __iomem *vaddr;
13929 + uint8_t addr[ETH_ALEN];
13930 + bool promisc;
13931 +
13932 + struct fm *fm_dev;
13933 + struct fm_port *port_dev[2];
13934 +
13935 + phy_interface_t phy_if;
13936 + u32 if_support;
13937 + bool link;
13938 + bool half_duplex;
13939 + uint16_t speed;
13940 + uint16_t max_speed;
13941 + struct device_node *phy_node;
13942 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
13943 + struct device_node *tbi_node;
13944 + struct phy_device *phy_dev;
13945 + void *fm;
13946 + /* List of multicast addresses */
13947 + struct list_head mc_addr_list;
13948 + struct fixed_phy_status *fixed_link;
13949 +
13950 + bool autoneg_pause;
13951 + bool rx_pause_req;
13952 + bool tx_pause_req;
13953 + bool rx_pause_active;
13954 + bool tx_pause_active;
13955 +
13956 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
13957 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
13958 + int (*init)(struct mac_device *mac_dev);
13959 + int (*start)(struct mac_device *mac_dev);
13960 + int (*stop)(struct mac_device *mac_dev);
13961 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
13962 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
13963 + int (*set_multi)(struct net_device *net_dev,
13964 + struct mac_device *mac_dev);
13965 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
13966 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
13967 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
13968 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
13969 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
13970 + int (*fm_rtc_enable)(struct fm *fm_dev);
13971 + int (*fm_rtc_disable)(struct fm *fm_dev);
13972 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
13973 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
13974 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
13975 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
13976 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
13977 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
13978 + uint64_t fiper);
13979 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
13980 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
13981 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
13982 +#endif
13983 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
13984 + bool en);
13985 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
13986 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
13987 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
13988 +};
13989 +
13990 +struct mac_address {
13991 + uint8_t addr[ETH_ALEN];
13992 + struct list_head list;
13993 +};
13994 +
13995 +#define get_fm_handle(net_dev) \
13996 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
13997 +
13998 +#define for_each_port_device(i, port_dev) \
13999 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
14000 +
14001 +static inline __attribute((nonnull)) void *macdev_priv(
14002 + const struct mac_device *mac_dev)
14003 +{
14004 + return (void *)mac_dev + sizeof(*mac_dev);
14005 +}
14006 +
14007 +extern const char *mac_driver_description;
14008 +extern const size_t mac_sizeof_priv[];
14009 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
14010 +
14011 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
14012 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
14013 +
14014 +#endif /* __MAC_H */
14015 --- /dev/null
14016 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
14017 @@ -0,0 +1,848 @@
14018 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
14019 + *
14020 + * Redistribution and use in source and binary forms, with or without
14021 + * modification, are permitted provided that the following conditions are met:
14022 + * * Redistributions of source code must retain the above copyright
14023 + * notice, this list of conditions and the following disclaimer.
14024 + * * Redistributions in binary form must reproduce the above copyright
14025 + * notice, this list of conditions and the following disclaimer in the
14026 + * documentation and/or other materials provided with the distribution.
14027 + * * Neither the name of Freescale Semiconductor nor the
14028 + * names of its contributors may be used to endorse or promote products
14029 + * derived from this software without specific prior written permission.
14030 + *
14031 + *
14032 + * ALTERNATIVELY, this software may be distributed under the terms of the
14033 + * GNU General Public License ("GPL") as published by the Free Software
14034 + * Foundation, either version 2 of that License or (at your option) any
14035 + * later version.
14036 + *
14037 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14038 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14039 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14040 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14041 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14042 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14043 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14044 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14045 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14046 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14047 + */
14048 +
14049 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
14050 + * Validates device-tree configuration and sets up the offline ports.
14051 + */
14052 +
14053 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
14054 +#define pr_fmt(fmt) \
14055 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
14056 + KBUILD_BASENAME".c", __LINE__, __func__
14057 +#else
14058 +#define pr_fmt(fmt) \
14059 + KBUILD_MODNAME ": " fmt
14060 +#endif
14061 +
14062 +
14063 +#include <linux/init.h>
14064 +#include <linux/module.h>
14065 +#include <linux/of_platform.h>
14066 +#include <linux/fsl_qman.h>
14067 +
14068 +#include "offline_port.h"
14069 +#include "dpaa_eth.h"
14070 +#include "dpaa_eth_common.h"
14071 +
14072 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
14073 +/* Manip extra space and data alignment for fragmentation */
14074 +#define FRAG_MANIP_SPACE 128
14075 +#define FRAG_DATA_ALIGN 64
14076 +
14077 +
14078 +MODULE_LICENSE("Dual BSD/GPL");
14079 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
14080 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
14081 +
14082 +
14083 +static const struct of_device_id oh_port_match_table[] = {
14084 + {
14085 + .compatible = "fsl,dpa-oh"
14086 + },
14087 + {
14088 + .compatible = "fsl,dpa-oh-shared"
14089 + },
14090 + {}
14091 +};
14092 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
14093 +
14094 +#ifdef CONFIG_PM
14095 +
14096 +static int oh_suspend(struct device *dev)
14097 +{
14098 + struct dpa_oh_config_s *oh_config;
14099 +
14100 + oh_config = dev_get_drvdata(dev);
14101 + return fm_port_suspend(oh_config->oh_port);
14102 +}
14103 +
14104 +static int oh_resume(struct device *dev)
14105 +{
14106 + struct dpa_oh_config_s *oh_config;
14107 +
14108 + oh_config = dev_get_drvdata(dev);
14109 + return fm_port_resume(oh_config->oh_port);
14110 +}
14111 +
14112 +static const struct dev_pm_ops oh_pm_ops = {
14113 + .suspend = oh_suspend,
14114 + .resume = oh_resume,
14115 +};
14116 +
14117 +#define OH_PM_OPS (&oh_pm_ops)
14118 +
14119 +#else /* CONFIG_PM */
14120 +
14121 +#define OH_PM_OPS NULL
14122 +
14123 +#endif /* CONFIG_PM */
14124 +
14125 +/* Creates Frame Queues */
14126 +static uint32_t oh_fq_create(struct qman_fq *fq,
14127 + uint32_t fq_id, uint16_t channel,
14128 + uint16_t wq_id)
14129 +{
14130 + struct qm_mcc_initfq fq_opts;
14131 + uint32_t create_flags, init_flags;
14132 + uint32_t ret = 0;
14133 +
14134 + if (fq == NULL)
14135 + return 1;
14136 +
14137 + /* Set flags for FQ create */
14138 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
14139 +
14140 + /* Create frame queue */
14141 + ret = qman_create_fq(fq_id, create_flags, fq);
14142 + if (ret != 0)
14143 + return 1;
14144 +
14145 + /* Set flags for FQ init */
14146 + init_flags = QMAN_INITFQ_FLAG_SCHED;
14147 +
14148 + /* Set FQ init options. Specify destination WQ ID and channel */
14149 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
14150 + fq_opts.fqd.dest.wq = wq_id;
14151 + fq_opts.fqd.dest.channel = channel;
14152 +
14153 + /* Initialize frame queue */
14154 + ret = qman_init_fq(fq, init_flags, &fq_opts);
14155 + if (ret != 0) {
14156 + qman_destroy_fq(fq, 0);
14157 + return 1;
14158 + }
14159 +
14160 + return 0;
14161 +}
14162 +
14163 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
14164 +{
14165 + if (channel) {
14166 + /* display fqs with a valid (!= 0) destination channel */
14167 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
14168 + }
14169 +}
14170 +
14171 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
14172 + int fqs_count, uint16_t channel_id)
14173 +{
14174 + int i;
14175 + for (i = 0; i < fqs_count; i++)
14176 + dump_fq(dev, (fqs + i)->fqid, channel_id);
14177 +}
14178 +
14179 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
14180 +{
14181 + struct list_head *fq_list;
14182 + struct fq_duple *fqd;
14183 + int i;
14184 +
14185 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
14186 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
14187 +
14188 + /* TX queues (old initialization) */
14189 + dev_info(dev, "Initialized queues:");
14190 + for (i = 0; i < conf->egress_cnt; i++)
14191 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
14192 + conf->channel);
14193 +
14194 + /* initialized ingress queues */
14195 + list_for_each(fq_list, &conf->fqs_ingress_list) {
14196 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14197 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
14198 + }
14199 +
14200 + /* initialized egress queues */
14201 + list_for_each(fq_list, &conf->fqs_egress_list) {
14202 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14203 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
14204 + }
14205 +}
14206 +
14207 +/* Destroys Frame Queues */
14208 +static void oh_fq_destroy(struct qman_fq *fq)
14209 +{
14210 + int _errno = 0;
14211 +
14212 + _errno = qman_retire_fq(fq, NULL);
14213 + if (unlikely(_errno < 0))
14214 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
14215 + KBUILD_BASENAME".c", __LINE__, __func__,
14216 + qman_fq_fqid(fq), _errno);
14217 +
14218 + _errno = qman_oos_fq(fq);
14219 + if (unlikely(_errno < 0)) {
14220 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
14221 + KBUILD_BASENAME".c", __LINE__, __func__,
14222 + qman_fq_fqid(fq), _errno);
14223 + }
14224 +
14225 + qman_destroy_fq(fq, 0);
14226 +}
14227 +
14228 +/* Allocation code for the OH port's PCD frame queues */
14229 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
14230 + uint32_t num,
14231 + uint8_t alignment,
14232 + uint32_t *base_fqid)
14233 +{
14234 + dev_crit(dev, "callback not implemented!\n");
14235 + BUG();
14236 +
14237 + return 0;
14238 +}
14239 +
14240 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
14241 +{
14242 + dev_crit(dev, "callback not implemented!\n");
14243 + BUG();
14244 +
14245 + return 0;
14246 +}
14247 +
14248 +static void oh_set_buffer_layout(struct fm_port *port,
14249 + struct dpa_buffer_layout_s *layout)
14250 +{
14251 + struct fm_port_params params;
14252 +
14253 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
14254 + layout->parse_results = true;
14255 + layout->hash_results = true;
14256 + layout->time_stamp = false;
14257 +
14258 + fm_port_get_buff_layout_ext_params(port, &params);
14259 + layout->manip_extra_space = params.manip_extra_space;
14260 + layout->data_align = params.data_align;
14261 +}
14262 +
14263 +static int
14264 +oh_port_probe(struct platform_device *_of_dev)
14265 +{
14266 + struct device *dpa_oh_dev;
14267 + struct device_node *dpa_oh_node;
14268 + int lenp, _errno = 0, fq_idx, duple_idx;
14269 + int n_size, i, j, ret, duples_count;
14270 + struct platform_device *oh_of_dev;
14271 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
14272 + struct device *oh_dev;
14273 + struct dpa_oh_config_s *oh_config = NULL;
14274 + const __be32 *oh_all_queues;
14275 + const __be32 *channel_ids;
14276 + const __be32 *oh_tx_queues;
14277 + uint32_t queues_count;
14278 + uint32_t crt_fqid_base;
14279 + uint32_t crt_fq_count;
14280 + bool frag_enabled = false;
14281 + struct fm_port_params oh_port_tx_params;
14282 + struct fm_port_pcd_param oh_port_pcd_params;
14283 + struct dpa_buffer_layout_s buf_layout;
14284 +
14285 + /* True if the current partition owns the OH port. */
14286 + bool init_oh_port;
14287 +
14288 + const struct of_device_id *match;
14289 + int crt_ext_pools_count;
14290 + u32 ext_pool_size;
14291 + u32 port_id;
14292 + u32 channel_id;
14293 +
14294 + int channel_ids_count;
14295 + int channel_idx;
14296 + struct fq_duple *fqd;
14297 + struct list_head *fq_list, *fq_list_tmp;
14298 +
14299 + const __be32 *bpool_cfg;
14300 + uint32_t bpid;
14301 +
14302 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
14303 + dpa_oh_dev = &_of_dev->dev;
14304 + dpa_oh_node = dpa_oh_dev->of_node;
14305 + BUG_ON(dpa_oh_node == NULL);
14306 +
14307 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
14308 + if (!match)
14309 + return -EINVAL;
14310 +
14311 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
14312 +
14313 + /* Find the referenced OH node */
14314 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
14315 + if (oh_node == NULL) {
14316 + dev_err(dpa_oh_dev,
14317 + "Can't find OH node referenced from node %s\n",
14318 + dpa_oh_node->full_name);
14319 + return -EINVAL;
14320 + }
14321 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
14322 + match->compatible);
14323 +
14324 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
14325 + if (_errno) {
14326 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
14327 + dpa_oh_node->full_name);
14328 + goto return_kfree;
14329 + }
14330 +
14331 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
14332 + &channel_id);
14333 + if (_errno) {
14334 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
14335 + dpa_oh_node->full_name);
14336 + goto return_kfree;
14337 + }
14338 +
14339 + oh_of_dev = of_find_device_by_node(oh_node);
14340 + BUG_ON(oh_of_dev == NULL);
14341 + oh_dev = &oh_of_dev->dev;
14342 +
14343 + /* The OH port must be initialized exactly once.
14344 + * The following scenarios are of interest:
14345 + * - the node is Linux-private (will always initialize it);
14346 + * - the node is shared between two Linux partitions
14347 + * (only one of them will initialize it);
14348 + * - the node is shared between a Linux and a LWE partition
14349 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
14350 + */
14351 +
14352 + /* Check if the current partition owns the OH port
14353 + * and ought to initialize it. It may be the case that we leave this
14354 + * to another (also Linux) partition.
14355 + */
14356 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
14357 +
14358 + /* If we aren't the "owner" of the OH node, we're done here. */
14359 + if (!init_oh_port) {
14360 + dev_dbg(dpa_oh_dev,
14361 + "Not owning the shared OH port %s, will not initialize it.\n",
14362 + oh_node->full_name);
14363 + of_node_put(oh_node);
14364 + return 0;
14365 + }
14366 +
14367 + /* Allocate OH dev private data */
14368 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
14369 + if (oh_config == NULL) {
14370 + dev_err(dpa_oh_dev,
14371 + "Can't allocate private data for OH node %s referenced from node %s!\n",
14372 + oh_node->full_name, dpa_oh_node->full_name);
14373 + _errno = -ENOMEM;
14374 + goto return_kfree;
14375 + }
14376 +
14377 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
14378 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
14379 +
14380 + /* FQs that enter OH port */
14381 + lenp = 0;
14382 + oh_all_queues = of_get_property(dpa_oh_node,
14383 + "fsl,qman-frame-queues-ingress", &lenp);
14384 + if (lenp % (2 * sizeof(*oh_all_queues))) {
14385 + dev_warn(dpa_oh_dev,
14386 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
14387 + oh_node->full_name, dpa_oh_node->full_name);
14388 + /* just ignore the last unpaired value */
14389 + }
14390 +
14391 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
14392 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
14393 + duples_count);
14394 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
14395 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
14396 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
14397 +
14398 + fqd = devm_kzalloc(dpa_oh_dev,
14399 + sizeof(struct fq_duple), GFP_KERNEL);
14400 + if (!fqd) {
14401 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
14402 + oh_node->full_name,
14403 + dpa_oh_node->full_name);
14404 + _errno = -ENOMEM;
14405 + goto return_kfree;
14406 + }
14407 +
14408 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
14409 + crt_fq_count * sizeof(struct qman_fq),
14410 + GFP_KERNEL);
14411 + if (!fqd->fqs) {
14412 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
14413 + oh_node->full_name,
14414 + dpa_oh_node->full_name);
14415 + _errno = -ENOMEM;
14416 + goto return_kfree;
14417 + }
14418 +
14419 + for (j = 0; j < crt_fq_count; j++)
14420 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
14421 + fqd->fqs_count = crt_fq_count;
14422 + fqd->channel_id = (uint16_t)channel_id;
14423 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
14424 + }
14425 +
14426 + /* create the ingress queues */
14427 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
14428 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14429 +
14430 + for (j = 0; j < fqd->fqs_count; j++) {
14431 + ret = oh_fq_create(fqd->fqs + j,
14432 + (fqd->fqs + j)->fqid,
14433 + fqd->channel_id, 3);
14434 + if (ret != 0) {
14435 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
14436 + (fqd->fqs + j)->fqid,
14437 + oh_node->full_name,
14438 + dpa_oh_node->full_name);
14439 + _errno = -EINVAL;
14440 + goto return_kfree;
14441 + }
14442 + }
14443 + }
14444 +
14445 + /* FQs that exit OH port */
14446 + lenp = 0;
14447 + oh_all_queues = of_get_property(dpa_oh_node,
14448 + "fsl,qman-frame-queues-egress", &lenp);
14449 + if (lenp % (2 * sizeof(*oh_all_queues))) {
14450 + dev_warn(dpa_oh_dev,
14451 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
14452 + oh_node->full_name, dpa_oh_node->full_name);
14453 + /* just ignore the last unpaired value */
14454 + }
14455 +
14456 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
14457 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
14458 + duples_count);
14459 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
14460 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
14461 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
14462 +
14463 + fqd = devm_kzalloc(dpa_oh_dev,
14464 + sizeof(struct fq_duple), GFP_KERNEL);
14465 + if (!fqd) {
14466 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
14467 + oh_node->full_name,
14468 + dpa_oh_node->full_name);
14469 + _errno = -ENOMEM;
14470 + goto return_kfree;
14471 + }
14472 +
14473 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
14474 + crt_fq_count * sizeof(struct qman_fq),
14475 + GFP_KERNEL);
14476 + if (!fqd->fqs) {
14477 + dev_err(dpa_oh_dev,
14478 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
14479 + oh_node->full_name,
14480 + dpa_oh_node->full_name);
14481 + _errno = -ENOMEM;
14482 + goto return_kfree;
14483 + }
14484 +
14485 + for (j = 0; j < crt_fq_count; j++)
14486 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
14487 + fqd->fqs_count = crt_fq_count;
14488 + /* channel ID is specified in another attribute */
14489 + fqd->channel_id = 0;
14490 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
14491 +
14492 + /* allocate the queue */
14493 +
14494 + }
14495 +
14496 + /* channel_ids for FQs that exit OH port */
14497 + lenp = 0;
14498 + channel_ids = of_get_property(dpa_oh_node,
14499 + "fsl,qman-channel-ids-egress", &lenp);
14500 +
14501 + channel_ids_count = lenp / (sizeof(*channel_ids));
14502 + if (channel_ids_count != duples_count) {
14503 + dev_warn(dpa_oh_dev,
14504 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
14505 + oh_node->full_name, dpa_oh_node->full_name);
14506 + /* just ignore the queues that do not have a Channel ID */
14507 + }
14508 +
14509 + channel_idx = 0;
14510 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
14511 + if (channel_idx + 1 > channel_ids_count)
14512 + break;
14513 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14514 + fqd->channel_id =
14515 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
14516 + }
14517 +
14518 + /* create egress queues */
14519 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
14520 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14521 +
14522 + if (fqd->channel_id == 0) {
14523 + /* missing channel id in dts */
14524 + continue;
14525 + }
14526 +
14527 + for (j = 0; j < fqd->fqs_count; j++) {
14528 + ret = oh_fq_create(fqd->fqs + j,
14529 + (fqd->fqs + j)->fqid,
14530 + fqd->channel_id, 3);
14531 + if (ret != 0) {
14532 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
14533 + (fqd->fqs + j)->fqid,
14534 + oh_node->full_name,
14535 + dpa_oh_node->full_name);
14536 + _errno = -EINVAL;
14537 + goto return_kfree;
14538 + }
14539 + }
14540 + }
14541 +
14542 + /* Read FQ ids/nums for the DPA OH node */
14543 + oh_all_queues = of_get_property(dpa_oh_node,
14544 + "fsl,qman-frame-queues-oh", &lenp);
14545 + if (oh_all_queues == NULL) {
14546 + dev_err(dpa_oh_dev,
14547 + "No frame queues have been defined for OH node %s referenced from node %s\n",
14548 + oh_node->full_name, dpa_oh_node->full_name);
14549 + _errno = -EINVAL;
14550 + goto return_kfree;
14551 + }
14552 +
14553 + /* Check that the OH error and default FQs are there */
14554 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
14555 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
14556 + if (queues_count != 2) {
14557 + dev_err(dpa_oh_dev,
14558 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
14559 + oh_node->full_name, dpa_oh_node->full_name);
14560 + _errno = -EINVAL;
14561 + goto return_kfree;
14562 + }
14563 +
14564 + /* Read the FQIDs defined for this OH port */
14565 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
14566 + fq_idx = 0;
14567 +
14568 + /* Error FQID - must be present */
14569 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
14570 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
14571 + if (crt_fq_count != 1) {
14572 + dev_err(dpa_oh_dev,
14573 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
14574 + oh_node->full_name, dpa_oh_node->full_name,
14575 + crt_fq_count);
14576 + _errno = -EINVAL;
14577 + goto return_kfree;
14578 + }
14579 + oh_config->error_fqid = crt_fqid_base;
14580 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
14581 + oh_config->error_fqid, oh_node->full_name);
14582 +
14583 + /* Default FQID - must be present */
14584 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
14585 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
14586 + if (crt_fq_count != 1) {
14587 + dev_err(dpa_oh_dev,
14588 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
14589 + oh_node->full_name, dpa_oh_node->full_name,
14590 + crt_fq_count);
14591 + _errno = -EINVAL;
14592 + goto return_kfree;
14593 + }
14594 + oh_config->default_fqid = crt_fqid_base;
14595 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
14596 + oh_config->default_fqid, oh_node->full_name);
14597 +
14598 + /* TX FQID - presence is optional */
14599 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
14600 + &lenp);
14601 + if (oh_tx_queues == NULL) {
14602 + dev_dbg(dpa_oh_dev,
14603 + "No tx queues have been defined for OH node %s referenced from node %s\n",
14604 + oh_node->full_name, dpa_oh_node->full_name);
14605 + goto config_port;
14606 + }
14607 +
14608 + /* Check that queues-tx has only a base and a count defined */
14609 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
14610 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
14611 + if (queues_count != 1) {
14612 + dev_err(dpa_oh_dev,
14613 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
14614 + oh_node->full_name, dpa_oh_node->full_name);
14615 + _errno = -EINVAL;
14616 + goto return_kfree;
14617 + }
14618 +
14619 + fq_idx = 0;
14620 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
14621 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
14622 + oh_config->egress_cnt = crt_fq_count;
14623 +
14624 + /* Allocate TX queues */
14625 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
14626 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
14627 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
14628 + if (oh_config->egress_fqs == NULL) {
14629 + dev_err(dpa_oh_dev,
14630 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
14631 + oh_node->full_name, dpa_oh_node->full_name);
14632 + _errno = -ENOMEM;
14633 + goto return_kfree;
14634 + }
14635 +
14636 + /* Create TX queues */
14637 + for (i = 0; i < crt_fq_count; i++) {
14638 + ret = oh_fq_create(oh_config->egress_fqs + i,
14639 + crt_fqid_base + i, (uint16_t)channel_id, 3);
14640 + if (ret != 0) {
14641 + dev_err(dpa_oh_dev,
14642 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
14643 + crt_fqid_base + i, oh_node->full_name,
14644 + dpa_oh_node->full_name);
14645 + _errno = -EINVAL;
14646 + goto return_kfree;
14647 + }
14648 + }
14649 +
14650 +config_port:
14651 + /* Get a handle to the fm_port so we can set
14652 + * its configuration params
14653 + */
14654 + oh_config->oh_port = fm_port_bind(oh_dev);
14655 + if (oh_config->oh_port == NULL) {
14656 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
14657 + oh_node->full_name);
14658 + _errno = -EINVAL;
14659 + goto return_kfree;
14660 + }
14661 +
14662 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
14663 +
14664 + /* read the pool handlers */
14665 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
14666 + "fsl,bman-buffer-pools", NULL);
14667 + if (crt_ext_pools_count <= 0) {
14668 + dev_info(dpa_oh_dev,
14669 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
14670 + oh_node->full_name);
14671 + goto init_port;
14672 + }
14673 +
14674 + /* used for reading ext_pool_size*/
14675 + root_node = of_find_node_by_path("/");
14676 + if (root_node == NULL) {
14677 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
14678 + _errno = -EINVAL;
14679 + goto return_kfree;
14680 + }
14681 +
14682 + n_size = of_n_size_cells(root_node);
14683 + of_node_put(root_node);
14684 +
14685 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
14686 + crt_ext_pools_count);
14687 +
14688 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
14689 +
14690 + for (i = 0; i < crt_ext_pools_count; i++) {
14691 + bpool_node = of_parse_phandle(dpa_oh_node,
14692 + "fsl,bman-buffer-pools", i);
14693 + if (bpool_node == NULL) {
14694 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
14695 + _errno = -EINVAL;
14696 + goto return_kfree;
14697 + }
14698 +
14699 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
14700 + if (_errno) {
14701 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
14702 + _errno = -EINVAL;
14703 + goto return_kfree;
14704 + }
14705 +
14706 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
14707 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
14708 +
14709 + bpool_cfg = of_get_property(bpool_node,
14710 + "fsl,bpool-ethernet-cfg", &lenp);
14711 + if (bpool_cfg == NULL) {
14712 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
14713 + _errno = -EINVAL;
14714 + goto return_kfree;
14715 + }
14716 +
14717 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
14718 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
14719 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
14720 + ext_pool_size);
14721 + of_node_put(bpool_node);
14722 +
14723 + }
14724 +
14725 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
14726 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
14727 + goto init_port;
14728 +
14729 + frag_enabled = true;
14730 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
14731 + port_id);
14732 +
14733 +init_port:
14734 + of_node_put(oh_node);
14735 + /* Set Tx params */
14736 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
14737 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
14738 + frag_enabled);
14739 + /* Set PCD params */
14740 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
14741 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
14742 + oh_port_pcd_params.dev = dpa_oh_dev;
14743 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
14744 +
14745 + dev_set_drvdata(dpa_oh_dev, oh_config);
14746 +
14747 + /* Enable the OH port */
14748 + _errno = fm_port_enable(oh_config->oh_port);
14749 + if (_errno)
14750 + goto return_kfree;
14751 +
14752 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
14753 +
14754 + /* print of all referenced & created queues */
14755 + dump_oh_config(dpa_oh_dev, oh_config);
14756 +
14757 + return 0;
14758 +
14759 +return_kfree:
14760 + if (bpool_node)
14761 + of_node_put(bpool_node);
14762 + if (oh_node)
14763 + of_node_put(oh_node);
14764 + if (oh_config && oh_config->egress_fqs)
14765 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
14766 +
14767 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
14768 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14769 + list_del(fq_list);
14770 + devm_kfree(dpa_oh_dev, fqd->fqs);
14771 + devm_kfree(dpa_oh_dev, fqd);
14772 + }
14773 +
14774 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
14775 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14776 + list_del(fq_list);
14777 + devm_kfree(dpa_oh_dev, fqd->fqs);
14778 + devm_kfree(dpa_oh_dev, fqd);
14779 + }
14780 +
14781 + devm_kfree(dpa_oh_dev, oh_config);
14782 + return _errno;
14783 +}
14784 +
14785 +static int __cold oh_port_remove(struct platform_device *_of_dev)
14786 +{
14787 + int _errno = 0, i;
14788 + struct dpa_oh_config_s *oh_config;
14789 +
14790 + pr_info("Removing OH port...\n");
14791 +
14792 + oh_config = dev_get_drvdata(&_of_dev->dev);
14793 + if (oh_config == NULL) {
14794 + pr_err(KBUILD_MODNAME
14795 + ": %s:%hu:%s(): No OH config in device private data!\n",
14796 + KBUILD_BASENAME".c", __LINE__, __func__);
14797 + _errno = -ENODEV;
14798 + goto return_error;
14799 + }
14800 +
14801 + if (oh_config->egress_fqs)
14802 + for (i = 0; i < oh_config->egress_cnt; i++)
14803 + oh_fq_destroy(oh_config->egress_fqs + i);
14804 +
14805 + if (oh_config->oh_port == NULL) {
14806 + pr_err(KBUILD_MODNAME
14807 + ": %s:%hu:%s(): No fm port in device private data!\n",
14808 + KBUILD_BASENAME".c", __LINE__, __func__);
14809 + _errno = -EINVAL;
14810 + goto free_egress_fqs;
14811 + }
14812 +
14813 + _errno = fm_port_disable(oh_config->oh_port);
14814 +
14815 +free_egress_fqs:
14816 + if (oh_config->egress_fqs)
14817 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
14818 + devm_kfree(&_of_dev->dev, oh_config);
14819 + dev_set_drvdata(&_of_dev->dev, NULL);
14820 +
14821 +return_error:
14822 + return _errno;
14823 +}
14824 +
14825 +static struct platform_driver oh_port_driver = {
14826 + .driver = {
14827 + .name = KBUILD_MODNAME,
14828 + .of_match_table = oh_port_match_table,
14829 + .owner = THIS_MODULE,
14830 + .pm = OH_PM_OPS,
14831 + },
14832 + .probe = oh_port_probe,
14833 + .remove = oh_port_remove
14834 +};
14835 +
14836 +static int __init __cold oh_port_load(void)
14837 +{
14838 + int _errno;
14839 +
14840 + pr_info(OH_MOD_DESCRIPTION "\n");
14841 +
14842 + _errno = platform_driver_register(&oh_port_driver);
14843 + if (_errno < 0) {
14844 + pr_err(KBUILD_MODNAME
14845 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
14846 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
14847 + }
14848 +
14849 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
14850 + KBUILD_BASENAME".c", __func__);
14851 + return _errno;
14852 +}
14853 +module_init(oh_port_load);
14854 +
14855 +static void __exit __cold oh_port_unload(void)
14856 +{
14857 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
14858 + KBUILD_BASENAME".c", __func__);
14859 +
14860 + platform_driver_unregister(&oh_port_driver);
14861 +
14862 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
14863 + KBUILD_BASENAME".c", __func__);
14864 +}
14865 +module_exit(oh_port_unload);
14866 --- /dev/null
14867 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
14868 @@ -0,0 +1,59 @@
14869 +/* Copyright 2011 Freescale Semiconductor Inc.
14870 + *
14871 + * Redistribution and use in source and binary forms, with or without
14872 + * modification, are permitted provided that the following conditions are met:
14873 + * * Redistributions of source code must retain the above copyright
14874 + * notice, this list of conditions and the following disclaimer.
14875 + * * Redistributions in binary form must reproduce the above copyright
14876 + * notice, this list of conditions and the following disclaimer in the
14877 + * documentation and/or other materials provided with the distribution.
14878 + * * Neither the name of Freescale Semiconductor nor the
14879 + * names of its contributors may be used to endorse or promote products
14880 + * derived from this software without specific prior written permission.
14881 + *
14882 + *
14883 + * ALTERNATIVELY, this software may be distributed under the terms of the
14884 + * GNU General Public License ("GPL") as published by the Free Software
14885 + * Foundation, either version 2 of that License or (at your option) any
14886 + * later version.
14887 + *
14888 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14889 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14890 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14891 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14892 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14893 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14894 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14895 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14896 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14897 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14898 + */
14899 +
14900 +#ifndef __OFFLINE_PORT_H
14901 +#define __OFFLINE_PORT_H
14902 +
14903 +struct fm_port;
14904 +struct qman_fq;
14905 +
14906 +/* fqs are defined in duples (base_fq, fq_count) */
14907 +struct fq_duple {
14908 + struct qman_fq *fqs;
14909 + int fqs_count;
14910 + uint16_t channel_id;
14911 + struct list_head fq_list;
14912 +};
14913 +
14914 +/* OH port configuration */
14915 +struct dpa_oh_config_s {
14916 + uint32_t error_fqid;
14917 + uint32_t default_fqid;
14918 + struct fm_port *oh_port;
14919 + uint32_t egress_cnt;
14920 + struct qman_fq *egress_fqs;
14921 + uint16_t channel;
14922 +
14923 + struct list_head fqs_ingress_list;
14924 + struct list_head fqs_egress_list;
14925 +};
14926 +
14927 +#endif /* __OFFLINE_PORT_H */
14928 --- /dev/null
14929 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
14930 @@ -0,0 +1,153 @@
14931 +menu "Frame Manager support"
14932 +
14933 +menuconfig FSL_SDK_FMAN
14934 + bool "Freescale Frame Manager (datapath) support - SDK driver"
14935 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
14936 + default y
14937 + ---help---
14938 + If unsure, say Y.
14939 +
14940 +if FSL_SDK_FMAN
14941 +
14942 +config FSL_SDK_FMAN_TEST
14943 + bool "FMan test module"
14944 + default n
14945 + select FSL_DPAA_HOOKS
14946 + ---help---
14947 + This option compiles test code for FMan.
14948 +
14949 +menu "FMAN Processor support"
14950 +choice
14951 + depends on FSL_SDK_FMAN
14952 + prompt "Processor Type"
14953 +
14954 +config FMAN_ARM
14955 + bool "LS1043"
14956 + depends on ARM64 || ARM
14957 + ---help---
14958 + Choose "LS1043" for the ARM platforms:
14959 + LS1043
14960 +
14961 +config FMAN_P3040_P4080_P5020
14962 + bool "P3040 P4080 5020"
14963 +
14964 +config FMAN_P1023
14965 + bool "P1023"
14966 +
14967 +config FMAN_V3H
14968 + bool "FmanV3H"
14969 + ---help---
14970 + Choose "FmanV3H" for Fman rev3H:
14971 + B4860, T4240, T4160, etc
14972 +
14973 +config FMAN_V3L
14974 + bool "FmanV3L"
14975 + ---help---
14976 + Choose "FmanV3L" for Fman rev3L:
14977 + T1040, T1042, T1020, T1022, T1023, T1024, etc
14978 +
14979 +endchoice
14980 +endmenu
14981 +
14982 +config FMAN_MIB_CNT_OVF_IRQ_EN
14983 + bool "Enable the dTSEC MIB counters overflow interrupt"
14984 + default n
14985 + ---help---
14986 + Enable the dTSEC MIB counters overflow interrupt to get
14987 + accurate MIB counters values. Enabled it compensates
14988 + for the counters overflow but reduces performance and
14989 + triggers error messages in HV setups.
14990 +
14991 +config FSL_FM_MAX_FRAME_SIZE
14992 + int "Maximum L2 frame size"
14993 + depends on FSL_SDK_FMAN
14994 + range 64 9600
14995 + default "1522"
14996 + help
14997 + Configure this in relation to the maximum possible MTU of your
14998 + network configuration. In particular, one would need to
14999 + increase this value in order to use jumbo frames.
15000 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
15001 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
15002 + excess of the desired L3 MTU.
15003 +
15004 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
15005 + than the actual MTU) may lead to buffer exhaustion, especially
15006 + in the case of badly fragmented datagrams on the Rx path.
15007 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
15008 + MTU will lead to frames being dropped.
15009 +
15010 + This can be overridden by specifying "fsl_fm_max_frm" in
15011 + the kernel bootargs:
15012 + * in Hypervisor-based scenarios, by adding a "chosen" node
15013 + with the "bootargs" property specifying
15014 + "fsl_fm_max_frm=<YourValue>";
15015 + * in non-Hypervisor-based scenarios, via u-boot's env, by
15016 + modifying the "bootargs" env variable.
15017 +
15018 +config FSL_FM_RX_EXTRA_HEADROOM
15019 + int "Add extra headroom at beginning of data buffers"
15020 + depends on FSL_SDK_FMAN
15021 + range 16 384
15022 + default "64"
15023 + help
15024 + Configure this to tell the Frame Manager to reserve some extra
15025 + space at the beginning of a data buffer on the receive path,
15026 + before Internal Context fields are copied. This is in addition
15027 + to the private data area already reserved for driver internal
15028 + use. The provided value must be a multiple of 16.
15029 +
15030 + This setting can be overridden by specifying
15031 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
15032 + * in Hypervisor-based scenarios, by adding a "chosen" node
15033 + with the "bootargs" property specifying
15034 + "fsl_fm_rx_extra_headroom=<YourValue>";
15035 + * in non-Hypervisor-based scenarios, via u-boot's env, by
15036 + modifying the "bootargs" env variable.
15037 +
15038 +config FMAN_PFC
15039 + bool "FMan PFC support (EXPERIMENTAL)"
15040 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
15041 + default n
15042 + help
15043 + This option enables PFC support on FMan v3 ports.
15044 + Data Center Bridging defines Classes of Service that are
15045 + flow-controlled using PFC pause frames.
15046 +
15047 +if FMAN_PFC
15048 +config FMAN_PFC_COS_COUNT
15049 + int "Number of PFC Classes of Service"
15050 + depends on FMAN_PFC && FSL_SDK_FMAN
15051 + range 1 4
15052 + default "3"
15053 + help
15054 + The number of Classes of Service controlled by PFC.
15055 +
15056 +config FMAN_PFC_QUANTA_0
15057 + int "The pause quanta for PFC CoS 0"
15058 + depends on FMAN_PFC && FSL_SDK_FMAN
15059 + range 0 65535
15060 + default "65535"
15061 +
15062 +config FMAN_PFC_QUANTA_1
15063 + int "The pause quanta for PFC CoS 1"
15064 + depends on FMAN_PFC && FSL_SDK_FMAN
15065 + range 0 65535
15066 + default "65535"
15067 +
15068 +config FMAN_PFC_QUANTA_2
15069 + int "The pause quanta for PFC CoS 2"
15070 + depends on FMAN_PFC && FSL_SDK_FMAN
15071 + range 0 65535
15072 + default "65535"
15073 +
15074 +config FMAN_PFC_QUANTA_3
15075 + int "The pause quanta for PFC CoS 3"
15076 + depends on FMAN_PFC && FSL_SDK_FMAN
15077 + range 0 65535
15078 + default "65535"
15079 +endif
15080 +
15081 +endif # FSL_SDK_FMAN
15082 +
15083 +endmenu
15084 --- /dev/null
15085 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
15086 @@ -0,0 +1,11 @@
15087 +#
15088 +# Makefile for the Freescale Ethernet controllers
15089 +#
15090 +ccflags-y += -DVERSION=\"\"
15091 +#
15092 +#Include netcomm SW specific definitions
15093 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
15094 +#
15095 +obj-y += etc/
15096 +obj-y += Peripherals/FM/
15097 +obj-y += src/
15098 --- /dev/null
15099 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
15100 @@ -0,0 +1,15 @@
15101 +#
15102 +# Makefile for the Freescale Ethernet controllers
15103 +#
15104 +ccflags-y += -DVERSION=\"\"
15105 +#
15106 +#Include netcomm SW specific definitions
15107 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
15108 +
15109 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
15110 +
15111 +ccflags-y += -I$(NCSW_FM_INC)
15112 +
15113 +obj-y += fsl-ncsw-Hc.o
15114 +
15115 +fsl-ncsw-Hc-objs := hc.o
15116 --- /dev/null
15117 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
15118 @@ -0,0 +1,1232 @@
15119 +/*
15120 + * Copyright 2008-2012 Freescale Semiconductor Inc.
15121 + *
15122 + * Redistribution and use in source and binary forms, with or without
15123 + * modification, are permitted provided that the following conditions are met:
15124 + * * Redistributions of source code must retain the above copyright
15125 + * notice, this list of conditions and the following disclaimer.
15126 + * * Redistributions in binary form must reproduce the above copyright
15127 + * notice, this list of conditions and the following disclaimer in the
15128 + * documentation and/or other materials provided with the distribution.
15129 + * * Neither the name of Freescale Semiconductor nor the
15130 + * names of its contributors may be used to endorse or promote products
15131 + * derived from this software without specific prior written permission.
15132 + *
15133 + *
15134 + * ALTERNATIVELY, this software may be distributed under the terms of the
15135 + * GNU General Public License ("GPL") as published by the Free Software
15136 + * Foundation, either version 2 of that License or (at your option) any
15137 + * later version.
15138 + *
15139 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
15140 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15141 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15142 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
15143 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15144 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15145 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15146 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15147 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15148 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15149 + */
15150 +
15151 +
15152 +#include "std_ext.h"
15153 +#include "error_ext.h"
15154 +#include "sprint_ext.h"
15155 +#include "string_ext.h"
15156 +
15157 +#include "fm_common.h"
15158 +#include "fm_hc.h"
15159 +
15160 +
15161 +/**************************************************************************//**
15162 + @Description defaults
15163 +*//***************************************************************************/
15164 +#define DEFAULT_dataMemId 0
15165 +
15166 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
15167 +#define HC_HCOR_OPCODE_KG_SCM 0x1
15168 +#define HC_HCOR_OPCODE_SYNC 0x2
15169 +#define HC_HCOR_OPCODE_CC 0x3
15170 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
15171 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
15172 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
15173 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
15174 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
15175 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
15176 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
15177 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
15178 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
15179 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
15180 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
15181 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
15182 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
15183 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
15184 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
15185 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
15186 +
15187 +#define HC_HCOR_GBL 0x20000000
15188 +
15189 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
15190 +
15191 +#if (DPAA_VERSION == 10)
15192 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
15193 +#else
15194 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
15195 +#endif /* (DPAA_VERSION == 10) */
15196 +
15197 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
15198 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
15199 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
15200 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
15201 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
15202 +
15203 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
15204 +
15205 +#define BUILD_FD(len) \
15206 +do { \
15207 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
15208 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
15209 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
15210 + DPAA_FD_SET_LENGTH(&fmFd, len); \
15211 +} while (0)
15212 +
15213 +
15214 +#if defined(__MWERKS__) && !defined(__GNUC__)
15215 +#pragma pack(push,1)
15216 +#endif /* defined(__MWERKS__) && ... */
15217 +
15218 +typedef struct t_FmPcdKgPortRegs {
15219 + volatile uint32_t spReg;
15220 + volatile uint32_t cppReg;
15221 +} t_FmPcdKgPortRegs;
15222 +
15223 +typedef struct t_HcFrame {
15224 + volatile uint32_t opcode;
15225 + volatile uint32_t actionReg;
15226 + volatile uint32_t extraReg;
15227 + volatile uint32_t commandSequence;
15228 + union {
15229 + struct fman_kg_scheme_regs schemeRegs;
15230 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
15231 + t_FmPcdPlcrProfileRegs profileRegs;
15232 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
15233 + t_FmPcdKgPortRegs portRegsForRead;
15234 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
15235 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
15236 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
15237 + } hcSpecificData;
15238 +} t_HcFrame;
15239 +
15240 +#if defined(__MWERKS__) && !defined(__GNUC__)
15241 +#pragma pack(pop)
15242 +#endif /* defined(__MWERKS__) && ... */
15243 +
15244 +
15245 +typedef struct t_FmHc {
15246 + t_Handle h_FmPcd;
15247 + t_Handle h_HcPortDev;
15248 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
15249 + t_Handle h_QmArg; /**< A handle to the QM module */
15250 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
15251 +
15252 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
15253 + taking buffer */
15254 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
15255 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
15256 + and not confirmed yet */
15257 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
15258 +} t_FmHc;
15259 +
15260 +
15261 +static t_Error FillBufPool(t_FmHc *p_FmHc)
15262 +{
15263 + uint32_t i;
15264 +
15265 + ASSERT_COND(p_FmHc);
15266 +
15267 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
15268 + {
15269 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
15270 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
15271 + p_FmHc->dataMemId,
15272 + 16);
15273 +#else
15274 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
15275 + p_FmHc->dataMemId,
15276 + 16);
15277 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
15278 + if (!p_FmHc->p_Frm[i])
15279 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
15280 + }
15281 +
15282 + /* Initialize FIFO of seqNum to use during GetBuf */
15283 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
15284 + {
15285 + p_FmHc->seqNum[i] = i;
15286 + }
15287 + p_FmHc->nextSeqNumLocation = 0;
15288 +
15289 + return E_OK;
15290 +}
15291 +
15292 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
15293 +{
15294 + uint32_t intFlags;
15295 +
15296 + ASSERT_COND(p_FmHc);
15297 +
15298 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15299 +
15300 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
15301 + {
15302 + /* No more buffers */
15303 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15304 + return NULL;
15305 + }
15306 +
15307 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
15308 + p_FmHc->nextSeqNumLocation++;
15309 +
15310 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15311 + return p_FmHc->p_Frm[*p_SeqNum];
15312 +}
15313 +
15314 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
15315 +{
15316 + uint32_t intFlags;
15317 +
15318 + UNUSED(p_Buf);
15319 +
15320 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15321 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
15322 + p_FmHc->nextSeqNumLocation--;
15323 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
15324 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15325 +}
15326 +
15327 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
15328 +{
15329 + t_Error err = E_OK;
15330 + uint32_t intFlags;
15331 + uint32_t timeout=100;
15332 +
15333 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15334 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
15335 + p_FmHc->enqueued[seqNum] = TRUE;
15336 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15337 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
15338 + seqNum,
15339 + DPAA_FD_GET_ADDR(p_FmFd),
15340 + DPAA_FD_GET_OFFSET(p_FmFd)));
15341 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
15342 + if (err)
15343 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
15344 +
15345 + while (p_FmHc->enqueued[seqNum] && --timeout)
15346 + XX_UDelay(100);
15347 +
15348 + if (!timeout)
15349 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
15350 +
15351 + return err;
15352 +}
15353 +
15354 +
15355 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
15356 +{
15357 + t_FmHc *p_FmHc;
15358 + t_FmPortParams fmPortParam;
15359 + t_Error err;
15360 +
15361 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
15362 + if (!p_FmHc)
15363 + {
15364 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
15365 + return NULL;
15366 + }
15367 + memset(p_FmHc,0,sizeof(t_FmHc));
15368 +
15369 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
15370 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
15371 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
15372 + p_FmHc->dataMemId = DEFAULT_dataMemId;
15373 +
15374 + err = FillBufPool(p_FmHc);
15375 + if (err != E_OK)
15376 + {
15377 + REPORT_ERROR(MAJOR, err, NO_MSG);
15378 + FmHcFree(p_FmHc);
15379 + return NULL;
15380 + }
15381 +
15382 + if (!FmIsMaster(p_FmHcParams->h_Fm))
15383 + return (t_Handle)p_FmHc;
15384 +
15385 + memset(&fmPortParam, 0, sizeof(fmPortParam));
15386 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
15387 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
15388 + fmPortParam.portId = p_FmHcParams->params.portId;
15389 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
15390 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
15391 +
15392 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
15393 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
15394 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
15395 +
15396 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
15397 + if (!p_FmHc->h_HcPortDev)
15398 + {
15399 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
15400 + XX_Free(p_FmHc);
15401 + return NULL;
15402 + }
15403 +
15404 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
15405 + (uint16_t)sizeof(t_HcFrame));
15406 +
15407 + if (err != E_OK)
15408 + {
15409 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
15410 + FmHcFree(p_FmHc);
15411 + return NULL;
15412 + }
15413 +
15414 + /* final init */
15415 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
15416 + if (err != E_OK)
15417 + {
15418 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
15419 + FmHcFree(p_FmHc);
15420 + return NULL;
15421 + }
15422 +
15423 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
15424 + if (err != E_OK)
15425 + {
15426 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
15427 + FmHcFree(p_FmHc);
15428 + return NULL;
15429 + }
15430 +
15431 + return (t_Handle)p_FmHc;
15432 +}
15433 +
15434 +void FmHcFree(t_Handle h_FmHc)
15435 +{
15436 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15437 + int i;
15438 +
15439 + if (!p_FmHc)
15440 + return;
15441 +
15442 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
15443 + if (p_FmHc->p_Frm[i])
15444 + XX_FreeSmart(p_FmHc->p_Frm[i]);
15445 + else
15446 + break;
15447 +
15448 + if (p_FmHc->h_HcPortDev)
15449 + FM_PORT_Free(p_FmHc->h_HcPortDev);
15450 +
15451 + XX_Free(p_FmHc);
15452 +}
15453 +
15454 +/*****************************************************************************/
15455 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
15456 + uint8_t memId)
15457 +{
15458 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15459 + int i;
15460 +
15461 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
15462 +
15463 + p_FmHc->dataMemId = memId;
15464 +
15465 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
15466 + if (p_FmHc->p_Frm[i])
15467 + XX_FreeSmart(p_FmHc->p_Frm[i]);
15468 +
15469 + return FillBufPool(p_FmHc);
15470 +}
15471 +
15472 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
15473 +{
15474 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15475 + t_HcFrame *p_HcFrame;
15476 + uint32_t intFlags;
15477 +
15478 + ASSERT_COND(p_FmHc);
15479 +
15480 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15481 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
15482 +
15483 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
15484 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
15485 +
15486 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
15487 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
15488 + else
15489 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
15490 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15491 +}
15492 +
15493 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
15494 + t_Handle h_Scheme,
15495 + struct fman_kg_scheme_regs *p_SchemeRegs,
15496 + bool updateCounter)
15497 +{
15498 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15499 + t_Error err = E_OK;
15500 + t_HcFrame *p_HcFrame;
15501 + t_DpaaFD fmFd;
15502 + uint8_t physicalSchemeId;
15503 + uint32_t seqNum;
15504 +
15505 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15506 + if (!p_HcFrame)
15507 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15508 +
15509 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15510 +
15511 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15512 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15513 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
15514 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15515 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
15516 + if (!updateCounter)
15517 + {
15518 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
15519 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
15520 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
15521 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
15522 + }
15523 + p_HcFrame->commandSequence = seqNum;
15524 +
15525 + BUILD_FD(sizeof(t_HcFrame));
15526 +
15527 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15528 +
15529 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15530 +
15531 + if (err != E_OK)
15532 + RETURN_ERROR(MINOR, err, NO_MSG);
15533 +
15534 + return E_OK;
15535 +}
15536 +
15537 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
15538 +{
15539 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15540 + t_Error err = E_OK;
15541 + t_HcFrame *p_HcFrame;
15542 + t_DpaaFD fmFd;
15543 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15544 + uint32_t seqNum;
15545 +
15546 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15547 + if (!p_HcFrame)
15548 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15549 +
15550 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15551 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15552 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
15553 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15554 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
15555 + p_HcFrame->commandSequence = seqNum;
15556 +
15557 + BUILD_FD(sizeof(t_HcFrame));
15558 +
15559 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15560 +
15561 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15562 +
15563 + if (err != E_OK)
15564 + RETURN_ERROR(MINOR, err, NO_MSG);
15565 +
15566 + return E_OK;
15567 +}
15568 +
15569 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
15570 +{
15571 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15572 + t_Error err = E_OK;
15573 + t_HcFrame *p_HcFrame;
15574 + t_DpaaFD fmFd;
15575 + uint8_t relativeSchemeId;
15576 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15577 + uint32_t tmpReg32 = 0;
15578 + uint32_t seqNum;
15579 +
15580 + /* Scheme is locked by calling routine */
15581 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
15582 + * "kgse_mode" or "kgse_om" without locking scheme !
15583 + */
15584 +
15585 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
15586 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
15587 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
15588 +
15589 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
15590 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
15591 + {
15592 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
15593 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
15594 + {
15595 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
15596 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
15597 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
15598 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
15599 + if (err)
15600 + RETURN_ERROR(MAJOR, err, NO_MSG);
15601 + }
15602 + else /* From here we deal with KG-Schemes only */
15603 + {
15604 + /* Pre change general code */
15605 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15606 + if (!p_HcFrame)
15607 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15608 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15609 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15610 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
15611 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15612 + p_HcFrame->commandSequence = seqNum;
15613 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
15614 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15615 + {
15616 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15617 + RETURN_ERROR(MINOR, err, NO_MSG);
15618 + }
15619 +
15620 + /* specific change */
15621 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
15622 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
15623 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
15624 + {
15625 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
15626 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
15627 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
15628 + }
15629 +
15630 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
15631 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
15632 + {
15633 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
15634 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
15635 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
15636 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
15637 + }
15638 +
15639 + if (requiredAction & UPDATE_KG_OPT_MODE)
15640 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
15641 +
15642 + if (requiredAction & UPDATE_KG_NIA)
15643 + {
15644 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
15645 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
15646 + tmpReg32 |= value;
15647 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
15648 + }
15649 +
15650 + /* Post change general code */
15651 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15652 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
15653 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15654 +
15655 + BUILD_FD(sizeof(t_HcFrame));
15656 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15657 +
15658 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15659 +
15660 + if (err != E_OK)
15661 + RETURN_ERROR(MINOR, err, NO_MSG);
15662 + }
15663 + }
15664 +
15665 + return E_OK;
15666 +}
15667 +
15668 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
15669 +{
15670 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15671 + t_Error err;
15672 + t_HcFrame *p_HcFrame;
15673 + t_DpaaFD fmFd;
15674 + uint32_t retVal;
15675 + uint8_t relativeSchemeId;
15676 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15677 + uint32_t seqNum;
15678 +
15679 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
15680 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
15681 + {
15682 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
15683 + return 0;
15684 + }
15685 +
15686 + /* first read scheme and check that it is valid */
15687 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15688 + if (!p_HcFrame)
15689 + {
15690 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15691 + return 0;
15692 + }
15693 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15694 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15695 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
15696 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15697 + p_HcFrame->commandSequence = seqNum;
15698 +
15699 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
15700 +
15701 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15702 + if (err != E_OK)
15703 + {
15704 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15705 + REPORT_ERROR(MINOR, err, NO_MSG);
15706 + return 0;
15707 + }
15708 +
15709 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
15710 + {
15711 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15712 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
15713 + return 0;
15714 + }
15715 +
15716 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
15717 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15718 +
15719 + return retVal;
15720 +}
15721 +
15722 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
15723 +{
15724 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15725 + t_Error err = E_OK;
15726 + t_HcFrame *p_HcFrame;
15727 + t_DpaaFD fmFd;
15728 + uint8_t relativeSchemeId, physicalSchemeId;
15729 + uint32_t seqNum;
15730 +
15731 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15732 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
15733 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
15734 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
15735 +
15736 + /* first read scheme and check that it is valid */
15737 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15738 + if (!p_HcFrame)
15739 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15740 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15741 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15742 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
15743 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
15744 + /* write counter */
15745 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
15746 + p_HcFrame->commandSequence = seqNum;
15747 +
15748 + BUILD_FD(sizeof(t_HcFrame));
15749 +
15750 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15751 +
15752 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15753 + return err;
15754 +}
15755 +
15756 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
15757 +{
15758 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15759 + t_HcFrame *p_HcFrame;
15760 + t_DpaaFD fmFd;
15761 + uint8_t i, idx;
15762 + uint32_t seqNum;
15763 + t_Error err = E_OK;
15764 +
15765 + ASSERT_COND(p_FmHc);
15766 +
15767 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15768 + if (!p_HcFrame)
15769 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15770 +
15771 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
15772 + {
15773 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15774 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15775 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
15776 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15777 +
15778 + idx = (uint8_t)(i - p_Set->baseEntry);
15779 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
15780 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
15781 + p_HcFrame->commandSequence = seqNum;
15782 +
15783 + BUILD_FD(sizeof(t_HcFrame));
15784 +
15785 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15786 + {
15787 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15788 + RETURN_ERROR(MINOR, err, NO_MSG);
15789 + }
15790 + }
15791 +
15792 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15793 + return err;
15794 +}
15795 +
15796 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
15797 +{
15798 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15799 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
15800 +
15801 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
15802 + if (!p_ClsPlanSet)
15803 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
15804 +
15805 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
15806 +
15807 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
15808 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
15809 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
15810 +
15811 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
15812 + {
15813 + XX_Free(p_ClsPlanSet);
15814 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
15815 + }
15816 +
15817 + XX_Free(p_ClsPlanSet);
15818 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
15819 +
15820 + return E_OK;
15821 +}
15822 +
15823 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
15824 +{
15825 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15826 + t_HcFrame *p_HcFrame;
15827 + t_DpaaFD fmFd;
15828 + t_Error err;
15829 + uint32_t seqNum;
15830 +
15831 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
15832 +
15833 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15834 + if (!p_HcFrame)
15835 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15836 +
15837 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15838 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
15839 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
15840 + p_HcFrame->commandSequence = seqNum;
15841 + BUILD_FD(sizeof(t_HcFrame));
15842 +
15843 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15844 +
15845 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15846 + return err;
15847 +}
15848 +
15849 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
15850 +{
15851 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15852 + t_HcFrame *p_HcFrame;
15853 + t_DpaaFD fmFd;
15854 + t_Error err;
15855 + uint32_t seqNum;
15856 +
15857 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
15858 +
15859 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15860 + if (!p_HcFrame)
15861 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15862 +
15863 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15864 +
15865 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
15866 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
15867 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
15868 + if (fill == TRUE)
15869 + {
15870 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
15871 + }
15872 + p_HcFrame->commandSequence = seqNum;
15873 +
15874 + BUILD_FD(sizeof(t_HcFrame));
15875 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15876 + {
15877 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15878 + RETURN_ERROR(MINOR, err, NO_MSG);
15879 + }
15880 +
15881 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
15882 +
15883 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15884 + return E_OK;
15885 +}
15886 +
15887 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
15888 +{
15889 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15890 + t_HcFrame *p_HcFrame;
15891 + t_DpaaFD fmFd;
15892 + t_Error err;
15893 + uint32_t seqNum;
15894 +
15895 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
15896 +
15897 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15898 + if (!p_HcFrame)
15899 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15900 +
15901 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15902 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
15903 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
15904 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
15905 + p_HcFrame->commandSequence = seqNum;
15906 +
15907 + BUILD_FD(sizeof(t_HcFrame));
15908 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15909 + {
15910 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15911 + RETURN_ERROR(MINOR, err, NO_MSG);
15912 + }
15913 +
15914 + *p_Result = (uint8_t)
15915 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
15916 +
15917 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15918 + return E_OK;
15919 +}
15920 +
15921 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
15922 +{
15923 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15924 + t_HcFrame *p_HcFrame;
15925 + t_DpaaFD fmFd;
15926 + t_Error err;
15927 + uint32_t tmpReg32 = 0;
15928 + uint32_t requiredActionTmp, requiredActionFlag;
15929 + uint32_t seqNum;
15930 +
15931 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
15932 +
15933 + /* Profile is locked by calling routine */
15934 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
15935 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
15936 + */
15937 +
15938 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
15939 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
15940 +
15941 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
15942 + {
15943 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
15944 + {
15945 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15946 + if (!p_HcFrame)
15947 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15948 + /* first read scheme and check that it is valid */
15949 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15950 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
15951 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
15952 + p_HcFrame->extraReg = 0x00008000;
15953 + p_HcFrame->commandSequence = seqNum;
15954 +
15955 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
15956 +
15957 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15958 + {
15959 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15960 + RETURN_ERROR(MINOR, err, NO_MSG);
15961 + }
15962 +
15963 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
15964 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
15965 + {
15966 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15967 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
15968 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
15969 + }
15970 +
15971 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
15972 +
15973 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
15974 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
15975 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
15976 + p_HcFrame->extraReg = 0x00008000;
15977 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
15978 +
15979 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
15980 +
15981 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15982 + {
15983 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15984 + RETURN_ERROR(MINOR, err, NO_MSG);
15985 + }
15986 +
15987 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
15988 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
15989 + {
15990 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15991 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
15992 + }
15993 +
15994 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
15995 +
15996 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
15997 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
15998 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
15999 + p_HcFrame->extraReg = 0x00008000;
16000 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
16001 +
16002 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16003 +
16004 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16005 + {
16006 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16007 + RETURN_ERROR(MINOR, err, NO_MSG);
16008 + }
16009 +
16010 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
16011 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
16012 + {
16013 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16014 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
16015 + }
16016 +
16017 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
16018 +
16019 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16020 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16021 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
16022 + p_HcFrame->extraReg = 0x00008000;
16023 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
16024 +
16025 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16026 +
16027 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16028 + {
16029 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16030 + RETURN_ERROR(MINOR, err, NO_MSG);
16031 + }
16032 +
16033 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16034 + }
16035 + }
16036 +
16037 + return E_OK;
16038 +}
16039 +
16040 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
16041 +{
16042 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16043 + t_Error err = E_OK;
16044 + uint16_t profileIndx;
16045 + t_HcFrame *p_HcFrame;
16046 + t_DpaaFD fmFd;
16047 + uint32_t seqNum;
16048 +
16049 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16050 + if (!p_HcFrame)
16051 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16052 +
16053 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16054 +
16055 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16056 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16057 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
16058 + p_HcFrame->extraReg = 0x00008000;
16059 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
16060 + p_HcFrame->commandSequence = seqNum;
16061 +
16062 + BUILD_FD(sizeof(t_HcFrame));
16063 +
16064 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16065 +
16066 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16067 +
16068 + if (err != E_OK)
16069 + RETURN_ERROR(MINOR, err, NO_MSG);
16070 +
16071 + return E_OK;
16072 +}
16073 +
16074 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
16075 +{
16076 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16077 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16078 + t_Error err = E_OK;
16079 + t_HcFrame *p_HcFrame;
16080 + t_DpaaFD fmFd;
16081 + uint32_t seqNum;
16082 +
16083 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16084 + if (!p_HcFrame)
16085 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16086 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16087 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16088 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16089 + p_HcFrame->actionReg |= 0x00008000;
16090 + p_HcFrame->extraReg = 0x00008000;
16091 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
16092 + p_HcFrame->commandSequence = seqNum;
16093 +
16094 + BUILD_FD(sizeof(t_HcFrame));
16095 +
16096 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16097 +
16098 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16099 +
16100 + if (err != E_OK)
16101 + RETURN_ERROR(MINOR, err, NO_MSG);
16102 +
16103 + return E_OK;
16104 +}
16105 +
16106 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
16107 +{
16108 +
16109 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16110 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16111 + t_Error err = E_OK;
16112 + t_HcFrame *p_HcFrame;
16113 + t_DpaaFD fmFd;
16114 + uint32_t seqNum;
16115 +
16116 + /* first read scheme and check that it is valid */
16117 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16118 + if (!p_HcFrame)
16119 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16120 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16121 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16122 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16123 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
16124 + p_HcFrame->extraReg = 0x00008000;
16125 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
16126 + p_HcFrame->commandSequence = seqNum;
16127 +
16128 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16129 +
16130 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16131 +
16132 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16133 +
16134 + if (err != E_OK)
16135 + RETURN_ERROR(MINOR, err, NO_MSG);
16136 +
16137 + return E_OK;
16138 +}
16139 +
16140 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
16141 +{
16142 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16143 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16144 + t_Error err;
16145 + t_HcFrame *p_HcFrame;
16146 + t_DpaaFD fmFd;
16147 + uint32_t retVal = 0;
16148 + uint32_t seqNum;
16149 +
16150 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
16151 +
16152 + /* first read scheme and check that it is valid */
16153 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16154 + if (!p_HcFrame)
16155 + {
16156 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16157 + return 0;
16158 + }
16159 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16160 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16161 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
16162 + p_HcFrame->extraReg = 0x00008000;
16163 + p_HcFrame->commandSequence = seqNum;
16164 +
16165 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
16166 +
16167 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16168 + if (err != E_OK)
16169 + {
16170 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16171 + REPORT_ERROR(MINOR, err, NO_MSG);
16172 + return 0;
16173 + }
16174 +
16175 + switch (counter)
16176 + {
16177 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
16178 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
16179 + break;
16180 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
16181 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
16182 + break;
16183 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
16184 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
16185 + break;
16186 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
16187 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
16188 + break;
16189 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
16190 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
16191 + break;
16192 + default:
16193 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
16194 + }
16195 +
16196 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16197 + return retVal;
16198 +}
16199 +
16200 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
16201 +{
16202 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16203 + t_HcFrame *p_HcFrame;
16204 + t_DpaaFD fmFd;
16205 + t_Error err = E_OK;
16206 + uint32_t seqNum;
16207 +
16208 + ASSERT_COND(p_FmHc);
16209 +
16210 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16211 + if (!p_HcFrame)
16212 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16213 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16214 + /* first read SP register */
16215 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16216 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
16217 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16218 + p_HcFrame->commandSequence = seqNum;
16219 +
16220 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
16221 +
16222 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16223 + {
16224 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16225 + RETURN_ERROR(MINOR, err, NO_MSG);
16226 + }
16227 +
16228 + /* spReg is the first reg, so we can use it both for read and for write */
16229 + if (add)
16230 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
16231 + else
16232 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
16233 +
16234 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
16235 +
16236 + BUILD_FD(sizeof(t_HcFrame));
16237 +
16238 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16239 +
16240 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16241 +
16242 + if (err != E_OK)
16243 + RETURN_ERROR(MINOR, err, NO_MSG);
16244 +
16245 + return E_OK;
16246 +}
16247 +
16248 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
16249 +{
16250 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16251 + t_HcFrame *p_HcFrame;
16252 + t_DpaaFD fmFd;
16253 + t_Error err = E_OK;
16254 + uint32_t seqNum;
16255 +
16256 + ASSERT_COND(p_FmHc);
16257 +
16258 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16259 + if (!p_HcFrame)
16260 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16261 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16262 + /* first read SP register */
16263 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16264 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
16265 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16266 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
16267 + p_HcFrame->commandSequence = seqNum;
16268 +
16269 + BUILD_FD(sizeof(t_HcFrame));
16270 +
16271 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16272 +
16273 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16274 +
16275 + if (err != E_OK)
16276 + RETURN_ERROR(MINOR, err, NO_MSG);
16277 +
16278 + return E_OK;
16279 +}
16280 +
16281 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
16282 +{
16283 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16284 + t_HcFrame *p_HcFrame;
16285 + t_DpaaFD fmFd;
16286 + t_Error err = E_OK;
16287 + uint32_t seqNum;
16288 +
16289 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
16290 +
16291 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16292 + if (!p_HcFrame)
16293 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16294 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16295 +
16296 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
16297 + p_HcFrame->actionReg = newAdAddrOffset;
16298 + p_HcFrame->actionReg |= 0xc0000000;
16299 + p_HcFrame->extraReg = oldAdAddrOffset;
16300 + p_HcFrame->commandSequence = seqNum;
16301 +
16302 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
16303 +
16304 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16305 +
16306 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16307 +
16308 + if (err != E_OK)
16309 + RETURN_ERROR(MAJOR, err, NO_MSG);
16310 +
16311 + return E_OK;
16312 +}
16313 +
16314 +t_Error FmHcPcdSync(t_Handle h_FmHc)
16315 +{
16316 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16317 + t_HcFrame *p_HcFrame;
16318 + t_DpaaFD fmFd;
16319 + t_Error err = E_OK;
16320 + uint32_t seqNum;
16321 +
16322 + ASSERT_COND(p_FmHc);
16323 +
16324 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16325 + if (!p_HcFrame)
16326 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16327 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16328 + /* first read SP register */
16329 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
16330 + p_HcFrame->actionReg = 0;
16331 + p_HcFrame->extraReg = 0;
16332 + p_HcFrame->commandSequence = seqNum;
16333 +
16334 + BUILD_FD(sizeof(t_HcFrame));
16335 +
16336 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16337 +
16338 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16339 +
16340 + if (err != E_OK)
16341 + RETURN_ERROR(MINOR, err, NO_MSG);
16342 +
16343 + return E_OK;
16344 +}
16345 +
16346 +t_Handle FmHcGetPort(t_Handle h_FmHc)
16347 +{
16348 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16349 + return p_FmHc->h_HcPortDev;
16350 +}
16351 --- /dev/null
16352 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
16353 @@ -0,0 +1,28 @@
16354 +#
16355 +# Makefile for the Freescale Ethernet controllers
16356 +#
16357 +ccflags-y += -DVERSION=\"\"
16358 +#
16359 +#Include netcomm SW specific definitions
16360 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
16361 +
16362 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
16363 +
16364 +ccflags-y += -I$(NCSW_FM_INC)
16365 +
16366 +obj-y += fsl-ncsw-MAC.o
16367 +
16368 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
16369 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
16370 + fman_tgec.o fman_crc32.o
16371 +
16372 +ifeq ($(CONFIG_FMAN_V3H),y)
16373 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
16374 +endif
16375 +ifeq ($(CONFIG_FMAN_V3L),y)
16376 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
16377 +endif
16378 +ifeq ($(CONFIG_FMAN_ARM),y)
16379 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
16380 +endif
16381 +
16382 --- /dev/null
16383 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
16384 @@ -0,0 +1,1504 @@
16385 +/*
16386 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16387 + *
16388 + * Redistribution and use in source and binary forms, with or without
16389 + * modification, are permitted provided that the following conditions are met:
16390 + * * Redistributions of source code must retain the above copyright
16391 + * notice, this list of conditions and the following disclaimer.
16392 + * * Redistributions in binary form must reproduce the above copyright
16393 + * notice, this list of conditions and the following disclaimer in the
16394 + * documentation and/or other materials provided with the distribution.
16395 + * * Neither the name of Freescale Semiconductor nor the
16396 + * names of its contributors may be used to endorse or promote products
16397 + * derived from this software without specific prior written permission.
16398 + *
16399 + *
16400 + * ALTERNATIVELY, this software may be distributed under the terms of the
16401 + * GNU General Public License ("GPL") as published by the Free Software
16402 + * Foundation, either version 2 of that License or (at your option) any
16403 + * later version.
16404 + *
16405 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16406 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16407 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16408 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16409 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16410 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16411 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16412 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16413 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16414 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16415 + */
16416 +
16417 +/******************************************************************************
16418 + @File dtsec.c
16419 +
16420 + @Description FMan dTSEC driver
16421 +*//***************************************************************************/
16422 +
16423 +#include "std_ext.h"
16424 +#include "error_ext.h"
16425 +#include "string_ext.h"
16426 +#include "xx_ext.h"
16427 +#include "endian_ext.h"
16428 +#include "debug_ext.h"
16429 +#include "crc_mac_addr_ext.h"
16430 +
16431 +#include "fm_common.h"
16432 +#include "dtsec.h"
16433 +#include "fsl_fman_dtsec.h"
16434 +#include "fsl_fman_dtsec_mii_acc.h"
16435 +
16436 +/*****************************************************************************/
16437 +/* Internal routines */
16438 +/*****************************************************************************/
16439 +
16440 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
16441 +{
16442 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
16443 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
16444 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
16445 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
16446 + if (p_Dtsec->addr == 0)
16447 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
16448 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
16449 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
16450 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
16451 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
16452 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
16453 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
16454 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
16455 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
16456 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
16457 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
16458 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
16459 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
16460 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
16461 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
16462 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
16463 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
16464 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
16465 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
16466 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
16467 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
16468 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
16469 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
16470 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
16471 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
16472 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
16473 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
16474 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
16475 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
16476 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
16477 +
16478 + /* If Auto negotiation process is disabled, need to */
16479 + /* Set up the PHY using the MII Management Interface */
16480 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
16481 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
16482 + if (!p_Dtsec->f_Exception)
16483 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
16484 + if (!p_Dtsec->f_Event)
16485 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
16486 +
16487 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
16488 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
16489 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
16490 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
16491 +
16492 + return E_OK;
16493 +}
16494 +
16495 +/* ......................................................................... */
16496 +
16497 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
16498 +{
16499 + uint32_t crc;
16500 +
16501 + /* CRC calculation */
16502 + GET_MAC_ADDR_CRC(ethAddr, crc);
16503 +
16504 + crc = GetMirror32(crc);
16505 +
16506 + return crc;
16507 +}
16508 +
16509 +/* ......................................................................... */
16510 +
16511 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
16512 +{
16513 + uint32_t car1, car2;
16514 +
16515 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
16516 +
16517 + if (car1)
16518 + {
16519 + if (car1 & CAR1_TR64)
16520 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
16521 + if (car1 & CAR1_TR127)
16522 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
16523 + if (car1 & CAR1_TR255)
16524 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
16525 + if (car1 & CAR1_TR511)
16526 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
16527 + if (car1 & CAR1_TRK1)
16528 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
16529 + if (car1 & CAR1_TRMAX)
16530 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
16531 + if (car1 & CAR1_TRMGV)
16532 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
16533 + if (car1 & CAR1_RBYT)
16534 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
16535 + if (car1 & CAR1_RPKT)
16536 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
16537 + if (car1 & CAR1_RMCA)
16538 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
16539 + if (car1 & CAR1_RBCA)
16540 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
16541 + if (car1 & CAR1_RXPF)
16542 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
16543 + if (car1 & CAR1_RALN)
16544 + p_Dtsec->internalStatistics.raln += VAL16BIT;
16545 + if (car1 & CAR1_RFLR)
16546 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
16547 + if (car1 & CAR1_RCDE)
16548 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
16549 + if (car1 & CAR1_RCSE)
16550 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
16551 + if (car1 & CAR1_RUND)
16552 + p_Dtsec->internalStatistics.rund += VAL16BIT;
16553 + if (car1 & CAR1_ROVR)
16554 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
16555 + if (car1 & CAR1_RFRG)
16556 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
16557 + if (car1 & CAR1_RJBR)
16558 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
16559 + if (car1 & CAR1_RDRP)
16560 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
16561 + }
16562 + if (car2)
16563 + {
16564 + if (car2 & CAR2_TFCS)
16565 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
16566 + if (car2 & CAR2_TBYT)
16567 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
16568 + if (car2 & CAR2_TPKT)
16569 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
16570 + if (car2 & CAR2_TMCA)
16571 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
16572 + if (car2 & CAR2_TBCA)
16573 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
16574 + if (car2 & CAR2_TXPF)
16575 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
16576 + if (car2 & CAR2_TDRP)
16577 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
16578 + }
16579 +}
16580 +
16581 +/* .............................................................................. */
16582 +
16583 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
16584 +{
16585 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16586 +
16587 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
16588 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
16589 +
16590 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16591 +}
16592 +
16593 +/* .............................................................................. */
16594 +
16595 +static void DtsecIsr(t_Handle h_Dtsec)
16596 +{
16597 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16598 + uint32_t event;
16599 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
16600 +
16601 + /* do not handle MDIO events */
16602 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
16603 +
16604 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
16605 +
16606 + fman_dtsec_ack_event(p_DtsecMemMap, event);
16607 +
16608 + if (event & DTSEC_IMASK_BREN)
16609 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
16610 + if (event & DTSEC_IMASK_RXCEN)
16611 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
16612 + if (event & DTSEC_IMASK_MSROEN)
16613 + UpdateStatistics(p_Dtsec);
16614 + if (event & DTSEC_IMASK_GTSCEN)
16615 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
16616 + if (event & DTSEC_IMASK_BTEN)
16617 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
16618 + if (event & DTSEC_IMASK_TXCEN)
16619 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
16620 + if (event & DTSEC_IMASK_TXEEN)
16621 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
16622 + if (event & DTSEC_IMASK_LCEN)
16623 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
16624 + if (event & DTSEC_IMASK_CRLEN)
16625 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
16626 + if (event & DTSEC_IMASK_XFUNEN)
16627 + {
16628 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
16629 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
16630 + {
16631 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
16632 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
16633 + /* This is a read only regidter */
16634 +
16635 + /* b. Read and save the value of TPKT */
16636 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
16637 +
16638 + /* c. Read the register at dTSEC address offset 0x32C */
16639 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
16640 +
16641 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
16642 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
16643 + {
16644 + /* If they are not equal, save the value of this register and wait for at least
16645 + * MAXFRM*16 ns */
16646 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
16647 + }
16648 +
16649 + /* e. Read and save TPKT again and read the register at dTSEC address offset
16650 + 0x32C again*/
16651 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
16652 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
16653 +
16654 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
16655 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
16656 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
16657 + the transmit portion of the dTSEC controller is locked up and the user should
16658 + proceed to the recover sequence. */
16659 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
16660 + {
16661 + /* recover sequence */
16662 +
16663 + /* a.Write a 1 to RCTRL[GRS]*/
16664 +
16665 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
16666 +
16667 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
16668 + for (i = 0 ; i < 100 ; i++ )
16669 + {
16670 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
16671 + break;
16672 + XX_UDelay(1);
16673 + }
16674 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
16675 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
16676 + else
16677 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
16678 +
16679 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
16680 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
16681 +
16682 + /* d.Wait 4 Tx clocks (32 ns) */
16683 + XX_UDelay(1);
16684 +
16685 + /* e.Write a 0 to bit n of FM_RSTC. */
16686 + /* cleared by FMAN */
16687 + }
16688 + }
16689 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
16690 +
16691 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
16692 + }
16693 + if (event & DTSEC_IMASK_MAGEN)
16694 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
16695 + if (event & DTSEC_IMASK_GRSCEN)
16696 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
16697 + if (event & DTSEC_IMASK_TDPEEN)
16698 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
16699 + if (event & DTSEC_IMASK_RDPEEN)
16700 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
16701 +
16702 + /* - masked interrupts */
16703 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
16704 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
16705 +}
16706 +
16707 +static void DtsecMdioIsr(t_Handle h_Dtsec)
16708 +{
16709 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16710 + uint32_t event;
16711 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
16712 +
16713 + event = GET_UINT32(p_DtsecMemMap->ievent);
16714 + /* handle only MDIO events */
16715 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
16716 + if (event)
16717 + {
16718 + event &= GET_UINT32(p_DtsecMemMap->imask);
16719 +
16720 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
16721 +
16722 + if (event & DTSEC_IMASK_MMRDEN)
16723 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
16724 + if (event & DTSEC_IMASK_MMWREN)
16725 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
16726 + }
16727 +}
16728 +
16729 +static void Dtsec1588Isr(t_Handle h_Dtsec)
16730 +{
16731 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16732 + uint32_t event;
16733 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
16734 +
16735 + if (p_Dtsec->ptpTsuEnabled)
16736 + {
16737 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
16738 +
16739 + if (event)
16740 + {
16741 + ASSERT_COND(event & TMR_PEVENT_TSRE);
16742 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
16743 + }
16744 + }
16745 +}
16746 +
16747 +/* ........................................................................... */
16748 +
16749 +static void FreeInitResources(t_Dtsec *p_Dtsec)
16750 +{
16751 + if (p_Dtsec->mdioIrq != NO_IRQ)
16752 + {
16753 + XX_DisableIntr(p_Dtsec->mdioIrq);
16754 + XX_FreeIntr(p_Dtsec->mdioIrq);
16755 + }
16756 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
16757 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
16758 +
16759 + /* release the driver's group hash table */
16760 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
16761 + p_Dtsec->p_MulticastAddrHash = NULL;
16762 +
16763 + /* release the driver's individual hash table */
16764 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
16765 + p_Dtsec->p_UnicastAddrHash = NULL;
16766 +}
16767 +
16768 +/* ........................................................................... */
16769 +
16770 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
16771 +{
16772 + struct dtsec_regs *p_MemMap;
16773 + int pollTimeout = 0;
16774 +
16775 + ASSERT_COND(p_Dtsec);
16776 +
16777 + p_MemMap = p_Dtsec->p_MemMap;
16778 + ASSERT_COND(p_MemMap);
16779 +
16780 + /* Assert the graceful transmit stop bit */
16781 + if (mode & e_COMM_MODE_RX)
16782 + {
16783 + fman_dtsec_stop_rx(p_MemMap);
16784 +
16785 +#ifdef FM_GRS_ERRATA_DTSEC_A002
16786 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
16787 + XX_UDelay(100);
16788 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
16789 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
16790 + XX_UDelay(10);
16791 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
16792 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
16793 + }
16794 +
16795 + if (mode & e_COMM_MODE_TX)
16796 + {
16797 +#if defined(FM_GTS_ERRATA_DTSEC_A004)
16798 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
16799 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
16800 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) */
16801 +
16802 + fman_dtsec_stop_tx(p_MemMap);
16803 +
16804 +#if defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
16805 + XX_UDelay(10);
16806 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 || FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 */
16807 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) */
16808 + }
16809 +
16810 + /* Poll GRSC/GTSC bits in IEVENT register until both are set */
16811 +#if defined(FM_GRS_ERRATA_DTSEC_A002) || defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) || defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839)
16812 + XX_UDelay(10);
16813 +#else
16814 + while (fman_dtsec_get_event(p_MemMap, DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN) != (DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN))
16815 + {
16816 + if (pollTimeout == 100)
16817 + break;
16818 + XX_UDelay(1);
16819 + pollTimeout++;
16820 + }
16821 +#endif
16822 +
16823 + return E_OK;
16824 +}
16825 +
16826 +/* .............................................................................. */
16827 +
16828 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
16829 +{
16830 + struct dtsec_regs *p_MemMap;
16831 +
16832 + ASSERT_COND(p_Dtsec);
16833 + p_MemMap = p_Dtsec->p_MemMap;
16834 + ASSERT_COND(p_MemMap);
16835 +
16836 + /* clear the graceful receive stop bit */
16837 + if (mode & e_COMM_MODE_TX)
16838 + fman_dtsec_start_tx(p_MemMap);
16839 +
16840 + if (mode & e_COMM_MODE_RX)
16841 + fman_dtsec_start_rx(p_MemMap);
16842 +
16843 + return E_OK;
16844 +}
16845 +
16846 +
16847 +/*****************************************************************************/
16848 +/* dTSEC Configs modification functions */
16849 +/*****************************************************************************/
16850 +
16851 +/* .............................................................................. */
16852 +
16853 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
16854 +{
16855 +
16856 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16857 +
16858 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16859 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16860 +
16861 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
16862 +
16863 + return E_OK;
16864 +}
16865 +
16866 +/* .............................................................................. */
16867 +
16868 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
16869 +{
16870 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16871 +
16872 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16873 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16874 +
16875 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
16876 +
16877 + return E_OK;
16878 +}
16879 +
16880 +/* .............................................................................. */
16881 +
16882 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
16883 +{
16884 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16885 +
16886 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16887 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16888 +
16889 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
16890 +
16891 + return E_OK;
16892 +}
16893 +
16894 +/* .............................................................................. */
16895 +
16896 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
16897 +{
16898 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16899 +
16900 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16901 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16902 +
16903 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
16904 +
16905 + return E_OK;
16906 +}
16907 +
16908 +/* .............................................................................. */
16909 +
16910 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
16911 +{
16912 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16913 +
16914 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16915 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16916 +
16917 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
16918 +
16919 + return E_OK;
16920 +}
16921 +
16922 +/* .............................................................................. */
16923 +
16924 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
16925 +{
16926 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16927 +
16928 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16929 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16930 +
16931 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
16932 +
16933 + return E_OK;
16934 +}
16935 +
16936 +/* .............................................................................. */
16937 +
16938 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16939 +{
16940 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16941 + uint32_t bitMask = 0;
16942 +
16943 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16944 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16945 +
16946 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16947 + {
16948 + GET_EXCEPTION_FLAG(bitMask, exception);
16949 + if (bitMask)
16950 + {
16951 + if (enable)
16952 + p_Dtsec->exceptions |= bitMask;
16953 + else
16954 + p_Dtsec->exceptions &= ~bitMask;
16955 + }
16956 + else
16957 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16958 + }
16959 + else
16960 + {
16961 + if (!p_Dtsec->ptpTsuEnabled)
16962 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16963 +
16964 + if (enable)
16965 + p_Dtsec->enTsuErrExeption = TRUE;
16966 + else
16967 + p_Dtsec->enTsuErrExeption = FALSE;
16968 + }
16969 +
16970 + return E_OK;
16971 +}
16972 +
16973 +
16974 +/*****************************************************************************/
16975 +/* dTSEC Run Time API functions */
16976 +/*****************************************************************************/
16977 +
16978 +/* .............................................................................. */
16979 +
16980 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
16981 +{
16982 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16983 +
16984 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16985 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16986 +
16987 + fman_dtsec_enable(p_Dtsec->p_MemMap,
16988 + (bool)!!(mode & e_COMM_MODE_RX),
16989 + (bool)!!(mode & e_COMM_MODE_TX));
16990 +
16991 + GracefulRestart(p_Dtsec, mode);
16992 +
16993 + return E_OK;
16994 +}
16995 +
16996 +/* .............................................................................. */
16997 +
16998 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
16999 +{
17000 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17001 +
17002 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17003 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17004 +
17005 + GracefulStop(p_Dtsec, mode);
17006 +
17007 + fman_dtsec_disable(p_Dtsec->p_MemMap,
17008 + (bool)!!(mode & e_COMM_MODE_RX),
17009 + (bool)!!(mode & e_COMM_MODE_TX));
17010 +
17011 + return E_OK;
17012 +}
17013 +
17014 +/* .............................................................................. */
17015 +
17016 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
17017 + uint8_t priority,
17018 + uint16_t pauseTime,
17019 + uint16_t threshTime)
17020 +{
17021 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17022 +
17023 + UNUSED(priority);UNUSED(threshTime);
17024 +
17025 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
17026 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17027 +
17028 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
17029 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
17030 + if (0 < pauseTime && pauseTime <= 320)
17031 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
17032 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
17033 + " value should be greater than 320."));
17034 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
17035 +
17036 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17037 +
17038 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
17039 +
17040 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17041 +
17042 + return E_OK;
17043 +}
17044 +
17045 +/* .............................................................................. */
17046 +/* backward compatibility. will be removed in the future. */
17047 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
17048 +{
17049 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
17050 +}
17051 +
17052 +/* .............................................................................. */
17053 +
17054 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
17055 +{
17056 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17057 + bool accept_pause = !en;
17058 +
17059 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
17060 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17061 +
17062 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17063 +
17064 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
17065 +
17066 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17067 +
17068 + return E_OK;
17069 +}
17070 +
17071 +/* .............................................................................. */
17072 +
17073 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
17074 +{
17075 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17076 +
17077 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17078 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17079 +
17080 + p_Dtsec->ptpTsuEnabled = TRUE;
17081 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
17082 +
17083 + return E_OK;
17084 +}
17085 +
17086 +/* .............................................................................. */
17087 +
17088 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
17089 +{
17090 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17091 +
17092 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17093 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17094 +
17095 + p_Dtsec->ptpTsuEnabled = FALSE;
17096 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
17097 +
17098 + return E_OK;
17099 +}
17100 +
17101 +/* .............................................................................. */
17102 +
17103 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
17104 +{
17105 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17106 + struct dtsec_regs *p_DtsecMemMap;
17107 +
17108 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17109 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17110 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
17111 +
17112 + p_DtsecMemMap = p_Dtsec->p_MemMap;
17113 +
17114 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
17115 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
17116 +
17117 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
17118 +
17119 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
17120 + {
17121 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
17122 + + p_Dtsec->internalStatistics.tr64;
17123 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
17124 + + p_Dtsec->internalStatistics.tr127;
17125 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
17126 + + p_Dtsec->internalStatistics.tr255;
17127 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
17128 + + p_Dtsec->internalStatistics.tr511;
17129 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
17130 + + p_Dtsec->internalStatistics.tr1k;
17131 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
17132 + + p_Dtsec->internalStatistics.trmax;
17133 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
17134 + + p_Dtsec->internalStatistics.trmgv;
17135 +
17136 + /* MIB II */
17137 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
17138 + + p_Dtsec->internalStatistics.rbyt;
17139 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
17140 + + p_Dtsec->internalStatistics.rpkt;
17141 + p_Statistics->ifInUcastPkts = 0;
17142 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
17143 + + p_Dtsec->internalStatistics.rmca;
17144 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
17145 + + p_Dtsec->internalStatistics.rbca;
17146 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
17147 + + p_Dtsec->internalStatistics.tbyt;
17148 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
17149 + + p_Dtsec->internalStatistics.tpkt;
17150 + p_Statistics->ifOutUcastPkts = 0;
17151 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
17152 + + p_Dtsec->internalStatistics.tmca;
17153 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
17154 + + p_Dtsec->internalStatistics.tbca;
17155 + }
17156 +
17157 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
17158 + + p_Dtsec->internalStatistics.rfrg;
17159 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
17160 + + p_Dtsec->internalStatistics.rjbr;
17161 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
17162 + + p_Dtsec->internalStatistics.rdrp;
17163 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
17164 + + p_Dtsec->internalStatistics.raln;
17165 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
17166 + + p_Dtsec->internalStatistics.rund;
17167 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
17168 + + p_Dtsec->internalStatistics.rovr;
17169 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
17170 + + p_Dtsec->internalStatistics.rxpf;
17171 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
17172 + + p_Dtsec->internalStatistics.txpf;
17173 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
17174 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
17175 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
17176 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
17177 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
17178 +
17179 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
17180 + + p_Dtsec->internalStatistics.tdrp;
17181 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
17182 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
17183 + + p_Dtsec->internalStatistics.tfcs;
17184 +
17185 + return E_OK;
17186 +}
17187 +
17188 +/* .............................................................................. */
17189 +
17190 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
17191 +{
17192 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17193 +
17194 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17195 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17196 +
17197 + /* Initialize MAC Station Address registers (1 & 2) */
17198 + /* Station address have to be swapped (big endian to little endian */
17199 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
17200 +
17201 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17202 +
17203 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
17204 +
17205 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17206 +
17207 + return E_OK;
17208 +}
17209 +
17210 +/* .............................................................................. */
17211 +
17212 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
17213 +{
17214 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17215 +
17216 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17217 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17218 +
17219 + /* clear HW counters */
17220 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
17221 +
17222 + /* clear SW counters holding carries */
17223 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
17224 +
17225 + return E_OK;
17226 +}
17227 +
17228 +/* .............................................................................. */
17229 +
17230 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17231 +{
17232 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
17233 + uint64_t ethAddr;
17234 + uint8_t paddrNum;
17235 +
17236 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17237 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17238 +
17239 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17240 +
17241 + if (ethAddr & GROUP_ADDRESS)
17242 + /* Multicast address has no effect in PADDR */
17243 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
17244 +
17245 + /* Make sure no PADDR contains this address */
17246 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
17247 + if (p_Dtsec->indAddrRegUsed[paddrNum])
17248 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
17249 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
17250 +
17251 + /* Find first unused PADDR */
17252 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
17253 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
17254 + {
17255 + /* mark this PADDR as used */
17256 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
17257 + /* store address */
17258 + p_Dtsec->paddr[paddrNum] = ethAddr;
17259 +
17260 + /* put in hardware */
17261 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
17262 + p_Dtsec->numOfIndAddrInRegs++;
17263 +
17264 + return E_OK;
17265 + }
17266 +
17267 + /* No free PADDR */
17268 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
17269 +}
17270 +
17271 +/* .............................................................................. */
17272 +
17273 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17274 +{
17275 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
17276 + uint64_t ethAddr;
17277 + uint8_t paddrNum;
17278 +
17279 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17280 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17281 +
17282 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17283 +
17284 + /* Find used PADDR containing this address */
17285 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
17286 + {
17287 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
17288 + (p_Dtsec->paddr[paddrNum] == ethAddr))
17289 + {
17290 + /* mark this PADDR as not used */
17291 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
17292 + /* clear in hardware */
17293 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
17294 + p_Dtsec->numOfIndAddrInRegs--;
17295 +
17296 + return E_OK;
17297 + }
17298 + }
17299 +
17300 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
17301 +}
17302 +
17303 +/* .............................................................................. */
17304 +
17305 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17306 +{
17307 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17308 + t_EthHashEntry *p_HashEntry;
17309 + uint64_t ethAddr;
17310 + int32_t bucket;
17311 + uint32_t crc;
17312 + bool mcast, ghtx;
17313 +
17314 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17315 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17316 +
17317 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17318 +
17319 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
17320 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
17321 +
17322 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
17323 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
17324 +
17325 + crc = GetMacAddrHashCode(ethAddr);
17326 +
17327 + /* considering the 9 highest order bits in crc H[8:0]:
17328 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
17329 + * and H[5:1] (next 5 bits) identify the hash bit
17330 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
17331 + * and H[4:0] (next 5 bits) identify the hash bit.
17332 + *
17333 + * In bucket index output the low 5 bits identify the hash register bit,
17334 + * while the higher 4 bits identify the hash register
17335 + */
17336 +
17337 + if (ghtx)
17338 + bucket = (int32_t)((crc >> 23) & 0x1ff);
17339 + else {
17340 + bucket = (int32_t)((crc >> 24) & 0xff);
17341 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
17342 + if (mcast)
17343 + bucket += 0x100;
17344 + }
17345 +
17346 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
17347 +
17348 + /* Create element to be added to the driver hash table */
17349 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
17350 + p_HashEntry->addr = ethAddr;
17351 + INIT_LIST(&p_HashEntry->node);
17352 +
17353 + if (ethAddr & MAC_GROUP_ADDRESS)
17354 + /* Group Address */
17355 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
17356 + else
17357 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
17358 +
17359 + return E_OK;
17360 +}
17361 +
17362 +/* .............................................................................. */
17363 +
17364 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17365 +{
17366 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17367 + t_List *p_Pos;
17368 + t_EthHashEntry *p_HashEntry = NULL;
17369 + uint64_t ethAddr;
17370 + int32_t bucket;
17371 + uint32_t crc;
17372 + bool mcast, ghtx;
17373 +
17374 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17375 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17376 +
17377 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17378 +
17379 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
17380 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
17381 +
17382 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
17383 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
17384 +
17385 + crc = GetMacAddrHashCode(ethAddr);
17386 +
17387 + if (ghtx)
17388 + bucket = (int32_t)((crc >> 23) & 0x1ff);
17389 + else {
17390 + bucket = (int32_t)((crc >> 24) & 0xff);
17391 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
17392 + if (mcast)
17393 + bucket += 0x100;
17394 + }
17395 +
17396 + if (ethAddr & MAC_GROUP_ADDRESS)
17397 + {
17398 + /* Group Address */
17399 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
17400 + {
17401 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
17402 + if (p_HashEntry->addr == ethAddr)
17403 + {
17404 + LIST_DelAndInit(&p_HashEntry->node);
17405 + XX_Free(p_HashEntry);
17406 + break;
17407 + }
17408 + }
17409 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
17410 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
17411 + }
17412 + else
17413 + {
17414 + /* Individual Address */
17415 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
17416 + {
17417 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
17418 + if (p_HashEntry->addr == ethAddr)
17419 + {
17420 + LIST_DelAndInit(&p_HashEntry->node);
17421 + XX_Free(p_HashEntry);
17422 + break;
17423 + }
17424 + }
17425 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
17426 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
17427 + }
17428 +
17429 + /* address does not exist */
17430 + ASSERT_COND(p_HashEntry != NULL);
17431 +
17432 + return E_OK;
17433 +}
17434 +
17435 +/* .............................................................................. */
17436 +
17437 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
17438 +{
17439 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17440 +
17441 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17442 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17443 +
17444 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
17445 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
17446 +
17447 + return E_OK;
17448 +}
17449 +
17450 +/* .............................................................................. */
17451 +
17452 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
17453 +{
17454 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17455 + t_Error err;
17456 +
17457 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17458 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17459 +
17460 + p_Dtsec->statisticsLevel = statisticsLevel;
17461 +
17462 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
17463 + (enum dtsec_stat_level)statisticsLevel);
17464 + if (err != E_OK)
17465 + return err;
17466 +
17467 + switch (statisticsLevel)
17468 + {
17469 + case (e_FM_MAC_NONE_STATISTICS):
17470 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
17471 + break;
17472 + case (e_FM_MAC_PARTIAL_STATISTICS):
17473 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
17474 + break;
17475 + case (e_FM_MAC_FULL_STATISTICS):
17476 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
17477 + break;
17478 + default:
17479 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
17480 + }
17481 +
17482 + return E_OK;
17483 +}
17484 +
17485 +/* .............................................................................. */
17486 +
17487 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
17488 +{
17489 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17490 +
17491 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
17492 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17493 +
17494 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17495 +
17496 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
17497 +
17498 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17499 +
17500 + return E_OK;
17501 +}
17502 +
17503 +/* .............................................................................. */
17504 +
17505 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
17506 +{
17507 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17508 + int err;
17509 + enum enet_interface enet_interface;
17510 + enum enet_speed enet_speed;
17511 +
17512 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17513 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17514 +
17515 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
17516 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
17517 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
17518 + p_Dtsec->halfDuplex = !fullDuplex;
17519 +
17520 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17521 +
17522 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
17523 +
17524 + if (err == -EINVAL)
17525 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
17526 +
17527 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17528 +
17529 + return (t_Error)err;
17530 +}
17531 +
17532 +/* .............................................................................. */
17533 +
17534 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
17535 +{
17536 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17537 + uint16_t tmpReg16;
17538 +
17539 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17540 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17541 +
17542 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
17543 +
17544 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
17545 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
17546 +
17547 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
17548 +
17549 + return E_OK;
17550 +}
17551 +
17552 +/* .............................................................................. */
17553 +
17554 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
17555 +{
17556 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17557 +
17558 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17559 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17560 +
17561 + *macId = p_Dtsec->macId;
17562 +
17563 + return E_OK;
17564 +}
17565 +
17566 +/* .............................................................................. */
17567 +
17568 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
17569 +{
17570 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17571 +
17572 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17573 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17574 +
17575 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
17576 +
17577 + return E_OK;
17578 +}
17579 +
17580 +/* .............................................................................. */
17581 +
17582 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
17583 +{
17584 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17585 + uint32_t bitMask = 0;
17586 +
17587 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17588 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17589 +
17590 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
17591 + {
17592 + GET_EXCEPTION_FLAG(bitMask, exception);
17593 + if (bitMask)
17594 + {
17595 + if (enable)
17596 + p_Dtsec->exceptions |= bitMask;
17597 + else
17598 + p_Dtsec->exceptions &= ~bitMask;
17599 + }
17600 + else
17601 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
17602 +
17603 + if (enable)
17604 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
17605 + else
17606 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
17607 + }
17608 + else
17609 + {
17610 + if (!p_Dtsec->ptpTsuEnabled)
17611 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
17612 +
17613 + if (enable)
17614 + {
17615 + p_Dtsec->enTsuErrExeption = TRUE;
17616 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
17617 + }
17618 + else
17619 + {
17620 + p_Dtsec->enTsuErrExeption = FALSE;
17621 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
17622 + }
17623 + }
17624 +
17625 + return E_OK;
17626 +}
17627 +
17628 +
17629 +/*****************************************************************************/
17630 +/* dTSEC Init & Free API */
17631 +/*****************************************************************************/
17632 +
17633 +/* .............................................................................. */
17634 +
17635 +static t_Error DtsecInit(t_Handle h_Dtsec)
17636 +{
17637 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17638 + struct dtsec_cfg *p_DtsecDriverParam;
17639 + t_Error err;
17640 + uint16_t maxFrmLn;
17641 + enum enet_interface enet_interface;
17642 + enum enet_speed enet_speed;
17643 + t_EnetAddr ethAddr;
17644 +
17645 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17646 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17647 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
17648 +
17649 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
17650 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
17651 +
17652 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
17653 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
17654 +
17655 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
17656 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
17657 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
17658 +
17659 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
17660 + p_DtsecDriverParam,
17661 + enet_interface,
17662 + enet_speed,
17663 + (uint8_t*)ethAddr,
17664 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
17665 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
17666 + p_Dtsec->exceptions);
17667 + if (err)
17668 + {
17669 + FreeInitResources(p_Dtsec);
17670 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
17671 + }
17672 +
17673 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
17674 + {
17675 + uint16_t tmpReg16;
17676 +
17677 + /* Configure the TBI PHY Control Register */
17678 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
17679 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
17680 +
17681 + tmpReg16 = PHY_TBICON_CLK_SEL;
17682 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
17683 +
17684 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
17685 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
17686 +
17687 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
17688 + tmpReg16 = PHY_TBIANA_1000X;
17689 + else
17690 + tmpReg16 = PHY_TBIANA_SGMII;
17691 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
17692 +
17693 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
17694 +
17695 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
17696 + }
17697 +
17698 + /* Max Frame Length */
17699 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
17700 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
17701 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
17702 + if (err)
17703 + RETURN_ERROR(MINOR,err, NO_MSG);
17704 +
17705 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
17706 + if (!p_Dtsec->p_MulticastAddrHash) {
17707 + FreeInitResources(p_Dtsec);
17708 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
17709 + }
17710 +
17711 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
17712 + if (!p_Dtsec->p_UnicastAddrHash)
17713 + {
17714 + FreeInitResources(p_Dtsec);
17715 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
17716 + }
17717 +
17718 + /* register err intr handler for dtsec to FPM (err)*/
17719 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
17720 + e_FM_MOD_1G_MAC,
17721 + p_Dtsec->macId,
17722 + e_FM_INTR_TYPE_ERR,
17723 + DtsecIsr,
17724 + p_Dtsec);
17725 + /* register 1588 intr handler for TMR to FPM (normal)*/
17726 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
17727 + e_FM_MOD_1G_MAC,
17728 + p_Dtsec->macId,
17729 + e_FM_INTR_TYPE_NORMAL,
17730 + Dtsec1588Isr,
17731 + p_Dtsec);
17732 + /* register normal intr handler for dtsec to main interrupt controller. */
17733 + if (p_Dtsec->mdioIrq != NO_IRQ)
17734 + {
17735 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
17736 + XX_EnableIntr(p_Dtsec->mdioIrq);
17737 + }
17738 +
17739 + XX_Free(p_DtsecDriverParam);
17740 + p_Dtsec->p_DtsecDriverParam = NULL;
17741 +
17742 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
17743 + if (err)
17744 + {
17745 + FreeInitResources(p_Dtsec);
17746 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
17747 + }
17748 +
17749 + return E_OK;
17750 +}
17751 +
17752 +/* ........................................................................... */
17753 +
17754 +static t_Error DtsecFree(t_Handle h_Dtsec)
17755 +{
17756 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17757 +
17758 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17759 +
17760 + if (p_Dtsec->p_DtsecDriverParam)
17761 + {
17762 + /* Called after config */
17763 + XX_Free(p_Dtsec->p_DtsecDriverParam);
17764 + p_Dtsec->p_DtsecDriverParam = NULL;
17765 + }
17766 + else
17767 + /* Called after init */
17768 + FreeInitResources(p_Dtsec);
17769 +
17770 + XX_Free(p_Dtsec);
17771 +
17772 + return E_OK;
17773 +}
17774 +
17775 +/* .............................................................................. */
17776 +
17777 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
17778 +{
17779 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
17780 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
17781 +
17782 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
17783 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
17784 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
17785 +
17786 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
17787 +
17788 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
17789 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
17790 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
17791 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
17792 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
17793 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
17794 +
17795 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
17796 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
17797 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
17798 +
17799 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
17800 +
17801 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
17802 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
17803 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
17804 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
17805 +
17806 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
17807 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
17808 +
17809 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
17810 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
17811 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
17812 +
17813 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
17814 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
17815 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL;
17816 +
17817 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
17818 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
17819 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
17820 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
17821 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
17822 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
17823 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
17824 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
17825 +
17826 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
17827 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
17828 +
17829 +}
17830 +
17831 +
17832 +/*****************************************************************************/
17833 +/* dTSEC Config Main Entry */
17834 +/*****************************************************************************/
17835 +
17836 +/* .............................................................................. */
17837 +
17838 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
17839 +{
17840 + t_Dtsec *p_Dtsec;
17841 + struct dtsec_cfg *p_DtsecDriverParam;
17842 + uintptr_t baseAddr;
17843 +
17844 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
17845 +
17846 + baseAddr = p_FmMacParam->baseAddr;
17847 +
17848 + /* allocate memory for the UCC GETH data structure. */
17849 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
17850 + if (!p_Dtsec)
17851 + {
17852 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
17853 + return NULL;
17854 + }
17855 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
17856 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
17857 +
17858 + /* allocate memory for the dTSEC driver parameters data structure. */
17859 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
17860 + if (!p_DtsecDriverParam)
17861 + {
17862 + XX_Free(p_Dtsec);
17863 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
17864 + return NULL;
17865 + }
17866 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
17867 +
17868 + /* Plant parameter structure pointer */
17869 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
17870 +
17871 + fman_dtsec_defconfig(p_DtsecDriverParam);
17872 +
17873 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
17874 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
17875 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
17876 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
17877 + p_Dtsec->macId = p_FmMacParam->macId;
17878 + p_Dtsec->exceptions = DEFAULT_exceptions;
17879 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
17880 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
17881 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
17882 + p_Dtsec->h_App = p_FmMacParam->h_App;
17883 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
17884 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
17885 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
17886 +
17887 + return p_Dtsec;
17888 +}
17889 --- /dev/null
17890 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
17891 @@ -0,0 +1,228 @@
17892 +/*
17893 + * Copyright 2008-2013 Freescale Semiconductor Inc.
17894 + *
17895 + * Redistribution and use in source and binary forms, with or without
17896 + * modification, are permitted provided that the following conditions are met:
17897 + * * Redistributions of source code must retain the above copyright
17898 + * notice, this list of conditions and the following disclaimer.
17899 + * * Redistributions in binary form must reproduce the above copyright
17900 + * notice, this list of conditions and the following disclaimer in the
17901 + * documentation and/or other materials provided with the distribution.
17902 + * * Neither the name of Freescale Semiconductor nor the
17903 + * names of its contributors may be used to endorse or promote products
17904 + * derived from this software without specific prior written permission.
17905 + *
17906 + *
17907 + * ALTERNATIVELY, this software may be distributed under the terms of the
17908 + * GNU General Public License ("GPL") as published by the Free Software
17909 + * Foundation, either version 2 of that License or (at your option) any
17910 + * later version.
17911 + *
17912 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17913 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17914 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17915 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17916 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17917 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17918 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17919 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17920 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17921 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17922 + */
17923 +
17924 +/******************************************************************************
17925 + @File dtsec.h
17926 +
17927 + @Description FM dTSEC ...
17928 +*//***************************************************************************/
17929 +#ifndef __DTSEC_H
17930 +#define __DTSEC_H
17931 +
17932 +#include "std_ext.h"
17933 +#include "error_ext.h"
17934 +#include "list_ext.h"
17935 +#include "enet_ext.h"
17936 +
17937 +#include "dtsec_mii_acc.h"
17938 +#include "fm_mac.h"
17939 +
17940 +
17941 +#define DEFAULT_exceptions \
17942 + ((uint32_t)(DTSEC_IMASK_BREN | \
17943 + DTSEC_IMASK_RXCEN | \
17944 + DTSEC_IMASK_BTEN | \
17945 + DTSEC_IMASK_TXCEN | \
17946 + DTSEC_IMASK_TXEEN | \
17947 + DTSEC_IMASK_ABRTEN | \
17948 + DTSEC_IMASK_LCEN | \
17949 + DTSEC_IMASK_CRLEN | \
17950 + DTSEC_IMASK_XFUNEN | \
17951 + DTSEC_IMASK_IFERREN | \
17952 + DTSEC_IMASK_MAGEN | \
17953 + DTSEC_IMASK_TDPEEN | \
17954 + DTSEC_IMASK_RDPEEN))
17955 +
17956 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
17957 + case e_FM_MAC_EX_1G_BAB_RX: \
17958 + bitMask = DTSEC_IMASK_BREN; break; \
17959 + case e_FM_MAC_EX_1G_RX_CTL: \
17960 + bitMask = DTSEC_IMASK_RXCEN; break; \
17961 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
17962 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
17963 + case e_FM_MAC_EX_1G_BAB_TX: \
17964 + bitMask = DTSEC_IMASK_BTEN ; break; \
17965 + case e_FM_MAC_EX_1G_TX_CTL: \
17966 + bitMask = DTSEC_IMASK_TXCEN ; break; \
17967 + case e_FM_MAC_EX_1G_TX_ERR: \
17968 + bitMask = DTSEC_IMASK_TXEEN ; break; \
17969 + case e_FM_MAC_EX_1G_LATE_COL: \
17970 + bitMask = DTSEC_IMASK_LCEN ; break; \
17971 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
17972 + bitMask = DTSEC_IMASK_CRLEN ; break; \
17973 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
17974 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
17975 + case e_FM_MAC_EX_1G_MAG_PCKT: \
17976 + bitMask = DTSEC_IMASK_MAGEN ; break; \
17977 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
17978 + bitMask = DTSEC_IMASK_MMRDEN; break; \
17979 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
17980 + bitMask = DTSEC_IMASK_MMWREN ; break; \
17981 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
17982 + bitMask = DTSEC_IMASK_GRSCEN; break; \
17983 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
17984 + bitMask = DTSEC_IMASK_TDPEEN; break; \
17985 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
17986 + bitMask = DTSEC_IMASK_MSROEN ; break; \
17987 + default: bitMask = 0;break;}
17988 +
17989 +
17990 +#define MAX_PACKET_ALIGNMENT 31
17991 +#define MAX_INTER_PACKET_GAP 0x7f
17992 +#define MAX_INTER_PALTERNATE_BEB 0x0f
17993 +#define MAX_RETRANSMISSION 0x0f
17994 +#define MAX_COLLISION_WINDOW 0x03ff
17995 +
17996 +
17997 +/********************* From mac ext ******************************************/
17998 +typedef uint32_t t_ErrorDisable;
17999 +
18000 +#define ERROR_DISABLE_TRANSMIT 0x00400000
18001 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
18002 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
18003 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
18004 +#define ERROR_DISABLE_TxABORT 0x00008000
18005 +#define ERROR_DISABLE_INTERFACE 0x00004000
18006 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
18007 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
18008 +
18009 +/*****************************************************************************/
18010 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
18011 +
18012 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
18013 +
18014 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
18015 +
18016 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
18017 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
18018 +
18019 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
18020 +
18021 +#define MAX_PHYS 32 /* maximum number of phys */
18022 +
18023 +#define VAL32BIT 0x100000000LL
18024 +#define VAL22BIT 0x00400000
18025 +#define VAL16BIT 0x00010000
18026 +#define VAL12BIT 0x00001000
18027 +
18028 +/* CAR1/2 bits */
18029 +#define CAR1_TR64 0x80000000
18030 +#define CAR1_TR127 0x40000000
18031 +#define CAR1_TR255 0x20000000
18032 +#define CAR1_TR511 0x10000000
18033 +#define CAR1_TRK1 0x08000000
18034 +#define CAR1_TRMAX 0x04000000
18035 +#define CAR1_TRMGV 0x02000000
18036 +
18037 +#define CAR1_RBYT 0x00010000
18038 +#define CAR1_RPKT 0x00008000
18039 +#define CAR1_RMCA 0x00002000
18040 +#define CAR1_RBCA 0x00001000
18041 +#define CAR1_RXPF 0x00000400
18042 +#define CAR1_RALN 0x00000100
18043 +#define CAR1_RFLR 0x00000080
18044 +#define CAR1_RCDE 0x00000040
18045 +#define CAR1_RCSE 0x00000020
18046 +#define CAR1_RUND 0x00000010
18047 +#define CAR1_ROVR 0x00000008
18048 +#define CAR1_RFRG 0x00000004
18049 +#define CAR1_RJBR 0x00000002
18050 +#define CAR1_RDRP 0x00000001
18051 +
18052 +#define CAR2_TFCS 0x00040000
18053 +#define CAR2_TBYT 0x00002000
18054 +#define CAR2_TPKT 0x00001000
18055 +#define CAR2_TMCA 0x00000800
18056 +#define CAR2_TBCA 0x00000400
18057 +#define CAR2_TXPF 0x00000200
18058 +#define CAR2_TDRP 0x00000001
18059 +
18060 +typedef struct t_InternalStatistics
18061 +{
18062 + uint64_t tr64;
18063 + uint64_t tr127;
18064 + uint64_t tr255;
18065 + uint64_t tr511;
18066 + uint64_t tr1k;
18067 + uint64_t trmax;
18068 + uint64_t trmgv;
18069 + uint64_t rfrg;
18070 + uint64_t rjbr;
18071 + uint64_t rdrp;
18072 + uint64_t raln;
18073 + uint64_t rund;
18074 + uint64_t rovr;
18075 + uint64_t rxpf;
18076 + uint64_t txpf;
18077 + uint64_t rbyt;
18078 + uint64_t rpkt;
18079 + uint64_t rmca;
18080 + uint64_t rbca;
18081 + uint64_t rflr;
18082 + uint64_t rcde;
18083 + uint64_t rcse;
18084 + uint64_t tbyt;
18085 + uint64_t tpkt;
18086 + uint64_t tmca;
18087 + uint64_t tbca;
18088 + uint64_t tdrp;
18089 + uint64_t tfcs;
18090 +} t_InternalStatistics;
18091 +
18092 +typedef struct {
18093 + t_FmMacControllerDriver fmMacControllerDriver;
18094 + t_Handle h_App; /**< Handle to the upper layer application */
18095 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
18096 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
18097 + uint64_t addr; /**< MAC address of device; */
18098 + e_EnetMode enetMode; /**< Ethernet physical interface */
18099 + t_FmMacExceptionCallback *f_Exception;
18100 + int mdioIrq;
18101 + t_FmMacExceptionCallback *f_Event;
18102 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
18103 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
18104 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
18105 + bool halfDuplex;
18106 + t_InternalStatistics internalStatistics;
18107 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
18108 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
18109 + uint8_t macId;
18110 + uint8_t tbi_phy_addr;
18111 + uint32_t exceptions;
18112 + bool ptpTsuEnabled;
18113 + bool enTsuErrExeption;
18114 + e_FmMacStatisticsLevel statisticsLevel;
18115 + struct dtsec_cfg *p_DtsecDriverParam;
18116 +} t_Dtsec;
18117 +
18118 +
18119 +#endif /* __DTSEC_H */
18120 --- /dev/null
18121 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
18122 @@ -0,0 +1,97 @@
18123 +/*
18124 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18125 + *
18126 + * Redistribution and use in source and binary forms, with or without
18127 + * modification, are permitted provided that the following conditions are met:
18128 + * * Redistributions of source code must retain the above copyright
18129 + * notice, this list of conditions and the following disclaimer.
18130 + * * Redistributions in binary form must reproduce the above copyright
18131 + * notice, this list of conditions and the following disclaimer in the
18132 + * documentation and/or other materials provided with the distribution.
18133 + * * Neither the name of Freescale Semiconductor nor the
18134 + * names of its contributors may be used to endorse or promote products
18135 + * derived from this software without specific prior written permission.
18136 + *
18137 + *
18138 + * ALTERNATIVELY, this software may be distributed under the terms of the
18139 + * GNU General Public License ("GPL") as published by the Free Software
18140 + * Foundation, either version 2 of that License or (at your option) any
18141 + * later version.
18142 + *
18143 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18144 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18145 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18146 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18147 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18148 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18149 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18150 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18151 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18152 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18153 + */
18154 +
18155 +
18156 +/******************************************************************************
18157 + @File dtsec_mii_acc.c
18158 +
18159 + @Description FM dtsec MII register access MAC ...
18160 +*//***************************************************************************/
18161 +
18162 +#include "error_ext.h"
18163 +#include "std_ext.h"
18164 +#include "fm_mac.h"
18165 +#include "dtsec.h"
18166 +#include "fsl_fman_dtsec_mii_acc.h"
18167 +
18168 +
18169 +/*****************************************************************************/
18170 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
18171 + uint8_t phyAddr,
18172 + uint8_t reg,
18173 + uint16_t data)
18174 +{
18175 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
18176 + struct dtsec_mii_reg *miiregs;
18177 + uint16_t dtsec_freq;
18178 + t_Error err;
18179 +
18180 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
18181 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
18182 +
18183 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
18184 + miiregs = p_Dtsec->p_MiiMemMap;
18185 +
18186 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
18187 +
18188 + return err;
18189 +}
18190 +
18191 +/*****************************************************************************/
18192 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
18193 + uint8_t phyAddr,
18194 + uint8_t reg,
18195 + uint16_t *p_Data)
18196 +{
18197 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
18198 + struct dtsec_mii_reg *miiregs;
18199 + uint16_t dtsec_freq;
18200 + t_Error err;
18201 +
18202 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
18203 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
18204 +
18205 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
18206 + miiregs = p_Dtsec->p_MiiMemMap;
18207 +
18208 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
18209 +
18210 + if (*p_Data == 0xffff)
18211 + RETURN_ERROR(MINOR, E_NO_DEVICE,
18212 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
18213 + phyAddr, reg));
18214 + if (err)
18215 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
18216 +
18217 + return E_OK;
18218 +}
18219 +
18220 --- /dev/null
18221 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
18222 @@ -0,0 +1,42 @@
18223 +/*
18224 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18225 + *
18226 + * Redistribution and use in source and binary forms, with or without
18227 + * modification, are permitted provided that the following conditions are met:
18228 + * * Redistributions of source code must retain the above copyright
18229 + * notice, this list of conditions and the following disclaimer.
18230 + * * Redistributions in binary form must reproduce the above copyright
18231 + * notice, this list of conditions and the following disclaimer in the
18232 + * documentation and/or other materials provided with the distribution.
18233 + * * Neither the name of Freescale Semiconductor nor the
18234 + * names of its contributors may be used to endorse or promote products
18235 + * derived from this software without specific prior written permission.
18236 + *
18237 + *
18238 + * ALTERNATIVELY, this software may be distributed under the terms of the
18239 + * GNU General Public License ("GPL") as published by the Free Software
18240 + * Foundation, either version 2 of that License or (at your option) any
18241 + * later version.
18242 + *
18243 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18244 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18245 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18246 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18247 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18248 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18249 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18250 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18251 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18252 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18253 + */
18254 +
18255 +#ifndef __DTSEC_MII_ACC_H
18256 +#define __DTSEC_MII_ACC_H
18257 +
18258 +#include "std_ext.h"
18259 +
18260 +
18261 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
18262 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
18263 +
18264 +#endif /* __DTSEC_MII_ACC_H */
18265 --- /dev/null
18266 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
18267 @@ -0,0 +1,674 @@
18268 +/*
18269 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18270 + *
18271 + * Redistribution and use in source and binary forms, with or without
18272 + * modification, are permitted provided that the following conditions are met:
18273 + * * Redistributions of source code must retain the above copyright
18274 + * notice, this list of conditions and the following disclaimer.
18275 + * * Redistributions in binary form must reproduce the above copyright
18276 + * notice, this list of conditions and the following disclaimer in the
18277 + * documentation and/or other materials provided with the distribution.
18278 + * * Neither the name of Freescale Semiconductor nor the
18279 + * names of its contributors may be used to endorse or promote products
18280 + * derived from this software without specific prior written permission.
18281 + *
18282 + *
18283 + * ALTERNATIVELY, this software may be distributed under the terms of the
18284 + * GNU General Public License ("GPL") as published by the Free Software
18285 + * Foundation, either version 2 of that License or (at your option) any
18286 + * later version.
18287 + *
18288 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18289 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18290 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18291 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18292 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18293 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18294 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18295 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18296 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18297 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18298 + */
18299 +
18300 +
18301 +/******************************************************************************
18302 + @File fm_mac.c
18303 +
18304 + @Description FM MAC ...
18305 +*//***************************************************************************/
18306 +#include "std_ext.h"
18307 +#include "string_ext.h"
18308 +#include "sprint_ext.h"
18309 +#include "error_ext.h"
18310 +#include "fm_ext.h"
18311 +
18312 +#include "fm_common.h"
18313 +#include "fm_mac.h"
18314 +
18315 +
18316 +/* ......................................................................... */
18317 +
18318 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
18319 +{
18320 + t_FmMacControllerDriver *p_FmMacControllerDriver;
18321 + uint16_t fmClkFreq;
18322 +
18323 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
18324 +
18325 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
18326 + if (fmClkFreq == 0)
18327 + {
18328 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
18329 + return NULL;
18330 + }
18331 +
18332 +#if (DPAA_VERSION == 10)
18333 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
18334 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
18335 + else
18336 +#if FM_MAX_NUM_OF_10G_MACS > 0
18337 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
18338 +#else
18339 + p_FmMacControllerDriver = NULL;
18340 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
18341 +#else
18342 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
18343 +#endif /* (DPAA_VERSION == 10) */
18344 +
18345 + if (!p_FmMacControllerDriver)
18346 + return NULL;
18347 +
18348 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
18349 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
18350 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
18351 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
18352 +
18353 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
18354 +
18355 + return (t_Handle)p_FmMacControllerDriver;
18356 +}
18357 +
18358 +/* ......................................................................... */
18359 +
18360 +t_Error FM_MAC_Init (t_Handle h_FmMac)
18361 +{
18362 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18363 +
18364 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18365 +
18366 + if (p_FmMacControllerDriver->resetOnInit &&
18367 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
18368 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
18369 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
18370 + e_FM_MAC_10G : e_FM_MAC_1G),
18371 + p_FmMacControllerDriver->macId) != E_OK))
18372 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
18373 +
18374 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
18375 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
18376 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18377 +}
18378 +
18379 +/* ......................................................................... */
18380 +
18381 +t_Error FM_MAC_Free (t_Handle h_FmMac)
18382 +{
18383 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18384 +
18385 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18386 +
18387 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
18388 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
18389 +
18390 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18391 +}
18392 +
18393 +/* ......................................................................... */
18394 +
18395 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
18396 +{
18397 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18398 +
18399 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18400 +
18401 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
18402 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
18403 +
18404 + p_FmMacControllerDriver->resetOnInit = enable;
18405 +
18406 + return E_OK;
18407 +}
18408 +
18409 +/* ......................................................................... */
18410 +
18411 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
18412 +{
18413 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18414 +
18415 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18416 +
18417 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
18418 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
18419 +
18420 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18421 +}
18422 +
18423 +/* ......................................................................... */
18424 +
18425 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
18426 +{
18427 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18428 +
18429 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18430 +
18431 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
18432 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
18433 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18434 +}
18435 +
18436 +/* ......................................................................... */
18437 +
18438 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
18439 +{
18440 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18441 +
18442 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18443 +
18444 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
18445 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
18446 +
18447 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18448 +}
18449 +
18450 +/* ......................................................................... */
18451 +
18452 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
18453 +{
18454 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18455 +
18456 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18457 +
18458 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
18459 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
18460 +
18461 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18462 +}
18463 +
18464 +/* ......................................................................... */
18465 +
18466 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
18467 +{
18468 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18469 +
18470 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18471 +
18472 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
18473 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
18474 +
18475 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18476 +}
18477 +
18478 +/* ......................................................................... */
18479 +
18480 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
18481 +{
18482 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18483 +
18484 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18485 +
18486 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
18487 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
18488 +
18489 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18490 +}
18491 +
18492 +/* ......................................................................... */
18493 +
18494 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
18495 +{
18496 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18497 +
18498 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18499 +
18500 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
18501 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
18502 +
18503 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18504 +}
18505 +
18506 +/* ......................................................................... */
18507 +
18508 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
18509 +{
18510 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18511 +
18512 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18513 +
18514 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
18515 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
18516 +
18517 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18518 +}
18519 +
18520 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
18521 +/* ......................................................................... */
18522 +
18523 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
18524 +{
18525 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18526 +
18527 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18528 +
18529 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
18530 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
18531 +
18532 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18533 +}
18534 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
18535 +
18536 +
18537 +/*****************************************************************************/
18538 +/* Run Time Control */
18539 +/*****************************************************************************/
18540 +
18541 +/* ......................................................................... */
18542 +
18543 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
18544 +{
18545 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18546 +
18547 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18548 +
18549 + if (p_FmMacControllerDriver->f_FM_MAC_Enable)
18550 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
18551 +
18552 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18553 +}
18554 +
18555 +/* ......................................................................... */
18556 +
18557 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
18558 +{
18559 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18560 +
18561 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18562 +
18563 + if (p_FmMacControllerDriver->f_FM_MAC_Disable)
18564 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
18565 +
18566 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18567 +}
18568 +
18569 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
18570 +{
18571 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18572 +
18573 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18574 +
18575 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
18576 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
18577 +
18578 + return E_OK;
18579 +}
18580 +
18581 +/* ......................................................................... */
18582 +
18583 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
18584 +{
18585 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18586 +
18587 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18588 +
18589 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
18590 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
18591 +
18592 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18593 +}
18594 +
18595 +/* ......................................................................... */
18596 +
18597 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
18598 +{
18599 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18600 +
18601 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18602 +
18603 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
18604 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
18605 +
18606 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18607 +}
18608 +
18609 +/* ......................................................................... */
18610 +
18611 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
18612 + uint16_t pauseTime)
18613 +{
18614 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18615 +
18616 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18617 +
18618 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
18619 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
18620 + pauseTime);
18621 +
18622 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18623 +}
18624 +
18625 +/* ......................................................................... */
18626 +
18627 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
18628 + uint8_t priority,
18629 + uint16_t pauseTime,
18630 + uint16_t threshTime)
18631 +{
18632 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18633 +
18634 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18635 +
18636 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
18637 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
18638 + priority,
18639 + pauseTime,
18640 + threshTime);
18641 +
18642 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
18643 +}
18644 +
18645 +/* ......................................................................... */
18646 +
18647 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
18648 +{
18649 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18650 +
18651 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18652 +
18653 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
18654 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
18655 +
18656 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18657 +}
18658 +
18659 +/* ......................................................................... */
18660 +
18661 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
18662 +{
18663 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18664 +
18665 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18666 +
18667 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
18668 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
18669 +
18670 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18671 +}
18672 +
18673 +/* ......................................................................... */
18674 +
18675 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
18676 +{
18677 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18678 +
18679 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18680 +
18681 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
18682 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
18683 +
18684 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18685 +}
18686 +
18687 +/* ......................................................................... */
18688 +
18689 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
18690 +{
18691 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18692 +
18693 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18694 +
18695 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
18696 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
18697 +
18698 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18699 +}
18700 +
18701 +/* ......................................................................... */
18702 +
18703 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
18704 +{
18705 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18706 +
18707 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18708 +
18709 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
18710 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
18711 +
18712 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18713 +}
18714 +
18715 +/* ......................................................................... */
18716 +
18717 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
18718 +{
18719 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18720 +
18721 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18722 +
18723 + if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
18724 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
18725 +
18726 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18727 +}
18728 +
18729 +/* ......................................................................... */
18730 +
18731 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
18732 +{
18733 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18734 +
18735 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18736 +
18737 + memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters));
18738 +
18739 + if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters)
18740 + return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type);
18741 +
18742 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18743 +}
18744 +
18745 +/* ......................................................................... */
18746 +
18747 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
18748 +{
18749 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18750 +
18751 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18752 +
18753 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
18754 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
18755 +
18756 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18757 +}
18758 +
18759 +/* ......................................................................... */
18760 +
18761 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
18762 +{
18763 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18764 +
18765 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18766 +
18767 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
18768 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
18769 +
18770 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18771 +}
18772 +
18773 +/* ......................................................................... */
18774 +
18775 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
18776 +{
18777 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18778 +
18779 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18780 +
18781 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
18782 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
18783 +
18784 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18785 +}
18786 +
18787 +/* ......................................................................... */
18788 +
18789 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
18790 +{
18791 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18792 +
18793 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18794 +
18795 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
18796 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
18797 +
18798 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18799 +}
18800 +
18801 +/* ......................................................................... */
18802 +
18803 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
18804 +{
18805 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18806 +
18807 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18808 +
18809 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
18810 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
18811 +
18812 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18813 +}
18814 +
18815 +/* ......................................................................... */
18816 +
18817 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
18818 +{
18819 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18820 +
18821 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18822 +
18823 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
18824 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
18825 +
18826 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18827 +
18828 +}
18829 +
18830 +/* ......................................................................... */
18831 +
18832 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
18833 +{
18834 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18835 +
18836 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18837 +
18838 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
18839 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
18840 +
18841 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18842 +}
18843 +
18844 +/* ......................................................................... */
18845 +
18846 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
18847 +{
18848 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18849 +
18850 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18851 +
18852 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
18853 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
18854 +
18855 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18856 +}
18857 +
18858 +/* ......................................................................... */
18859 +
18860 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
18861 +{
18862 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18863 +
18864 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18865 +
18866 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
18867 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
18868 +
18869 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18870 +}
18871 +
18872 +/* ......................................................................... */
18873 +
18874 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
18875 +{
18876 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18877 +
18878 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18879 +
18880 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
18881 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
18882 +
18883 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18884 +}
18885 +
18886 +/* ......................................................................... */
18887 +
18888 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
18889 +{
18890 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18891 +
18892 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18893 +
18894 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
18895 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
18896 +
18897 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18898 +}
18899 +
18900 +/* ......................................................................... */
18901 +
18902 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
18903 +{
18904 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18905 +
18906 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18907 +
18908 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
18909 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
18910 +
18911 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18912 +}
18913 +
18914 +/* ......................................................................... */
18915 +
18916 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
18917 +{
18918 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18919 +
18920 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
18921 +
18922 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
18923 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
18924 +
18925 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18926 + return 0;
18927 +}
18928 +
18929 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
18930 +/*****************************************************************************/
18931 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
18932 +{
18933 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18934 +
18935 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18936 +
18937 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
18938 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
18939 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18940 +}
18941 +#endif /* (defined(DEBUG_ERRORS) && ... */
18942 --- /dev/null
18943 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
18944 @@ -0,0 +1,226 @@
18945 +/*
18946 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18947 + *
18948 + * Redistribution and use in source and binary forms, with or without
18949 + * modification, are permitted provided that the following conditions are met:
18950 + * * Redistributions of source code must retain the above copyright
18951 + * notice, this list of conditions and the following disclaimer.
18952 + * * Redistributions in binary form must reproduce the above copyright
18953 + * notice, this list of conditions and the following disclaimer in the
18954 + * documentation and/or other materials provided with the distribution.
18955 + * * Neither the name of Freescale Semiconductor nor the
18956 + * names of its contributors may be used to endorse or promote products
18957 + * derived from this software without specific prior written permission.
18958 + *
18959 + *
18960 + * ALTERNATIVELY, this software may be distributed under the terms of the
18961 + * GNU General Public License ("GPL") as published by the Free Software
18962 + * Foundation, either version 2 of that License or (at your option) any
18963 + * later version.
18964 + *
18965 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18966 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18967 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18968 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18969 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18970 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18971 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18972 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18973 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18974 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18975 + */
18976 +
18977 +
18978 +/******************************************************************************
18979 + @File fm_mac.h
18980 +
18981 + @Description FM MAC ...
18982 +*//***************************************************************************/
18983 +#ifndef __FM_MAC_H
18984 +#define __FM_MAC_H
18985 +
18986 +#include "std_ext.h"
18987 +#include "error_ext.h"
18988 +#include "list_ext.h"
18989 +#include "fm_mac_ext.h"
18990 +#include "fm_common.h"
18991 +
18992 +
18993 +#define __ERR_MODULE__ MODULE_FM_MAC
18994 +
18995 +/**************************************************************************//**
18996 + @Description defaults
18997 +*//***************************************************************************/
18998 +
18999 +
19000 +#define DEFAULT_halfDuplex FALSE
19001 +#define DEFAULT_padAndCrcEnable TRUE
19002 +#define DEFAULT_resetOnInit FALSE
19003 +
19004 +
19005 +typedef struct {
19006 + uint64_t addr; /* Ethernet Address */
19007 + t_List node;
19008 +} t_EthHashEntry;
19009 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
19010 +
19011 +typedef struct {
19012 + uint16_t size;
19013 + t_List *p_Lsts;
19014 +} t_EthHash;
19015 +
19016 +typedef struct {
19017 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
19018 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
19019 +
19020 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
19021 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
19022 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
19023 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
19024 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
19025 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
19026 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
19027 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
19028 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
19029 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
19030 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
19031 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
19032 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
19033 +
19034 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
19035 +
19036 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
19037 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
19038 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
19039 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
19040 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
19041 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
19042 +
19043 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
19044 + uint16_t pauseTime);
19045 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
19046 + uint8_t priority,
19047 + uint16_t pauseTime,
19048 + uint16_t threshTime);
19049 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
19050 +
19051 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
19052 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
19053 + t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
19054 +
19055 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19056 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19057 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19058 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19059 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19060 +
19061 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
19062 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
19063 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
19064 +
19065 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
19066 +
19067 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
19068 +
19069 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
19070 +
19071 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
19072 +
19073 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
19074 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
19075 +
19076 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
19077 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
19078 +#endif /* (defined(DEBUG_ERRORS) && ... */
19079 +
19080 + t_Handle h_Fm;
19081 + t_FmRevisionInfo fmRevInfo;
19082 + e_EnetMode enetMode;
19083 + uint8_t macId;
19084 + bool resetOnInit;
19085 + uint16_t clkFreq;
19086 +} t_FmMacControllerDriver;
19087 +
19088 +
19089 +#if (DPAA_VERSION == 10)
19090 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
19091 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
19092 +#else
19093 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
19094 +#endif /* (DPAA_VERSION == 10) */
19095 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
19096 +
19097 +
19098 +/* ........................................................................... */
19099 +
19100 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
19101 +{
19102 + t_EthHashEntry *p_HashEntry = NULL;
19103 + if (!LIST_IsEmpty(p_AddrLst))
19104 + {
19105 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
19106 + LIST_DelAndInit(&p_HashEntry->node);
19107 + }
19108 + return p_HashEntry;
19109 +}
19110 +
19111 +/* ........................................................................... */
19112 +
19113 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
19114 +{
19115 + t_EthHashEntry *p_HashEntry;
19116 + int i = 0;
19117 +
19118 + if (p_Hash)
19119 + {
19120 + if (p_Hash->p_Lsts)
19121 + {
19122 + for (i=0; i<p_Hash->size; i++)
19123 + {
19124 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
19125 + while (p_HashEntry)
19126 + {
19127 + XX_Free(p_HashEntry);
19128 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
19129 + }
19130 + }
19131 +
19132 + XX_Free(p_Hash->p_Lsts);
19133 + }
19134 +
19135 + XX_Free(p_Hash);
19136 + }
19137 +}
19138 +
19139 +/* ........................................................................... */
19140 +
19141 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
19142 +{
19143 + uint32_t i;
19144 + t_EthHash *p_Hash;
19145 +
19146 + /* Allocate address hash table */
19147 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
19148 + if (!p_Hash)
19149 + {
19150 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
19151 + return NULL;
19152 + }
19153 + p_Hash->size = size;
19154 +
19155 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
19156 + if (!p_Hash->p_Lsts)
19157 + {
19158 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
19159 + XX_Free(p_Hash);
19160 + return NULL;
19161 + }
19162 +
19163 + for (i=0 ; i<p_Hash->size; i++)
19164 + INIT_LIST(&p_Hash->p_Lsts[i]);
19165 +
19166 + return p_Hash;
19167 +}
19168 +
19169 +
19170 +#endif /* __FM_MAC_H */
19171 --- /dev/null
19172 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
19173 @@ -0,0 +1,119 @@
19174 +/*
19175 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19176 + *
19177 + * Redistribution and use in source and binary forms, with or without
19178 + * modification, are permitted provided that the following conditions are met:
19179 + * * Redistributions of source code must retain the above copyright
19180 + * notice, this list of conditions and the following disclaimer.
19181 + * * Redistributions in binary form must reproduce the above copyright
19182 + * notice, this list of conditions and the following disclaimer in the
19183 + * documentation and/or other materials provided with the distribution.
19184 + * * Neither the name of Freescale Semiconductor nor the
19185 + * names of its contributors may be used to endorse or promote products
19186 + * derived from this software without specific prior written permission.
19187 + *
19188 + *
19189 + * ALTERNATIVELY, this software may be distributed under the terms of the
19190 + * GNU General Public License ("GPL") as published by the Free Software
19191 + * Foundation, either version 2 of that License or (at your option) any
19192 + * later version.
19193 + *
19194 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19195 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19196 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19197 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19198 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19199 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19200 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19201 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19202 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19203 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19204 + */
19205 +
19206 +
19207 +#include "fman_crc32.h"
19208 +#include "common/general.h"
19209 +
19210 +
19211 +/* precomputed CRC values for address hashing */
19212 +static const uint32_t crc_tbl[256] = {
19213 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
19214 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
19215 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
19216 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
19217 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
19218 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
19219 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
19220 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
19221 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
19222 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
19223 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
19224 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
19225 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
19226 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
19227 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
19228 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
19229 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
19230 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
19231 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
19232 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
19233 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
19234 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
19235 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
19236 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
19237 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
19238 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
19239 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
19240 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
19241 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
19242 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
19243 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
19244 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
19245 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
19246 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
19247 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
19248 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
19249 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
19250 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
19251 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
19252 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
19253 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
19254 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
19255 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
19256 +};
19257 +
19258 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
19259 +static inline uint8_t get_mirror8(uint8_t n)
19260 +{
19261 + uint8_t mirror[16] = {
19262 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
19263 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
19264 + };
19265 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
19266 +}
19267 +
19268 +static inline uint32_t get_mirror32(uint32_t n)
19269 +{
19270 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
19271 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
19272 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
19273 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
19274 +}
19275 +
19276 +uint32_t get_mac_addr_crc(uint64_t _addr)
19277 +{
19278 + uint32_t i;
19279 + uint8_t data;
19280 + uint32_t crc;
19281 +
19282 + /* CRC calculation */
19283 + crc = 0xffffffff;
19284 + for (i = 0; i < 6; i++) {
19285 + data = (uint8_t)(_addr >> ((5-i)*8));
19286 + crc = crc ^ data;
19287 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
19288 + }
19289 +
19290 + crc = get_mirror32(crc);
19291 + return crc;
19292 +}
19293 --- /dev/null
19294 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
19295 @@ -0,0 +1,43 @@
19296 +/*
19297 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19298 + *
19299 + * Redistribution and use in source and binary forms, with or without
19300 + * modification, are permitted provided that the following conditions are met:
19301 + * * Redistributions of source code must retain the above copyright
19302 + * notice, this list of conditions and the following disclaimer.
19303 + * * Redistributions in binary form must reproduce the above copyright
19304 + * notice, this list of conditions and the following disclaimer in the
19305 + * documentation and/or other materials provided with the distribution.
19306 + * * Neither the name of Freescale Semiconductor nor the
19307 + * names of its contributors may be used to endorse or promote products
19308 + * derived from this software without specific prior written permission.
19309 + *
19310 + *
19311 + * ALTERNATIVELY, this software may be distributed under the terms of the
19312 + * GNU General Public License ("GPL") as published by the Free Software
19313 + * Foundation, either version 2 of that License or (at your option) any
19314 + * later version.
19315 + *
19316 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19317 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19318 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19319 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19320 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19321 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19322 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19323 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19324 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19325 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19326 + */
19327 +
19328 +
19329 +#ifndef __FMAN_CRC32_H
19330 +#define __FMAN_CRC32_H
19331 +
19332 +#include "common/general.h"
19333 +
19334 +
19335 +uint32_t get_mac_addr_crc(uint64_t _addr);
19336 +
19337 +
19338 +#endif /* __FMAN_CRC32_H */
19339 --- /dev/null
19340 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
19341 @@ -0,0 +1,847 @@
19342 +/*
19343 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19344 + *
19345 + * Redistribution and use in source and binary forms, with or without
19346 + * modification, are permitted provided that the following conditions are met:
19347 + * * Redistributions of source code must retain the above copyright
19348 + * notice, this list of conditions and the following disclaimer.
19349 + * * Redistributions in binary form must reproduce the above copyright
19350 + * notice, this list of conditions and the following disclaimer in the
19351 + * documentation and/or other materials provided with the distribution.
19352 + * * Neither the name of Freescale Semiconductor nor the
19353 + * names of its contributors may be used to endorse or promote products
19354 + * derived from this software without specific prior written permission.
19355 + *
19356 + *
19357 + * ALTERNATIVELY, this software may be distributed under the terms of the
19358 + * GNU General Public License ("GPL") as published by the Free Software
19359 + * Foundation, either version 2 of that License or (at your option) any
19360 + * later version.
19361 + *
19362 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19363 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19364 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19365 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19366 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19367 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19368 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19369 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19370 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19371 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19372 + */
19373 +
19374 +
19375 +#include "std_ext.h"
19376 +#include "error_ext.h"
19377 +#include "fsl_fman_dtsec.h"
19378 +
19379 +
19380 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
19381 +{
19382 + /* Assert the graceful stop bit */
19383 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
19384 +}
19385 +
19386 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
19387 +{
19388 + /* Assert the graceful stop bit */
19389 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
19390 +}
19391 +
19392 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
19393 +{
19394 + /* clear the graceful stop bit */
19395 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
19396 +}
19397 +
19398 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
19399 +{
19400 + /* clear the graceful stop bit */
19401 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
19402 +}
19403 +
19404 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
19405 +{
19406 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
19407 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
19408 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
19409 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
19410 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
19411 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
19412 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
19413 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
19414 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
19415 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
19416 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
19417 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
19418 + cfg->tx_crc = DEFAULT_TX_CRC;
19419 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
19420 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
19421 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
19422 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
19423 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
19424 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
19425 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
19426 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
19427 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
19428 + cfg->loopback = DEFAULT_LOOPBACK;
19429 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
19430 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
19431 + cfg->rx_flow = DEFAULT_RX_FLOW;
19432 + cfg->tx_flow = DEFAULT_TX_FLOW;
19433 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
19434 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
19435 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
19436 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
19437 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
19438 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
19439 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
19440 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
19441 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
19442 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
19443 +}
19444 +
19445 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
19446 + enum enet_interface iface_mode,
19447 + enum enet_speed iface_speed,
19448 + uint8_t *macaddr,
19449 + uint8_t fm_rev_maj,
19450 + uint8_t fm_rev_min,
19451 + uint32_t exception_mask)
19452 +{
19453 + bool is_rgmii = FALSE;
19454 + bool is_sgmii = FALSE;
19455 + bool is_qsgmii = FALSE;
19456 + int i;
19457 + uint32_t tmp;
19458 +
19459 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
19460 +
19461 + /* let's start with a soft reset */
19462 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
19463 + iowrite32be(0, &regs->maccfg1);
19464 +
19465 + /*************dtsec_id2******************/
19466 + tmp = ioread32be(&regs->tsec_id2);
19467 +
19468 + /* check RGMII support */
19469 + if (iface_mode == E_ENET_IF_RGMII ||
19470 + iface_mode == E_ENET_IF_RMII)
19471 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
19472 + return -EINVAL;
19473 +
19474 + if (iface_mode == E_ENET_IF_SGMII ||
19475 + iface_mode == E_ENET_IF_MII)
19476 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
19477 + return -EINVAL;
19478 +
19479 + /***************ECNTRL************************/
19480 +
19481 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
19482 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
19483 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
19484 +
19485 + tmp = 0;
19486 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
19487 + tmp |= DTSEC_ECNTRL_GMIIM;
19488 + if (is_sgmii)
19489 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
19490 + if (is_qsgmii)
19491 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
19492 + DTSEC_ECNTRL_QSGMIIM);
19493 + if (is_rgmii)
19494 + tmp |= DTSEC_ECNTRL_RPM;
19495 + if (iface_speed == E_ENET_SPEED_100)
19496 + tmp |= DTSEC_ECNTRL_R100M;
19497 +
19498 + iowrite32be(tmp, &regs->ecntrl);
19499 + /***************ECNTRL************************/
19500 +
19501 + /***************TCTRL************************/
19502 + tmp = 0;
19503 + if (cfg->halfdup_on)
19504 + tmp |= DTSEC_TCTRL_THDF;
19505 + if (cfg->tx_time_stamp_en)
19506 + tmp |= DTSEC_TCTRL_TTSE;
19507 +
19508 + iowrite32be(tmp, &regs->tctrl);
19509 +
19510 + /***************TCTRL************************/
19511 +
19512 + /***************PTV************************/
19513 + tmp = 0;
19514 +
19515 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
19516 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
19517 + cfg->tx_pause_time += 2;
19518 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
19519 +
19520 + if (cfg->tx_pause_time)
19521 + tmp |= cfg->tx_pause_time;
19522 + if (cfg->tx_pause_time_extd)
19523 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
19524 + iowrite32be(tmp, &regs->ptv);
19525 +
19526 + /***************RCTRL************************/
19527 + tmp = 0;
19528 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
19529 + if (cfg->rx_ctrl_acc)
19530 + tmp |= RCTRL_CFA;
19531 + if (cfg->rx_group_hash_exd)
19532 + tmp |= RCTRL_GHTX;
19533 + if (cfg->rx_time_stamp_en)
19534 + tmp |= RCTRL_RTSE;
19535 + if (cfg->rx_drop_bcast)
19536 + tmp |= RCTRL_BC_REJ;
19537 + if (cfg->rx_short_frm)
19538 + tmp |= RCTRL_RSF;
19539 + if (cfg->rx_promisc)
19540 + tmp |= RCTRL_PROM;
19541 +
19542 + iowrite32be(tmp, &regs->rctrl);
19543 + /***************RCTRL************************/
19544 +
19545 + /*
19546 + * Assign a Phy Address to the TBI (TBIPA).
19547 + * Done also in cases where TBI is not selected to avoid conflict with
19548 + * the external PHY's Physical address
19549 + */
19550 + iowrite32be(cfg->tbipa, &regs->tbipa);
19551 +
19552 + /***************TMR_CTL************************/
19553 + iowrite32be(0, &regs->tmr_ctrl);
19554 +
19555 + if (cfg->ptp_tsu_en) {
19556 + tmp = 0;
19557 + tmp |= TMR_PEVENT_TSRE;
19558 + iowrite32be(tmp, &regs->tmr_pevent);
19559 +
19560 + if (cfg->ptp_exception_en) {
19561 + tmp = 0;
19562 + tmp |= TMR_PEMASK_TSREEN;
19563 + iowrite32be(tmp, &regs->tmr_pemask);
19564 + }
19565 + }
19566 +
19567 + /***************MACCFG1***********************/
19568 + tmp = 0;
19569 + if (cfg->loopback)
19570 + tmp |= MACCFG1_LOOPBACK;
19571 + if (cfg->rx_flow)
19572 + tmp |= MACCFG1_RX_FLOW;
19573 + if (cfg->tx_flow)
19574 + tmp |= MACCFG1_TX_FLOW;
19575 + iowrite32be(tmp, &regs->maccfg1);
19576 +
19577 + /***************MACCFG1***********************/
19578 +
19579 + /***************MACCFG2***********************/
19580 + tmp = 0;
19581 +
19582 + if (iface_speed < E_ENET_SPEED_1000)
19583 + tmp |= MACCFG2_NIBBLE_MODE;
19584 + else if (iface_speed == E_ENET_SPEED_1000)
19585 + tmp |= MACCFG2_BYTE_MODE;
19586 +
19587 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
19588 + << PREAMBLE_LENGTH_SHIFT;
19589 +
19590 + if (cfg->rx_preamble)
19591 + tmp |= MACCFG2_PRE_AM_Rx_EN;
19592 + if (cfg->tx_preamble)
19593 + tmp |= MACCFG2_PRE_AM_Tx_EN;
19594 + if (cfg->rx_len_check)
19595 + tmp |= MACCFG2_LENGTH_CHECK;
19596 + if (cfg->tx_pad_crc)
19597 + tmp |= MACCFG2_PAD_CRC_EN;
19598 + if (cfg->tx_crc)
19599 + tmp |= MACCFG2_CRC_EN;
19600 + if (!cfg->halfdup_on)
19601 + tmp |= MACCFG2_FULL_DUPLEX;
19602 + iowrite32be(tmp, &regs->maccfg2);
19603 +
19604 + /***************MACCFG2***********************/
19605 +
19606 + /***************IPGIFG************************/
19607 + tmp = (((cfg->non_back_to_back_ipg1 <<
19608 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
19609 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
19610 + | ((cfg->non_back_to_back_ipg2 <<
19611 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
19612 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
19613 + | ((cfg->min_ifg_enforcement <<
19614 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
19615 + & IPGIFG_MIN_IFG_ENFORCEMENT)
19616 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
19617 + iowrite32be(tmp, &regs->ipgifg);
19618 +
19619 + /***************IPGIFG************************/
19620 +
19621 + /***************HAFDUP************************/
19622 + tmp = 0;
19623 +
19624 + if (cfg->halfdup_alt_backoff_en)
19625 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
19626 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
19627 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
19628 + if (cfg->halfdup_bp_no_backoff)
19629 + tmp |= HAFDUP_BP_NO_BACKOFF;
19630 + if (cfg->halfdup_no_backoff)
19631 + tmp |= HAFDUP_NO_BACKOFF;
19632 + if (cfg->halfdup_excess_defer)
19633 + tmp |= HAFDUP_EXCESS_DEFER;
19634 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
19635 + & HAFDUP_RETRANSMISSION_MAX);
19636 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
19637 +
19638 + iowrite32be(tmp, &regs->hafdup);
19639 + /***************HAFDUP************************/
19640 +
19641 + /***************MAXFRM************************/
19642 + /* Initialize MAXFRM */
19643 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
19644 +
19645 + /***************MAXFRM************************/
19646 +
19647 + /***************CAM1************************/
19648 + iowrite32be(0xffffffff, &regs->cam1);
19649 + iowrite32be(0xffffffff, &regs->cam2);
19650 +
19651 + /***************IMASK************************/
19652 + iowrite32be(exception_mask, &regs->imask);
19653 + /***************IMASK************************/
19654 +
19655 + /***************IEVENT************************/
19656 + iowrite32be(0xffffffff, &regs->ievent);
19657 +
19658 + /***************MACSTNADDR1/2*****************/
19659 +
19660 + tmp = (uint32_t)((macaddr[5] << 24) |
19661 + (macaddr[4] << 16) |
19662 + (macaddr[3] << 8) |
19663 + macaddr[2]);
19664 + iowrite32be(tmp, &regs->macstnaddr1);
19665 +
19666 + tmp = (uint32_t)((macaddr[1] << 24) |
19667 + (macaddr[0] << 16));
19668 + iowrite32be(tmp, &regs->macstnaddr2);
19669 +
19670 + /***************MACSTNADDR1/2*****************/
19671 +
19672 + /*****************HASH************************/
19673 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
19674 + /* Initialize IADDRx */
19675 + iowrite32be(0, &regs->igaddr[i]);
19676 + /* Initialize GADDRx */
19677 + iowrite32be(0, &regs->gaddr[i]);
19678 + }
19679 +
19680 + fman_dtsec_reset_stat(regs);
19681 +
19682 + return 0;
19683 +}
19684 +
19685 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
19686 +{
19687 + return (uint16_t)ioread32be(&regs->maxfrm);
19688 +}
19689 +
19690 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
19691 +{
19692 + iowrite32be(length, &regs->maxfrm);
19693 +}
19694 +
19695 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
19696 +{
19697 + uint32_t tmp;
19698 +
19699 + tmp = (uint32_t)((adr[5] << 24) |
19700 + (adr[4] << 16) |
19701 + (adr[3] << 8) |
19702 + adr[2]);
19703 + iowrite32be(tmp, &regs->macstnaddr1);
19704 +
19705 + tmp = (uint32_t)((adr[1] << 24) |
19706 + (adr[0] << 16));
19707 + iowrite32be(tmp, &regs->macstnaddr2);
19708 +}
19709 +
19710 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
19711 +{
19712 + uint32_t tmp1, tmp2;
19713 +
19714 + tmp1 = ioread32be(&regs->macstnaddr1);
19715 + tmp2 = ioread32be(&regs->macstnaddr2);
19716 +
19717 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
19718 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
19719 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
19720 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
19721 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
19722 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
19723 +}
19724 +
19725 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
19726 +{
19727 + int32_t bucket;
19728 + if (ghtx)
19729 + bucket = (int32_t)((crc >> 23) & 0x1ff);
19730 + else {
19731 + bucket = (int32_t)((crc >> 24) & 0xff);
19732 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
19733 + if (mcast)
19734 + bucket += 0x100;
19735 + }
19736 + fman_dtsec_set_bucket(regs, bucket, TRUE);
19737 +}
19738 +
19739 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
19740 +{
19741 + int reg_idx = (bucket >> 5) & 0xf;
19742 + int bit_idx = bucket & 0x1f;
19743 + uint32_t bit_mask = 0x80000000 >> bit_idx;
19744 + uint32_t *reg;
19745 +
19746 + if (reg_idx > 7)
19747 + reg = &regs->gaddr[reg_idx-8];
19748 + else
19749 + reg = &regs->igaddr[reg_idx];
19750 +
19751 + if (enable)
19752 + iowrite32be(ioread32be(reg) | bit_mask, reg);
19753 + else
19754 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
19755 +}
19756 +
19757 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
19758 +{
19759 + int i;
19760 + bool ghtx;
19761 +
19762 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
19763 +
19764 + if (ucast || (ghtx && mcast)) {
19765 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
19766 + iowrite32be(0, &regs->igaddr[i]);
19767 + }
19768 + if (mcast) {
19769 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
19770 + iowrite32be(0, &regs->gaddr[i]);
19771 + }
19772 +}
19773 +
19774 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
19775 + uint8_t addr)
19776 +{
19777 + if (addr > 0 && addr < 32)
19778 + iowrite32be(addr, &regs->tbipa);
19779 + else
19780 + return -EINVAL;
19781 +
19782 + return 0;
19783 +}
19784 +
19785 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
19786 +{
19787 + uint32_t tmp;
19788 +
19789 + tmp = ioread32be(&regs->maccfg2);
19790 + if (en)
19791 + tmp |= MACCFG2_MAGIC_PACKET_EN;
19792 + else
19793 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
19794 + iowrite32be(tmp, &regs->maccfg2);
19795 +}
19796 +
19797 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
19798 + enum enet_interface iface_mode,
19799 + enum enet_speed speed, bool full_dx)
19800 +{
19801 + uint32_t tmp;
19802 +
19803 + UNUSED(iface_mode);
19804 +
19805 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
19806 + return -EINVAL;
19807 +
19808 + tmp = ioread32be(&regs->maccfg2);
19809 + if (!full_dx)
19810 + tmp &= ~MACCFG2_FULL_DUPLEX;
19811 + else
19812 + tmp |= MACCFG2_FULL_DUPLEX;
19813 +
19814 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
19815 + if (speed < E_ENET_SPEED_1000)
19816 + tmp |= MACCFG2_NIBBLE_MODE;
19817 + else if (speed == E_ENET_SPEED_1000)
19818 + tmp |= MACCFG2_BYTE_MODE;
19819 + iowrite32be(tmp, &regs->maccfg2);
19820 +
19821 + tmp = ioread32be(&regs->ecntrl);
19822 + if (speed == E_ENET_SPEED_100)
19823 + tmp |= DTSEC_ECNTRL_R100M;
19824 + else
19825 + tmp &= ~DTSEC_ECNTRL_R100M;
19826 + iowrite32be(tmp, &regs->ecntrl);
19827 +
19828 + return 0;
19829 +}
19830 +
19831 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
19832 +{
19833 + uint32_t tmp;
19834 +
19835 + tmp = ioread32be(&regs->rctrl);
19836 +
19837 + if (enable)
19838 + tmp |= RCTRL_UPROM;
19839 + else
19840 + tmp &= ~RCTRL_UPROM;
19841 +
19842 + iowrite32be(tmp, &regs->rctrl);
19843 +}
19844 +
19845 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
19846 +{
19847 + uint32_t tmp;
19848 +
19849 + tmp = ioread32be(&regs->rctrl);
19850 +
19851 + if (enable)
19852 + tmp |= RCTRL_MPROM;
19853 + else
19854 + tmp &= ~RCTRL_MPROM;
19855 +
19856 + iowrite32be(tmp, &regs->rctrl);
19857 +}
19858 +
19859 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
19860 + uint32_t *car1, uint32_t *car2)
19861 +{
19862 + /* read carry registers */
19863 + *car1 = ioread32be(&regs->car1);
19864 + *car2 = ioread32be(&regs->car2);
19865 + /* clear carry registers */
19866 + if (*car1)
19867 + iowrite32be(*car1, &regs->car1);
19868 + if (*car2)
19869 + iowrite32be(*car2, &regs->car2);
19870 +
19871 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
19872 +}
19873 +
19874 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
19875 +{
19876 + /* clear HW counters */
19877 + iowrite32be(ioread32be(&regs->ecntrl) |
19878 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
19879 +}
19880 +
19881 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
19882 +{
19883 + switch (level) {
19884 + case E_MAC_STAT_NONE:
19885 + iowrite32be(0xffffffff, &regs->cam1);
19886 + iowrite32be(0xffffffff, &regs->cam2);
19887 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
19888 + &regs->ecntrl);
19889 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
19890 + &regs->imask);
19891 + break;
19892 + case E_MAC_STAT_PARTIAL:
19893 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
19894 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
19895 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
19896 + &regs->ecntrl);
19897 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
19898 + &regs->imask);
19899 + break;
19900 + case E_MAC_STAT_MIB_GRP1:
19901 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
19902 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
19903 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
19904 + &regs->ecntrl);
19905 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
19906 + &regs->imask);
19907 + break;
19908 + case E_MAC_STAT_FULL:
19909 + iowrite32be(0, &regs->cam1);
19910 + iowrite32be(0, &regs->cam2);
19911 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
19912 + &regs->ecntrl);
19913 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
19914 + &regs->imask);
19915 + break;
19916 + default:
19917 + return -EINVAL;
19918 + }
19919 +
19920 + return 0;
19921 +}
19922 +
19923 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
19924 +{
19925 + if (en) {
19926 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
19927 + &regs->rctrl);
19928 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
19929 + &regs->tctrl);
19930 + } else {
19931 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
19932 + &regs->rctrl);
19933 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
19934 + &regs->tctrl);
19935 + }
19936 +}
19937 +
19938 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
19939 +{
19940 + uint32_t tmp;
19941 +
19942 + tmp = ioread32be(&regs->maccfg1);
19943 +
19944 + if (apply_rx)
19945 + tmp |= MACCFG1_RX_EN ;
19946 +
19947 + if (apply_tx)
19948 + tmp |= MACCFG1_TX_EN ;
19949 +
19950 + iowrite32be(tmp, &regs->maccfg1);
19951 +}
19952 +
19953 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
19954 +{
19955 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
19956 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
19957 +}
19958 +
19959 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
19960 + uint64_t addr,
19961 + uint8_t paddr_num)
19962 +{
19963 + uint32_t tmp;
19964 +
19965 + tmp = (uint32_t)(addr);
19966 + /* swap */
19967 + tmp = (((tmp & 0x000000FF) << 24) |
19968 + ((tmp & 0x0000FF00) << 8) |
19969 + ((tmp & 0x00FF0000) >> 8) |
19970 + ((tmp & 0xFF000000) >> 24));
19971 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
19972 +
19973 + tmp = (uint32_t)(addr>>32);
19974 + /* swap */
19975 + tmp = (((tmp & 0x000000FF) << 24) |
19976 + ((tmp & 0x0000FF00) << 8) |
19977 + ((tmp & 0x00FF0000) >> 8) |
19978 + ((tmp & 0xFF000000) >> 24));
19979 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
19980 +}
19981 +
19982 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
19983 +{
19984 + uint32_t tmp;
19985 +
19986 + tmp = ioread32be(&regs->maccfg1);
19987 +
19988 + if (apply_rx)
19989 + tmp &= ~MACCFG1_RX_EN;
19990 +
19991 + if (apply_tx)
19992 + tmp &= ~MACCFG1_TX_EN;
19993 +
19994 + iowrite32be(tmp, &regs->maccfg1);
19995 +}
19996 +
19997 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
19998 +{
19999 + uint32_t ptv = 0;
20000 +
20001 + /* fixme: don't enable tx pause for half-duplex */
20002 +
20003 + if (time) {
20004 + ptv = ioread32be(&regs->ptv);
20005 + ptv &= 0xffff0000;
20006 + ptv |= time & 0x0000ffff;
20007 + iowrite32be(ptv, &regs->ptv);
20008 +
20009 + /* trigger the transmission of a flow-control pause frame */
20010 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
20011 + &regs->maccfg1);
20012 + } else
20013 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
20014 + &regs->maccfg1);
20015 +}
20016 +
20017 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
20018 +{
20019 + uint32_t tmp;
20020 +
20021 + /* todo: check if mac is set to full-duplex */
20022 +
20023 + tmp = ioread32be(&regs->maccfg1);
20024 + if (en)
20025 + tmp |= MACCFG1_RX_FLOW;
20026 + else
20027 + tmp &= ~MACCFG1_RX_FLOW;
20028 + iowrite32be(tmp, &regs->maccfg1);
20029 +}
20030 +
20031 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
20032 +{
20033 + return ioread32be(&regs->rctrl);
20034 +}
20035 +
20036 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
20037 +{
20038 + return ioread32be(&regs->tsec_id);
20039 +}
20040 +
20041 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
20042 +{
20043 + return ioread32be(&regs->ievent) & ev_mask;
20044 +}
20045 +
20046 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
20047 +{
20048 + iowrite32be(ev_mask, &regs->ievent);
20049 +}
20050 +
20051 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
20052 +{
20053 + return ioread32be(&regs->imask);
20054 +}
20055 +
20056 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
20057 +{
20058 + uint32_t event;
20059 +
20060 + event = ioread32be(&regs->tmr_pevent);
20061 + event &= ioread32be(&regs->tmr_pemask);
20062 +
20063 + if (event)
20064 + iowrite32be(event, &regs->tmr_pevent);
20065 + return event;
20066 +}
20067 +
20068 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
20069 +{
20070 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
20071 + &regs->tmr_pemask);
20072 +}
20073 +
20074 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
20075 +{
20076 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
20077 + &regs->tmr_pemask);
20078 +}
20079 +
20080 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
20081 +{
20082 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
20083 +}
20084 +
20085 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
20086 +{
20087 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
20088 +}
20089 +
20090 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
20091 + enum dtsec_stat_counters reg_name)
20092 +{
20093 + uint32_t ret_val;
20094 +
20095 + switch (reg_name) {
20096 + case E_DTSEC_STAT_TR64:
20097 + ret_val = ioread32be(&regs->tr64);
20098 + break;
20099 + case E_DTSEC_STAT_TR127:
20100 + ret_val = ioread32be(&regs->tr127);
20101 + break;
20102 + case E_DTSEC_STAT_TR255:
20103 + ret_val = ioread32be(&regs->tr255);
20104 + break;
20105 + case E_DTSEC_STAT_TR511:
20106 + ret_val = ioread32be(&regs->tr511);
20107 + break;
20108 + case E_DTSEC_STAT_TR1K:
20109 + ret_val = ioread32be(&regs->tr1k);
20110 + break;
20111 + case E_DTSEC_STAT_TRMAX:
20112 + ret_val = ioread32be(&regs->trmax);
20113 + break;
20114 + case E_DTSEC_STAT_TRMGV:
20115 + ret_val = ioread32be(&regs->trmgv);
20116 + break;
20117 + case E_DTSEC_STAT_RBYT:
20118 + ret_val = ioread32be(&regs->rbyt);
20119 + break;
20120 + case E_DTSEC_STAT_RPKT:
20121 + ret_val = ioread32be(&regs->rpkt);
20122 + break;
20123 + case E_DTSEC_STAT_RMCA:
20124 + ret_val = ioread32be(&regs->rmca);
20125 + break;
20126 + case E_DTSEC_STAT_RBCA:
20127 + ret_val = ioread32be(&regs->rbca);
20128 + break;
20129 + case E_DTSEC_STAT_RXPF:
20130 + ret_val = ioread32be(&regs->rxpf);
20131 + break;
20132 + case E_DTSEC_STAT_RALN:
20133 + ret_val = ioread32be(&regs->raln);
20134 + break;
20135 + case E_DTSEC_STAT_RFLR:
20136 + ret_val = ioread32be(&regs->rflr);
20137 + break;
20138 + case E_DTSEC_STAT_RCDE:
20139 + ret_val = ioread32be(&regs->rcde);
20140 + break;
20141 + case E_DTSEC_STAT_RCSE:
20142 + ret_val = ioread32be(&regs->rcse);
20143 + break;
20144 + case E_DTSEC_STAT_RUND:
20145 + ret_val = ioread32be(&regs->rund);
20146 + break;
20147 + case E_DTSEC_STAT_ROVR:
20148 + ret_val = ioread32be(&regs->rovr);
20149 + break;
20150 + case E_DTSEC_STAT_RFRG:
20151 + ret_val = ioread32be(&regs->rfrg);
20152 + break;
20153 + case E_DTSEC_STAT_RJBR:
20154 + ret_val = ioread32be(&regs->rjbr);
20155 + break;
20156 + case E_DTSEC_STAT_RDRP:
20157 + ret_val = ioread32be(&regs->rdrp);
20158 + break;
20159 + case E_DTSEC_STAT_TFCS:
20160 + ret_val = ioread32be(&regs->tfcs);
20161 + break;
20162 + case E_DTSEC_STAT_TBYT:
20163 + ret_val = ioread32be(&regs->tbyt);
20164 + break;
20165 + case E_DTSEC_STAT_TPKT:
20166 + ret_val = ioread32be(&regs->tpkt);
20167 + break;
20168 + case E_DTSEC_STAT_TMCA:
20169 + ret_val = ioread32be(&regs->tmca);
20170 + break;
20171 + case E_DTSEC_STAT_TBCA:
20172 + ret_val = ioread32be(&regs->tbca);
20173 + break;
20174 + case E_DTSEC_STAT_TXPF:
20175 + ret_val = ioread32be(&regs->txpf);
20176 + break;
20177 + case E_DTSEC_STAT_TNCL:
20178 + ret_val = ioread32be(&regs->tncl);
20179 + break;
20180 + case E_DTSEC_STAT_TDRP:
20181 + ret_val = ioread32be(&regs->tdrp);
20182 + break;
20183 + default:
20184 + ret_val = 0;
20185 + }
20186 +
20187 + return ret_val;
20188 +}
20189 --- /dev/null
20190 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
20191 @@ -0,0 +1,165 @@
20192 +/*
20193 + * Copyright 2008-2013 Freescale Semiconductor Inc.
20194 + *
20195 + * Redistribution and use in source and binary forms, with or without
20196 + * modification, are permitted provided that the following conditions are met:
20197 + * * Redistributions of source code must retain the above copyright
20198 + * notice, this list of conditions and the following disclaimer.
20199 + * * Redistributions in binary form must reproduce the above copyright
20200 + * notice, this list of conditions and the following disclaimer in the
20201 + * documentation and/or other materials provided with the distribution.
20202 + * * Neither the name of Freescale Semiconductor nor the
20203 + * names of its contributors may be used to endorse or promote products
20204 + * derived from this software without specific prior written permission.
20205 + *
20206 + *
20207 + * ALTERNATIVELY, this software may be distributed under the terms of the
20208 + * GNU General Public License ("GPL") as published by the Free Software
20209 + * Foundation, either version 2 of that License or (at your option) any
20210 + * later version.
20211 + *
20212 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20213 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20214 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20215 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20216 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20217 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20218 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20219 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20220 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20221 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20222 + */
20223 +
20224 +
20225 +#include "std_ext.h"
20226 +#include "error_ext.h"
20227 +#include "common/general.h"
20228 +#include "fsl_fman_dtsec_mii_acc.h"
20229 +
20230 +
20231 +/**
20232 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
20233 + * @dtsec_freq: dtsec clock frequency (in Mhz)
20234 + *
20235 + * This function calculates the dtsec mii clock divider that determines
20236 + * the MII MDC clock. MII MDC clock will be set to work in the range
20237 + * of 1.5 to 2.5Mhz
20238 + * The output of this function is the value of MIIMCFG[MgmtClk] which
20239 + * implicitly determines the divider value.
20240 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
20241 + *
20242 + * The table below which reflects dtsec_mii_get_div() functionality
20243 + * shows the relations among dtsec_freq, MgmtClk, actual divider
20244 + * and the MII frequency:
20245 + *
20246 + * dtsec freq MgmtClk div MII freq Mhz
20247 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
20248 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
20249 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
20250 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
20251 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
20252 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
20253 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
20254 + * [560..frq] 7 (1/28)(1/8) [frq/224]
20255 + *
20256 + * Returns: the MIIMCFG[MgmtClk] appropriate value
20257 + */
20258 +
20259 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
20260 +{
20261 + uint16_t mgmt_clk;
20262 +
20263 + if (dtsec_freq < 80) mgmt_clk = 1;
20264 + else if (dtsec_freq < 120) mgmt_clk = 2;
20265 + else if (dtsec_freq < 160) mgmt_clk = 3;
20266 + else if (dtsec_freq < 200) mgmt_clk = 4;
20267 + else if (dtsec_freq < 280) mgmt_clk = 5;
20268 + else if (dtsec_freq < 400) mgmt_clk = 6;
20269 + else mgmt_clk = 7;
20270 +
20271 + return (uint8_t)mgmt_clk;
20272 +}
20273 +
20274 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
20275 +{
20276 + /* Reset the management interface */
20277 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
20278 + &regs->miimcfg);
20279 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
20280 + &regs->miimcfg);
20281 +}
20282 +
20283 +
20284 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
20285 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
20286 +{
20287 + uint32_t tmp;
20288 +
20289 + /* Setup the MII Mgmt clock speed */
20290 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
20291 + wmb();
20292 +
20293 + /* Stop the MII management read cycle */
20294 + iowrite32be(0, &regs->miimcom);
20295 + /* Dummy read to make sure MIIMCOM is written */
20296 + tmp = ioread32be(&regs->miimcom);
20297 + wmb();
20298 +
20299 + /* Setting up MII Management Address Register */
20300 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
20301 + iowrite32be(tmp, &regs->miimadd);
20302 + wmb();
20303 +
20304 + /* Setting up MII Management Control Register with data */
20305 + iowrite32be((uint32_t)data, &regs->miimcon);
20306 + /* Dummy read to make sure MIIMCON is written */
20307 + tmp = ioread32be(&regs->miimcon);
20308 + wmb();
20309 +
20310 + /* Wait until MII management write is complete */
20311 + /* todo: a timeout could be useful here */
20312 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
20313 + /* busy wait */;
20314 +
20315 + return 0;
20316 +}
20317 +
20318 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
20319 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
20320 +{
20321 + uint32_t tmp;
20322 +
20323 + /* Setup the MII Mgmt clock speed */
20324 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
20325 + wmb();
20326 +
20327 + /* Setting up the MII Management Address Register */
20328 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
20329 + iowrite32be(tmp, &regs->miimadd);
20330 + wmb();
20331 +
20332 + /* Perform an MII management read cycle */
20333 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
20334 + /* Dummy read to make sure MIIMCOM is written */
20335 + tmp = ioread32be(&regs->miimcom);
20336 + wmb();
20337 +
20338 + /* Wait until MII management read is complete */
20339 + /* todo: a timeout could be useful here */
20340 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
20341 + /* busy wait */;
20342 +
20343 + /* Read MII management status */
20344 + *data = (uint16_t)ioread32be(&regs->miimstat);
20345 + wmb();
20346 +
20347 + iowrite32be(0, &regs->miimcom);
20348 + /* Dummy read to make sure MIIMCOM is written */
20349 + tmp = ioread32be(&regs->miimcom);
20350 +
20351 + if (*data == 0xffff)
20352 + return -ENXIO;
20353 +
20354 + return 0;
20355 +}
20356 +
20357 --- /dev/null
20358 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
20359 @@ -0,0 +1,532 @@
20360 +/*
20361 + * Copyright 2008-2012 Freescale Semiconductor Inc.
20362 + *
20363 + * Redistribution and use in source and binary forms, with or without
20364 + * modification, are permitted provided that the following conditions are met:
20365 + * * Redistributions of source code must retain the above copyright
20366 + * notice, this list of conditions and the following disclaimer.
20367 + * * Redistributions in binary form must reproduce the above copyright
20368 + * notice, this list of conditions and the following disclaimer in the
20369 + * documentation and/or other materials provided with the distribution.
20370 + * * Neither the name of Freescale Semiconductor nor the
20371 + * names of its contributors may be used to endorse or promote products
20372 + * derived from this software without specific prior written permission.
20373 + *
20374 + *
20375 + * ALTERNATIVELY, this software may be distributed under the terms of the
20376 + * GNU General Public License ("GPL") as published by the Free Software
20377 + * Foundation, either version 2 of that License or (at your option) any
20378 + * later version.
20379 + *
20380 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20381 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20382 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20383 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20384 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20385 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20386 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20387 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20388 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20389 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20390 + */
20391 +
20392 +
20393 +#include "fsl_fman_memac.h"
20394 +
20395 +
20396 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
20397 +{
20398 + return ioread32be(&regs->ievent) & ev_mask;
20399 +}
20400 +
20401 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
20402 +{
20403 + return ioread32be(&regs->imask);
20404 +}
20405 +
20406 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
20407 +{
20408 + iowrite32be(ev_mask, &regs->ievent);
20409 +}
20410 +
20411 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
20412 +{
20413 + uint32_t tmp;
20414 +
20415 + tmp = ioread32be(&regs->command_config);
20416 +
20417 + if (val)
20418 + tmp |= CMD_CFG_PROMIS_EN;
20419 + else
20420 + tmp &= ~CMD_CFG_PROMIS_EN;
20421 +
20422 + iowrite32be(tmp, &regs->command_config);
20423 +}
20424 +
20425 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
20426 + uint8_t paddr_num)
20427 +{
20428 + if (paddr_num == 0) {
20429 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
20430 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
20431 + } else {
20432 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
20433 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
20434 + }
20435 +}
20436 +
20437 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
20438 + uint8_t *adr,
20439 + uint8_t paddr_num)
20440 +{
20441 + uint32_t tmp0, tmp1;
20442 +
20443 + tmp0 = (uint32_t)(adr[0] |
20444 + adr[1] << 8 |
20445 + adr[2] << 16 |
20446 + adr[3] << 24);
20447 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
20448 +
20449 + if (paddr_num == 0) {
20450 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
20451 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
20452 + } else {
20453 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
20454 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
20455 + }
20456 +}
20457 +
20458 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
20459 +{
20460 + uint32_t tmp;
20461 +
20462 + tmp = ioread32be(&regs->command_config);
20463 +
20464 + if (apply_rx)
20465 + tmp |= CMD_CFG_RX_EN;
20466 +
20467 + if (apply_tx)
20468 + tmp |= CMD_CFG_TX_EN;
20469 +
20470 + iowrite32be(tmp, &regs->command_config);
20471 +}
20472 +
20473 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
20474 +{
20475 + uint32_t tmp;
20476 +
20477 + tmp = ioread32be(&regs->command_config);
20478 +
20479 + if (apply_rx)
20480 + tmp &= ~CMD_CFG_RX_EN;
20481 +
20482 + if (apply_tx)
20483 + tmp &= ~CMD_CFG_TX_EN;
20484 +
20485 + iowrite32be(tmp, &regs->command_config);
20486 +}
20487 +
20488 +void fman_memac_reset_stat(struct memac_regs *regs)
20489 +{
20490 + uint32_t tmp;
20491 +
20492 + tmp = ioread32be(&regs->statn_config);
20493 +
20494 + tmp |= STATS_CFG_CLR;
20495 +
20496 + iowrite32be(tmp, &regs->statn_config);
20497 +
20498 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
20499 +}
20500 +
20501 +void fman_memac_reset(struct memac_regs *regs)
20502 +{
20503 + uint32_t tmp;
20504 +
20505 + tmp = ioread32be(&regs->command_config);
20506 +
20507 + tmp |= CMD_CFG_SW_RESET;
20508 +
20509 + iowrite32be(tmp, &regs->command_config);
20510 +
20511 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
20512 +}
20513 +
20514 +int fman_memac_init(struct memac_regs *regs,
20515 + struct memac_cfg *cfg,
20516 + enum enet_interface enet_interface,
20517 + enum enet_speed enet_speed,
20518 + bool slow_10g_if,
20519 + uint32_t exceptions)
20520 +{
20521 + uint32_t tmp;
20522 +
20523 + /* Config */
20524 + tmp = 0;
20525 + if (cfg->wan_mode_enable)
20526 + tmp |= CMD_CFG_WAN_MODE;
20527 + if (cfg->promiscuous_mode_enable)
20528 + tmp |= CMD_CFG_PROMIS_EN;
20529 + if (cfg->pause_forward_enable)
20530 + tmp |= CMD_CFG_PAUSE_FWD;
20531 + if (cfg->pause_ignore)
20532 + tmp |= CMD_CFG_PAUSE_IGNORE;
20533 + if (cfg->tx_addr_ins_enable)
20534 + tmp |= CMD_CFG_TX_ADDR_INS;
20535 + if (cfg->loopback_enable)
20536 + tmp |= CMD_CFG_LOOPBACK_EN;
20537 + if (cfg->cmd_frame_enable)
20538 + tmp |= CMD_CFG_CNT_FRM_EN;
20539 + if (cfg->send_idle_enable)
20540 + tmp |= CMD_CFG_SEND_IDLE;
20541 + if (cfg->no_length_check_enable)
20542 + tmp |= CMD_CFG_NO_LEN_CHK;
20543 + if (cfg->rx_sfd_any)
20544 + tmp |= CMD_CFG_SFD_ANY;
20545 + if (cfg->pad_enable)
20546 + tmp |= CMD_CFG_TX_PAD_EN;
20547 + if (cfg->wake_on_lan)
20548 + tmp |= CMD_CFG_MG;
20549 +
20550 + tmp |= CMD_CFG_CRC_FWD;
20551 +
20552 + iowrite32be(tmp, &regs->command_config);
20553 +
20554 + /* Max Frame Length */
20555 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
20556 +
20557 + /* Pause Time */
20558 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
20559 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
20560 +
20561 + /* IF_MODE */
20562 + tmp = 0;
20563 + switch (enet_interface) {
20564 + case E_ENET_IF_XGMII:
20565 + case E_ENET_IF_XFI:
20566 + tmp |= IF_MODE_XGMII;
20567 + break;
20568 + default:
20569 + tmp |= IF_MODE_GMII;
20570 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
20571 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
20572 + }
20573 + iowrite32be(tmp, &regs->if_mode);
20574 +
20575 + /* TX_FIFO_SECTIONS */
20576 + tmp = 0;
20577 + if (enet_interface == E_ENET_IF_XGMII ||
20578 + enet_interface == E_ENET_IF_XFI) {
20579 + if(slow_10g_if) {
20580 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
20581 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
20582 + } else {
20583 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
20584 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
20585 + }
20586 + } else {
20587 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
20588 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
20589 + }
20590 + iowrite32be(tmp, &regs->tx_fifo_sections);
20591 +
20592 + /* clear all pending events and set-up interrupts */
20593 + fman_memac_ack_event(regs, 0xffffffff);
20594 + fman_memac_set_exception(regs, exceptions, TRUE);
20595 +
20596 + return 0;
20597 +}
20598 +
20599 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
20600 +{
20601 + uint32_t tmp;
20602 +
20603 + tmp = ioread32be(&regs->imask);
20604 + if (enable)
20605 + tmp |= val;
20606 + else
20607 + tmp &= ~val;
20608 +
20609 + iowrite32be(tmp, &regs->imask);
20610 +}
20611 +
20612 +void fman_memac_reset_filter_table(struct memac_regs *regs)
20613 +{
20614 + uint32_t i;
20615 + for (i = 0; i < 64; i++)
20616 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
20617 +}
20618 +
20619 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
20620 +{
20621 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
20622 +}
20623 +
20624 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
20625 +{
20626 + iowrite32be(val, &regs->hashtable_ctrl);
20627 +}
20628 +
20629 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
20630 +{
20631 + uint32_t tmp;
20632 +
20633 + tmp = ioread32be(&regs->maxfrm);
20634 +
20635 + return(uint16_t)tmp;
20636 +}
20637 +
20638 +
20639 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
20640 + uint8_t priority,
20641 + uint16_t pause_time,
20642 + uint16_t thresh_time)
20643 +{
20644 + uint32_t tmp;
20645 +
20646 + tmp = ioread32be(&regs->tx_fifo_sections);
20647 +
20648 + if (priority == 0xff) {
20649 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
20650 + iowrite32be(tmp, &regs->tx_fifo_sections);
20651 +
20652 + tmp = ioread32be(&regs->command_config);
20653 + tmp &= ~CMD_CFG_PFC_MODE;
20654 + priority = 0;
20655 + } else {
20656 + GET_TX_EMPTY_PFC_VALUE(tmp);
20657 + iowrite32be(tmp, &regs->tx_fifo_sections);
20658 +
20659 + tmp = ioread32be(&regs->command_config);
20660 + tmp |= CMD_CFG_PFC_MODE;
20661 + }
20662 +
20663 + iowrite32be(tmp, &regs->command_config);
20664 +
20665 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
20666 + if (priority % 2)
20667 + tmp &= 0x0000FFFF;
20668 + else
20669 + tmp &= 0xFFFF0000;
20670 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
20671 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
20672 +
20673 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
20674 + if (priority % 2)
20675 + tmp &= 0x0000FFFF;
20676 + else
20677 + tmp &= 0xFFFF0000;
20678 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
20679 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
20680 +}
20681 +
20682 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
20683 +{
20684 + uint32_t tmp;
20685 +
20686 + tmp = ioread32be(&regs->command_config);
20687 + if (enable)
20688 + tmp |= CMD_CFG_PAUSE_IGNORE;
20689 + else
20690 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
20691 +
20692 + iowrite32be(tmp, &regs->command_config);
20693 +}
20694 +
20695 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
20696 +{
20697 + uint32_t tmp;
20698 +
20699 + tmp = ioread32be(&regs->command_config);
20700 +
20701 + if (enable)
20702 + tmp |= CMD_CFG_MG;
20703 + else
20704 + tmp &= ~CMD_CFG_MG;
20705 +
20706 + iowrite32be(tmp, &regs->command_config);
20707 +}
20708 +
20709 +#define GET_MEMAC_CNTR_64(bn) \
20710 + (ioread32be(&regs->bn ## _l) | \
20711 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
20712 +
20713 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
20714 + enum memac_counters reg_name)
20715 +{
20716 + uint64_t ret_val;
20717 +
20718 + switch (reg_name) {
20719 + case E_MEMAC_COUNTER_R64:
20720 + ret_val = GET_MEMAC_CNTR_64(r64);
20721 + break;
20722 + case E_MEMAC_COUNTER_T64:
20723 + ret_val = GET_MEMAC_CNTR_64(t64);
20724 + break;
20725 + case E_MEMAC_COUNTER_R127:
20726 + ret_val = GET_MEMAC_CNTR_64(r127);
20727 + break;
20728 + case E_MEMAC_COUNTER_T127:
20729 + ret_val = GET_MEMAC_CNTR_64(t127);
20730 + break;
20731 + case E_MEMAC_COUNTER_R255:
20732 + ret_val = GET_MEMAC_CNTR_64(r255);
20733 + break;
20734 + case E_MEMAC_COUNTER_T255:
20735 + ret_val = GET_MEMAC_CNTR_64(t255);
20736 + break;
20737 + case E_MEMAC_COUNTER_R511:
20738 + ret_val = GET_MEMAC_CNTR_64(r511);
20739 + break;
20740 + case E_MEMAC_COUNTER_T511:
20741 + ret_val = GET_MEMAC_CNTR_64(t511);
20742 + break;
20743 + case E_MEMAC_COUNTER_R1023:
20744 + ret_val = GET_MEMAC_CNTR_64(r1023);
20745 + break;
20746 + case E_MEMAC_COUNTER_T1023:
20747 + ret_val = GET_MEMAC_CNTR_64(t1023);
20748 + break;
20749 + case E_MEMAC_COUNTER_R1518:
20750 + ret_val = GET_MEMAC_CNTR_64(r1518);
20751 + break;
20752 + case E_MEMAC_COUNTER_T1518:
20753 + ret_val = GET_MEMAC_CNTR_64(t1518);
20754 + break;
20755 + case E_MEMAC_COUNTER_R1519X:
20756 + ret_val = GET_MEMAC_CNTR_64(r1519x);
20757 + break;
20758 + case E_MEMAC_COUNTER_T1519X:
20759 + ret_val = GET_MEMAC_CNTR_64(t1519x);
20760 + break;
20761 + case E_MEMAC_COUNTER_RFRG:
20762 + ret_val = GET_MEMAC_CNTR_64(rfrg);
20763 + break;
20764 + case E_MEMAC_COUNTER_RJBR:
20765 + ret_val = GET_MEMAC_CNTR_64(rjbr);
20766 + break;
20767 + case E_MEMAC_COUNTER_RDRP:
20768 + ret_val = GET_MEMAC_CNTR_64(rdrp);
20769 + break;
20770 + case E_MEMAC_COUNTER_RALN:
20771 + ret_val = GET_MEMAC_CNTR_64(raln);
20772 + break;
20773 + case E_MEMAC_COUNTER_TUND:
20774 + ret_val = GET_MEMAC_CNTR_64(tund);
20775 + break;
20776 + case E_MEMAC_COUNTER_ROVR:
20777 + ret_val = GET_MEMAC_CNTR_64(rovr);
20778 + break;
20779 + case E_MEMAC_COUNTER_RXPF:
20780 + ret_val = GET_MEMAC_CNTR_64(rxpf);
20781 + break;
20782 + case E_MEMAC_COUNTER_TXPF:
20783 + ret_val = GET_MEMAC_CNTR_64(txpf);
20784 + break;
20785 + case E_MEMAC_COUNTER_ROCT:
20786 + ret_val = GET_MEMAC_CNTR_64(roct);
20787 + break;
20788 + case E_MEMAC_COUNTER_RMCA:
20789 + ret_val = GET_MEMAC_CNTR_64(rmca);
20790 + break;
20791 + case E_MEMAC_COUNTER_RBCA:
20792 + ret_val = GET_MEMAC_CNTR_64(rbca);
20793 + break;
20794 + case E_MEMAC_COUNTER_RPKT:
20795 + ret_val = GET_MEMAC_CNTR_64(rpkt);
20796 + break;
20797 + case E_MEMAC_COUNTER_RUCA:
20798 + ret_val = GET_MEMAC_CNTR_64(ruca);
20799 + break;
20800 + case E_MEMAC_COUNTER_RERR:
20801 + ret_val = GET_MEMAC_CNTR_64(rerr);
20802 + break;
20803 + case E_MEMAC_COUNTER_TOCT:
20804 + ret_val = GET_MEMAC_CNTR_64(toct);
20805 + break;
20806 + case E_MEMAC_COUNTER_TMCA:
20807 + ret_val = GET_MEMAC_CNTR_64(tmca);
20808 + break;
20809 + case E_MEMAC_COUNTER_TBCA:
20810 + ret_val = GET_MEMAC_CNTR_64(tbca);
20811 + break;
20812 + case E_MEMAC_COUNTER_TUCA:
20813 + ret_val = GET_MEMAC_CNTR_64(tuca);
20814 + break;
20815 + case E_MEMAC_COUNTER_TERR:
20816 + ret_val = GET_MEMAC_CNTR_64(terr);
20817 + break;
20818 + default:
20819 + ret_val = 0;
20820 + }
20821 +
20822 + return ret_val;
20823 +}
20824 +
20825 +void fman_memac_adjust_link(struct memac_regs *regs,
20826 + enum enet_interface iface_mode,
20827 + enum enet_speed speed, bool full_dx)
20828 +{
20829 + uint32_t tmp;
20830 +
20831 + tmp = ioread32be(&regs->if_mode);
20832 +
20833 + if (full_dx)
20834 + tmp &= ~IF_MODE_HD;
20835 + else
20836 + tmp |= IF_MODE_HD;
20837 +
20838 + if (iface_mode == E_ENET_IF_RGMII) {
20839 + /* Configure RGMII in manual mode */
20840 + tmp &= ~IF_MODE_RGMII_AUTO;
20841 + tmp &= ~IF_MODE_RGMII_SP_MASK;
20842 +
20843 + if (full_dx)
20844 + tmp |= IF_MODE_RGMII_FD;
20845 + else
20846 + tmp &= ~IF_MODE_RGMII_FD;
20847 +
20848 + switch (speed) {
20849 + case E_ENET_SPEED_1000:
20850 + tmp |= IF_MODE_RGMII_1000;
20851 + break;
20852 + case E_ENET_SPEED_100:
20853 + tmp |= IF_MODE_RGMII_100;
20854 + break;
20855 + case E_ENET_SPEED_10:
20856 + tmp |= IF_MODE_RGMII_10;
20857 + break;
20858 + default:
20859 + break;
20860 + }
20861 + }
20862 +
20863 + iowrite32be(tmp, &regs->if_mode);
20864 +}
20865 +
20866 +void fman_memac_defconfig(struct memac_cfg *cfg)
20867 +{
20868 + cfg->reset_on_init = FALSE;
20869 + cfg->wan_mode_enable = FALSE;
20870 + cfg->promiscuous_mode_enable = FALSE;
20871 + cfg->pause_forward_enable = FALSE;
20872 + cfg->pause_ignore = FALSE;
20873 + cfg->tx_addr_ins_enable = FALSE;
20874 + cfg->loopback_enable = FALSE;
20875 + cfg->cmd_frame_enable = FALSE;
20876 + cfg->rx_error_discard = FALSE;
20877 + cfg->send_idle_enable = FALSE;
20878 + cfg->no_length_check_enable = TRUE;
20879 + cfg->lgth_check_nostdr = FALSE;
20880 + cfg->time_stamp_enable = FALSE;
20881 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
20882 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
20883 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
20884 + cfg->pad_enable = TRUE;
20885 + cfg->phy_tx_ena_on = FALSE;
20886 + cfg->rx_sfd_any = FALSE;
20887 + cfg->rx_pbl_fwd = FALSE;
20888 + cfg->tx_pbl_fwd = FALSE;
20889 + cfg->debug_mode = FALSE;
20890 + cfg->wake_on_lan = FALSE;
20891 +}
20892 --- /dev/null
20893 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
20894 @@ -0,0 +1,215 @@
20895 +/*
20896 + * Copyright 2008-2013 Freescale Semiconductor Inc.
20897 + *
20898 + * Redistribution and use in source and binary forms, with or without
20899 + * modification, are permitted provided that the following conditions are met:
20900 + * * Redistributions of source code must retain the above copyright
20901 + * notice, this list of conditions and the following disclaimer.
20902 + * * Redistributions in binary form must reproduce the above copyright
20903 + * notice, this list of conditions and the following disclaimer in the
20904 + * documentation and/or other materials provided with the distribution.
20905 + * * Neither the name of Freescale Semiconductor nor the
20906 + * names of its contributors may be used to endorse or promote products
20907 + * derived from this software without specific prior written permission.
20908 + *
20909 + *
20910 + * ALTERNATIVELY, this software may be distributed under the terms of the
20911 + * GNU General Public License ("GPL") as published by the Free Software
20912 + * Foundation, either version 2 of that License or (at your option) any
20913 + * later version.
20914 + *
20915 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20916 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20917 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20918 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20919 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20920 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20921 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20922 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20923 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20924 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20925 + */
20926 +
20927 +
20928 +#include "std_ext.h"
20929 +#include "error_ext.h"
20930 +#include "fsl_fman_memac_mii_acc.h"
20931 +
20932 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
20933 + uint8_t phy_addr, uint8_t reg, uint16_t data)
20934 +{
20935 + uint32_t tmp_reg;
20936 +
20937 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
20938 + /* Leave only MDIO_CLK_DIV bits set on */
20939 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
20940 + /* Set maximum MDIO_HOLD value to allow phy to see
20941 + change of data signal */
20942 + tmp_reg |= MDIO_CFG_HOLD_MASK;
20943 + /* Add 10G interface mode */
20944 + tmp_reg |= MDIO_CFG_ENC45;
20945 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
20946 +
20947 + /* Wait for command completion */
20948 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
20949 + udelay(1);
20950 +
20951 + /* Specify phy and register to be accessed */
20952 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
20953 + iowrite32be(reg, &mii_regs->mdio_addr);
20954 + wmb();
20955 +
20956 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
20957 + udelay(1);
20958 +
20959 + /* Write data */
20960 + iowrite32be(data, &mii_regs->mdio_data);
20961 + wmb();
20962 +
20963 + /* Wait for write transaction end */
20964 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
20965 + udelay(1);
20966 +}
20967 +
20968 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
20969 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
20970 +{
20971 + uint32_t tmp_reg;
20972 +
20973 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
20974 + /* Leave only MDIO_CLK_DIV bits set on */
20975 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
20976 + /* Set maximum MDIO_HOLD value to allow phy to see
20977 + change of data signal */
20978 + tmp_reg |= MDIO_CFG_HOLD_MASK;
20979 + /* Add 10G interface mode */
20980 + tmp_reg |= MDIO_CFG_ENC45;
20981 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
20982 +
20983 + /* Wait for command completion */
20984 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
20985 + udelay(1);
20986 +
20987 + /* Specify phy and register to be accessed */
20988 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
20989 + iowrite32be(reg, &mii_regs->mdio_addr);
20990 + wmb();
20991 +
20992 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
20993 + udelay(1);
20994 +
20995 + /* Read cycle */
20996 + tmp_reg = phy_addr;
20997 + tmp_reg |= MDIO_CTL_READ;
20998 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
20999 + wmb();
21000 +
21001 + /* Wait for data to be available */
21002 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21003 + udelay(1);
21004 +
21005 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
21006 +
21007 + /* Check if there was an error */
21008 + return ioread32be(&mii_regs->mdio_cfg);
21009 +}
21010 +
21011 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
21012 + uint8_t phy_addr, uint8_t reg, uint16_t data)
21013 +{
21014 + uint32_t tmp_reg;
21015 +
21016 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
21017 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
21018 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
21019 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
21020 +
21021 + /* Wait for command completion */
21022 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21023 + udelay(1);
21024 +
21025 + /* Write transaction */
21026 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
21027 + tmp_reg |= reg;
21028 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
21029 +
21030 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21031 + udelay(1);
21032 +
21033 + iowrite32be(data, &mii_regs->mdio_data);
21034 +
21035 + wmb();
21036 +
21037 + /* Wait for write transaction to end */
21038 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21039 + udelay(1);
21040 +}
21041 +
21042 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
21043 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
21044 +{
21045 + uint32_t tmp_reg;
21046 +
21047 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
21048 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
21049 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
21050 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
21051 +
21052 + /* Wait for command completion */
21053 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21054 + udelay(1);
21055 +
21056 + /* Read transaction */
21057 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
21058 + tmp_reg |= reg;
21059 + tmp_reg |= MDIO_CTL_READ;
21060 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
21061 +
21062 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21063 + udelay(1);
21064 +
21065 + /* Wait for data to be available */
21066 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21067 + udelay(1);
21068 +
21069 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
21070 +
21071 + /* Check error */
21072 + return ioread32be(&mii_regs->mdio_cfg);
21073 +}
21074 +
21075 +/*****************************************************************************/
21076 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
21077 + uint8_t phy_addr, uint8_t reg, uint16_t data,
21078 + enum enet_speed enet_speed)
21079 +{
21080 + /* Figure out interface type - 10G vs 1G.
21081 + In 10G interface both phy_addr and devAddr present. */
21082 + if (enet_speed == E_ENET_SPEED_10000)
21083 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
21084 + else
21085 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
21086 +
21087 + return 0;
21088 +}
21089 +
21090 +/*****************************************************************************/
21091 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
21092 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
21093 + enum enet_speed enet_speed)
21094 +{
21095 + uint32_t ans;
21096 + /* Figure out interface type - 10G vs 1G.
21097 + In 10G interface both phy_addr and devAddr present. */
21098 + if (enet_speed == E_ENET_SPEED_10000)
21099 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
21100 + else
21101 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
21102 +
21103 + if (ans & MDIO_CFG_READ_ERR)
21104 + return -EINVAL;
21105 + return 0;
21106 +}
21107 +
21108 +/* ......................................................................... */
21109 +
21110 --- /dev/null
21111 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
21112 @@ -0,0 +1,367 @@
21113 +/*
21114 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21115 + *
21116 + * Redistribution and use in source and binary forms, with or without
21117 + * modification, are permitted provided that the following conditions are met:
21118 + * * Redistributions of source code must retain the above copyright
21119 + * notice, this list of conditions and the following disclaimer.
21120 + * * Redistributions in binary form must reproduce the above copyright
21121 + * notice, this list of conditions and the following disclaimer in the
21122 + * documentation and/or other materials provided with the distribution.
21123 + * * Neither the name of Freescale Semiconductor nor the
21124 + * names of its contributors may be used to endorse or promote products
21125 + * derived from this software without specific prior written permission.
21126 + *
21127 + *
21128 + * ALTERNATIVELY, this software may be distributed under the terms of the
21129 + * GNU General Public License ("GPL") as published by the Free Software
21130 + * Foundation, either version 2 of that License or (at your option) any
21131 + * later version.
21132 + *
21133 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21134 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21135 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21136 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21137 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21138 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21139 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21140 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21141 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21142 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21143 + */
21144 +
21145 +
21146 +#include "fsl_fman_tgec.h"
21147 +
21148 +
21149 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
21150 +{
21151 + uint32_t tmp0, tmp1;
21152 +
21153 + tmp0 = (uint32_t)(adr[0] |
21154 + adr[1] << 8 |
21155 + adr[2] << 16 |
21156 + adr[3] << 24);
21157 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
21158 + iowrite32be(tmp0, &regs->mac_addr_0);
21159 + iowrite32be(tmp1, &regs->mac_addr_1);
21160 +}
21161 +
21162 +void fman_tgec_reset_stat(struct tgec_regs *regs)
21163 +{
21164 + uint32_t tmp;
21165 +
21166 + tmp = ioread32be(&regs->command_config);
21167 +
21168 + tmp |= CMD_CFG_STAT_CLR;
21169 +
21170 + iowrite32be(tmp, &regs->command_config);
21171 +
21172 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
21173 +}
21174 +
21175 +#define GET_TGEC_CNTR_64(bn) \
21176 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
21177 + ioread32be(&regs->bn ## _l))
21178 +
21179 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
21180 +{
21181 + uint64_t ret_val;
21182 +
21183 + switch (reg_name) {
21184 + case E_TGEC_COUNTER_R64:
21185 + ret_val = GET_TGEC_CNTR_64(r64);
21186 + break;
21187 + case E_TGEC_COUNTER_R127:
21188 + ret_val = GET_TGEC_CNTR_64(r127);
21189 + break;
21190 + case E_TGEC_COUNTER_R255:
21191 + ret_val = GET_TGEC_CNTR_64(r255);
21192 + break;
21193 + case E_TGEC_COUNTER_R511:
21194 + ret_val = GET_TGEC_CNTR_64(r511);
21195 + break;
21196 + case E_TGEC_COUNTER_R1023:
21197 + ret_val = GET_TGEC_CNTR_64(r1023);
21198 + break;
21199 + case E_TGEC_COUNTER_R1518:
21200 + ret_val = GET_TGEC_CNTR_64(r1518);
21201 + break;
21202 + case E_TGEC_COUNTER_R1519X:
21203 + ret_val = GET_TGEC_CNTR_64(r1519x);
21204 + break;
21205 + case E_TGEC_COUNTER_TRFRG:
21206 + ret_val = GET_TGEC_CNTR_64(trfrg);
21207 + break;
21208 + case E_TGEC_COUNTER_TRJBR:
21209 + ret_val = GET_TGEC_CNTR_64(trjbr);
21210 + break;
21211 + case E_TGEC_COUNTER_RDRP:
21212 + ret_val = GET_TGEC_CNTR_64(rdrp);
21213 + break;
21214 + case E_TGEC_COUNTER_RALN:
21215 + ret_val = GET_TGEC_CNTR_64(raln);
21216 + break;
21217 + case E_TGEC_COUNTER_TRUND:
21218 + ret_val = GET_TGEC_CNTR_64(trund);
21219 + break;
21220 + case E_TGEC_COUNTER_TROVR:
21221 + ret_val = GET_TGEC_CNTR_64(trovr);
21222 + break;
21223 + case E_TGEC_COUNTER_RXPF:
21224 + ret_val = GET_TGEC_CNTR_64(rxpf);
21225 + break;
21226 + case E_TGEC_COUNTER_TXPF:
21227 + ret_val = GET_TGEC_CNTR_64(txpf);
21228 + break;
21229 + case E_TGEC_COUNTER_ROCT:
21230 + ret_val = GET_TGEC_CNTR_64(roct);
21231 + break;
21232 + case E_TGEC_COUNTER_RMCA:
21233 + ret_val = GET_TGEC_CNTR_64(rmca);
21234 + break;
21235 + case E_TGEC_COUNTER_RBCA:
21236 + ret_val = GET_TGEC_CNTR_64(rbca);
21237 + break;
21238 + case E_TGEC_COUNTER_RPKT:
21239 + ret_val = GET_TGEC_CNTR_64(rpkt);
21240 + break;
21241 + case E_TGEC_COUNTER_RUCA:
21242 + ret_val = GET_TGEC_CNTR_64(ruca);
21243 + break;
21244 + case E_TGEC_COUNTER_RERR:
21245 + ret_val = GET_TGEC_CNTR_64(rerr);
21246 + break;
21247 + case E_TGEC_COUNTER_TOCT:
21248 + ret_val = GET_TGEC_CNTR_64(toct);
21249 + break;
21250 + case E_TGEC_COUNTER_TMCA:
21251 + ret_val = GET_TGEC_CNTR_64(tmca);
21252 + break;
21253 + case E_TGEC_COUNTER_TBCA:
21254 + ret_val = GET_TGEC_CNTR_64(tbca);
21255 + break;
21256 + case E_TGEC_COUNTER_TUCA:
21257 + ret_val = GET_TGEC_CNTR_64(tuca);
21258 + break;
21259 + case E_TGEC_COUNTER_TERR:
21260 + ret_val = GET_TGEC_CNTR_64(terr);
21261 + break;
21262 + default:
21263 + ret_val = 0;
21264 + }
21265 +
21266 + return ret_val;
21267 +}
21268 +
21269 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
21270 +{
21271 + uint32_t tmp;
21272 +
21273 + tmp = ioread32be(&regs->command_config);
21274 + if (apply_rx)
21275 + tmp |= CMD_CFG_RX_EN;
21276 + if (apply_tx)
21277 + tmp |= CMD_CFG_TX_EN;
21278 + iowrite32be(tmp, &regs->command_config);
21279 +}
21280 +
21281 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
21282 +{
21283 + uint32_t tmp_reg_32;
21284 +
21285 + tmp_reg_32 = ioread32be(&regs->command_config);
21286 + if (apply_rx)
21287 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
21288 + if (apply_tx)
21289 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
21290 + iowrite32be(tmp_reg_32, &regs->command_config);
21291 +}
21292 +
21293 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
21294 +{
21295 + uint32_t tmp;
21296 +
21297 + tmp = ioread32be(&regs->command_config);
21298 + if (val)
21299 + tmp |= CMD_CFG_PROMIS_EN;
21300 + else
21301 + tmp &= ~CMD_CFG_PROMIS_EN;
21302 + iowrite32be(tmp, &regs->command_config);
21303 +}
21304 +
21305 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
21306 +{
21307 + uint32_t i;
21308 + for (i = 0; i < 512; i++)
21309 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
21310 +}
21311 +
21312 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
21313 +{
21314 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
21315 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
21316 +}
21317 +
21318 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
21319 +{
21320 + iowrite32be(value, &regs->hashtable_ctrl);
21321 +}
21322 +
21323 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
21324 +{
21325 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
21326 +}
21327 +
21328 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
21329 +{
21330 + uint32_t tmp;
21331 +
21332 + tmp = ioread32be(&regs->command_config);
21333 + if (en)
21334 + tmp |= CMD_CFG_PAUSE_IGNORE;
21335 + else
21336 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
21337 + iowrite32be(tmp, &regs->command_config);
21338 +}
21339 +
21340 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
21341 +{
21342 + uint32_t tmp;
21343 +
21344 + tmp = ioread32be(&regs->command_config);
21345 + if (en)
21346 + tmp |= CMD_CFG_EN_TIMESTAMP;
21347 + else
21348 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
21349 + iowrite32be(tmp, &regs->command_config);
21350 +}
21351 +
21352 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
21353 +{
21354 + return ioread32be(&regs->ievent) & ev_mask;
21355 +}
21356 +
21357 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
21358 +{
21359 + iowrite32be(ev_mask, &regs->ievent);
21360 +}
21361 +
21362 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
21363 +{
21364 + return ioread32be(&regs->imask);
21365 +}
21366 +
21367 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
21368 +{
21369 + uint32_t tmp0, tmp1;
21370 +
21371 + tmp0 = (uint32_t)(adr[0] |
21372 + adr[1] << 8 |
21373 + adr[2] << 16 |
21374 + adr[3] << 24);
21375 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
21376 + iowrite32be(tmp0, &regs->mac_addr_2);
21377 + iowrite32be(tmp1, &regs->mac_addr_3);
21378 +}
21379 +
21380 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
21381 +{
21382 + iowrite32be(0, &regs->mac_addr_2);
21383 + iowrite32be(0, &regs->mac_addr_3);
21384 +}
21385 +
21386 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
21387 +{
21388 + return ioread32be(&regs->tgec_id);
21389 +}
21390 +
21391 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
21392 +{
21393 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
21394 +}
21395 +
21396 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
21397 +{
21398 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
21399 +}
21400 +
21401 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
21402 +{
21403 + return (uint16_t) ioread32be(&regs->maxfrm);
21404 +}
21405 +
21406 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
21407 +{
21408 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
21409 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
21410 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
21411 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
21412 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
21413 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
21414 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
21415 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
21416 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
21417 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
21418 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
21419 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
21420 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
21421 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
21422 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
21423 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21424 + cfg->skip_fman11_workaround = FALSE;
21425 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21426 +}
21427 +
21428 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
21429 + uint32_t exception_mask)
21430 +{
21431 + uint32_t tmp;
21432 +
21433 + /* Config */
21434 + tmp = 0x40; /* CRC forward */
21435 + if (cfg->wan_mode_enable)
21436 + tmp |= CMD_CFG_WAN_MODE;
21437 + if (cfg->promiscuous_mode_enable)
21438 + tmp |= CMD_CFG_PROMIS_EN;
21439 + if (cfg->pause_forward_enable)
21440 + tmp |= CMD_CFG_PAUSE_FWD;
21441 + if (cfg->pause_ignore)
21442 + tmp |= CMD_CFG_PAUSE_IGNORE;
21443 + if (cfg->tx_addr_ins_enable)
21444 + tmp |= CMD_CFG_TX_ADDR_INS;
21445 + if (cfg->loopback_enable)
21446 + tmp |= CMD_CFG_LOOPBACK_EN;
21447 + if (cfg->cmd_frame_enable)
21448 + tmp |= CMD_CFG_CMD_FRM_EN;
21449 + if (cfg->rx_error_discard)
21450 + tmp |= CMD_CFG_RX_ER_DISC;
21451 + if (cfg->send_idle_enable)
21452 + tmp |= CMD_CFG_SEND_IDLE;
21453 + if (cfg->no_length_check_enable)
21454 + tmp |= CMD_CFG_NO_LEN_CHK;
21455 + if (cfg->time_stamp_enable)
21456 + tmp |= CMD_CFG_EN_TIMESTAMP;
21457 + iowrite32be(tmp, &regs->command_config);
21458 +
21459 + /* Max Frame Length */
21460 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
21461 + /* Pause Time */
21462 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
21463 +
21464 + /* clear all pending events and set-up interrupts */
21465 + fman_tgec_ack_event(regs, 0xffffffff);
21466 + fman_tgec_enable_interrupt(regs, exception_mask);
21467 +
21468 + return 0;
21469 +}
21470 +
21471 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
21472 +{
21473 + uint32_t tmp;
21474 +
21475 + /* restore the default tx ipg Length */
21476 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
21477 +
21478 + iowrite32be(tmp, &regs->tx_ipg_len);
21479 +}
21480 --- /dev/null
21481 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
21482 @@ -0,0 +1,1153 @@
21483 +/*
21484 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21485 + *
21486 + * Redistribution and use in source and binary forms, with or without
21487 + * modification, are permitted provided that the following conditions are met:
21488 + * * Redistributions of source code must retain the above copyright
21489 + * notice, this list of conditions and the following disclaimer.
21490 + * * Redistributions in binary form must reproduce the above copyright
21491 + * notice, this list of conditions and the following disclaimer in the
21492 + * documentation and/or other materials provided with the distribution.
21493 + * * Neither the name of Freescale Semiconductor nor the
21494 + * names of its contributors may be used to endorse or promote products
21495 + * derived from this software without specific prior written permission.
21496 + *
21497 + *
21498 + * ALTERNATIVELY, this software may be distributed under the terms of the
21499 + * GNU General Public License ("GPL") as published by the Free Software
21500 + * Foundation, either version 2 of that License or (at your option) any
21501 + * later version.
21502 + *
21503 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21504 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21505 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21506 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21507 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21508 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21509 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21510 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21511 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21512 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21513 + */
21514 +
21515 +
21516 +/******************************************************************************
21517 + @File memac.c
21518 +
21519 + @Description FM mEMAC driver
21520 +*//***************************************************************************/
21521 +
21522 +#include "std_ext.h"
21523 +#include "string_ext.h"
21524 +#include "error_ext.h"
21525 +#include "xx_ext.h"
21526 +#include "endian_ext.h"
21527 +#include "debug_ext.h"
21528 +
21529 +#include "fm_common.h"
21530 +#include "memac.h"
21531 +
21532 +
21533 +/*****************************************************************************/
21534 +/* Internal routines */
21535 +/*****************************************************************************/
21536 +
21537 +/* ......................................................................... */
21538 +
21539 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21540 +{
21541 + uint64_t mask1, mask2;
21542 + uint32_t xorVal = 0;
21543 + uint8_t i, j;
21544 +
21545 + for (i=0; i<6; i++)
21546 + {
21547 + mask1 = ethAddr & (uint64_t)0x01;
21548 + ethAddr >>= 1;
21549 +
21550 + for (j=0; j<7; j++)
21551 + {
21552 + mask2 = ethAddr & (uint64_t)0x01;
21553 + mask1 ^= mask2;
21554 + ethAddr >>= 1;
21555 + }
21556 +
21557 + xorVal |= (mask1 << (5-i));
21558 + }
21559 +
21560 + return xorVal;
21561 +}
21562 +
21563 +/* ......................................................................... */
21564 +
21565 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
21566 +{
21567 + uint16_t tmpReg16;
21568 + e_EnetMode enetMode;
21569 +
21570 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
21571 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
21572 + to 1G one, so MII functions can work correctly. */
21573 + enetMode = p_Memac->enetMode;
21574 +
21575 + /* SGMII mode + AN enable */
21576 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
21577 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
21578 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
21579 +
21580 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
21581 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
21582 +
21583 + /* Device ability according to SGMII specification */
21584 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
21585 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
21586 +
21587 + /* Adjust link timer for SGMII -
21588 + According to Cisco SGMII specification the timer should be 1.6 ms.
21589 + The link_timer register is configured in units of the clock.
21590 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
21591 + unit = 1 / (125*10^6 Hz) = 8 ns.
21592 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
21593 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
21594 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
21595 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
21596 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
21597 + we always set up here a value of 2.5 SGMII. */
21598 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
21599 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
21600 +
21601 + /* Restart AN */
21602 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
21603 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
21604 +
21605 + /* Restore original enet mode */
21606 + p_Memac->enetMode = enetMode;
21607 +}
21608 +
21609 +/* ......................................................................... */
21610 +
21611 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
21612 +{
21613 + uint16_t tmpReg16;
21614 + e_EnetMode enetMode;
21615 +
21616 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
21617 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
21618 + to 1G one, so MII functions can work correctly. */
21619 + enetMode = p_Memac->enetMode;
21620 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
21621 +
21622 + /* 1000BaseX mode */
21623 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
21624 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
21625 +
21626 + /* AN Device capability */
21627 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
21628 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
21629 +
21630 + /* Adjust link timer for SGMII -
21631 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
21632 + The link_timer register is configured in units of the clock.
21633 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
21634 + unit = 1 / (125*10^6 Hz) = 8 ns.
21635 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
21636 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
21637 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
21638 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
21639 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
21640 + we always set up here a value of 2.5 SGMII. */
21641 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
21642 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
21643 +
21644 + /* Restart AN */
21645 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
21646 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
21647 +
21648 + /* Restore original enet mode */
21649 + p_Memac->enetMode = enetMode;
21650 +}
21651 +
21652 +/* ......................................................................... */
21653 +
21654 +static t_Error CheckInitParameters(t_Memac *p_Memac)
21655 +{
21656 + e_FmMacType portType;
21657 +
21658 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
21659 +
21660 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21661 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
21662 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
21663 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21664 +
21665 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
21666 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
21667 + if (p_Memac->addr == 0)
21668 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
21669 + if (!p_Memac->f_Exception)
21670 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
21671 + if (!p_Memac->f_Event)
21672 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
21673 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21674 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
21675 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21676 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21677 +
21678 + return E_OK;
21679 +}
21680 +
21681 +/* ........................................................................... */
21682 +
21683 +static void MemacErrException(t_Handle h_Memac)
21684 +{
21685 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21686 + uint32_t event, imask;
21687 +
21688 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
21689 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
21690 +
21691 + /* Imask include both error and notification/event bits.
21692 + Leaving only error bits enabled by imask.
21693 + The imask error bits are shifted by 16 bits offset from
21694 + their corresponding location in the ievent - hence the >> 16 */
21695 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
21696 +
21697 + fman_memac_ack_event(p_Memac->p_MemMap, event);
21698 +
21699 + if (event & MEMAC_IEVNT_TS_ECC_ER)
21700 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
21701 + if (event & MEMAC_IEVNT_TX_ECC_ER)
21702 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21703 + if (event & MEMAC_IEVNT_RX_ECC_ER)
21704 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21705 +}
21706 +
21707 +static void MemacException(t_Handle h_Memac)
21708 +{
21709 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21710 + uint32_t event, imask;
21711 +
21712 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
21713 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
21714 +
21715 + /* Imask include both error and notification/event bits.
21716 + Leaving only error bits enabled by imask.
21717 + The imask error bits are shifted by 16 bits offset from
21718 + their corresponding location in the ievent - hence the >> 16 */
21719 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
21720 +
21721 + fman_memac_ack_event(p_Memac->p_MemMap, event);
21722 +
21723 + if (event & MEMAC_IEVNT_MGI)
21724 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
21725 +}
21726 +
21727 +/* ......................................................................... */
21728 +
21729 +static void FreeInitResources(t_Memac *p_Memac)
21730 +{
21731 + e_FmMacType portType;
21732 +
21733 + portType =
21734 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
21735 +
21736 + if (portType == e_FM_MAC_10G)
21737 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
21738 + else
21739 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
21740 +
21741 + /* release the driver's group hash table */
21742 + FreeHashTable(p_Memac->p_MulticastAddrHash);
21743 + p_Memac->p_MulticastAddrHash = NULL;
21744 +
21745 + /* release the driver's individual hash table */
21746 + FreeHashTable(p_Memac->p_UnicastAddrHash);
21747 + p_Memac->p_UnicastAddrHash = NULL;
21748 +}
21749 +
21750 +
21751 +/*****************************************************************************/
21752 +/* mEMAC API routines */
21753 +/*****************************************************************************/
21754 +
21755 +/* ......................................................................... */
21756 +
21757 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
21758 +{
21759 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21760 +
21761 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21762 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21763 +
21764 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21765 +
21766 + return E_OK;
21767 +}
21768 +
21769 +/* ......................................................................... */
21770 +
21771 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
21772 +{
21773 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21774 +
21775 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21776 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21777 +
21778 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21779 +
21780 + return E_OK;
21781 +}
21782 +
21783 +/* ......................................................................... */
21784 +
21785 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
21786 +{
21787 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21788 +
21789 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21790 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21791 +
21792 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
21793 +
21794 + return E_OK;
21795 +}
21796 +
21797 +/* .............................................................................. */
21798 +
21799 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
21800 +{
21801 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21802 +
21803 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21804 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21805 +
21806 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
21807 + RETURN_ERROR(MAJOR, E_CONFLICT,
21808 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
21809 +
21810 + fman_memac_adjust_link(p_Memac->p_MemMap,
21811 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
21812 + (enum enet_speed)speed,
21813 + fullDuplex);
21814 + return E_OK;
21815 +}
21816 +
21817 +
21818 +/*****************************************************************************/
21819 +/* Memac Configs modification functions */
21820 +/*****************************************************************************/
21821 +
21822 +/* ......................................................................... */
21823 +
21824 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
21825 +{
21826 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21827 +
21828 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21829 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21830 +
21831 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
21832 +
21833 + return E_OK;
21834 +}
21835 +
21836 +/* ......................................................................... */
21837 +
21838 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
21839 +{
21840 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21841 +
21842 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21843 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21844 +
21845 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
21846 +
21847 + return E_OK;
21848 +}
21849 +
21850 +/* ......................................................................... */
21851 +
21852 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
21853 +{
21854 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21855 +
21856 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21857 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21858 +
21859 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
21860 +
21861 + return E_OK;
21862 +}
21863 +
21864 +/* ......................................................................... */
21865 +
21866 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
21867 +{
21868 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21869 +
21870 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21871 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21872 +
21873 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
21874 +
21875 + return E_OK;
21876 +}
21877 +
21878 +/* ......................................................................... */
21879 +
21880 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
21881 +{
21882 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21883 +
21884 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21885 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21886 +
21887 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
21888 +
21889 + return E_OK;
21890 +}
21891 +
21892 +/* ......................................................................... */
21893 +
21894 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
21895 +{
21896 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21897 + uint32_t bitMask = 0;
21898 +
21899 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21900 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21901 +
21902 + GET_EXCEPTION_FLAG(bitMask, exception);
21903 + if (bitMask)
21904 + {
21905 + if (enable)
21906 + p_Memac->exceptions |= bitMask;
21907 + else
21908 + p_Memac->exceptions &= ~bitMask;
21909 + }
21910 + else
21911 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21912 +
21913 + return E_OK;
21914 +}
21915 +
21916 +/* ......................................................................... */
21917 +
21918 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
21919 +{
21920 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21921 +
21922 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21923 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21924 +
21925 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
21926 +
21927 + return E_OK;
21928 +}
21929 +
21930 +
21931 +/*****************************************************************************/
21932 +/* Memac Run Time API functions */
21933 +/*****************************************************************************/
21934 +
21935 +/* ......................................................................... */
21936 +
21937 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
21938 + uint8_t priority,
21939 + uint16_t pauseTime,
21940 + uint16_t threshTime)
21941 +{
21942 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21943 +
21944 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
21945 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21946 +
21947 + if (priority != 0xFF)
21948 + {
21949 + bool PortConfigured, PreFetchEnabled;
21950 +
21951 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
21952 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
21953 +
21954 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
21955 + p_Memac->fmMacControllerDriver.macId,
21956 + &PortConfigured,
21957 + &PreFetchEnabled);
21958 +
21959 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
21960 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
21961 +
21962 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
21963 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
21964 + }
21965 +
21966 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
21967 +
21968 + return E_OK;
21969 +}
21970 +
21971 +/* ......................................................................... */
21972 +
21973 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
21974 + uint16_t pauseTime)
21975 +{
21976 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
21977 +}
21978 +
21979 +/* ......................................................................... */
21980 +
21981 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
21982 +{
21983 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21984 +
21985 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
21986 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21987 +
21988 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
21989 +
21990 + return E_OK;
21991 +}
21992 +
21993 +/* ......................................................................... */
21994 +
21995 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
21996 +{
21997 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21998 +
21999 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
22000 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22001 +
22002 + fman_memac_set_wol(p_Memac->p_MemMap, en);
22003 +
22004 + return E_OK;
22005 +}
22006 +
22007 +/* .............................................................................. */
22008 +
22009 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
22010 +{
22011 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22012 +
22013 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22014 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22015 +UNUSED(p_Memac);
22016 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
22017 +
22018 + return E_OK;
22019 +}
22020 +
22021 +/* Counters handling */
22022 +/* ......................................................................... */
22023 +
22024 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
22025 +{
22026 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22027 +
22028 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22029 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22030 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
22031 +
22032 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
22033 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
22034 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
22035 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
22036 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
22037 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
22038 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
22039 +/* */
22040 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
22041 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
22042 +
22043 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
22044 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
22045 +
22046 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
22047 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
22048 +/* Pause */
22049 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
22050 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
22051 +
22052 +/* MIB II */
22053 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
22054 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
22055 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
22056 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
22057 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
22058 + + p_Statistics->ifInMcastPkts
22059 + + p_Statistics->ifInBcastPkts;
22060 + p_Statistics->ifInDiscards = 0;
22061 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
22062 +
22063 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
22064 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
22065 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
22066 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
22067 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
22068 + + p_Statistics->ifOutMcastPkts
22069 + + p_Statistics->ifOutBcastPkts;
22070 + p_Statistics->ifOutDiscards = 0;
22071 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
22072 +
22073 + return E_OK;
22074 +}
22075 +
22076 +/* ......................................................................... */
22077 +
22078 +static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
22079 +{
22080 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22081 +
22082 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22083 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22084 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
22085 +
22086 + switch (type)
22087 + {
22088 + case e_COMM_MODE_NONE:
22089 + break;
22090 +
22091 + case e_COMM_MODE_RX:
22092 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
22093 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
22094 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
22095 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
22096 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
22097 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
22098 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
22099 + break;
22100 +
22101 + case e_COMM_MODE_TX:
22102 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
22103 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
22104 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
22105 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
22106 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
22107 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
22108 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
22109 + break;
22110 +
22111 + case e_COMM_MODE_RX_AND_TX:
22112 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64)
22113 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
22114 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127)
22115 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
22116 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255)
22117 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
22118 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511)
22119 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
22120 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023)
22121 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
22122 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518)
22123 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
22124 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X)
22125 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
22126 + break;
22127 + }
22128 +
22129 + return E_OK;
22130 +}
22131 +
22132 +/* ......................................................................... */
22133 +
22134 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
22135 +{
22136 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22137 +
22138 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22139 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22140 +
22141 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
22142 +
22143 + return E_OK;
22144 +}
22145 +
22146 +/* ......................................................................... */
22147 +
22148 +static t_Error MemacResetCounters (t_Handle h_Memac)
22149 +{
22150 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22151 +
22152 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22153 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22154 +
22155 + fman_memac_reset_stat(p_Memac->p_MemMap);
22156 +
22157 + return E_OK;
22158 +}
22159 +
22160 +/* ......................................................................... */
22161 +
22162 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22163 +{
22164 + t_Memac *p_Memac = (t_Memac *) h_Memac;
22165 + uint64_t ethAddr;
22166 + uint8_t paddrNum;
22167 +
22168 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22169 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22170 +
22171 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22172 +
22173 + if (ethAddr & GROUP_ADDRESS)
22174 + /* Multicast address has no effect in PADDR */
22175 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
22176 +
22177 + /* Make sure no PADDR contains this address */
22178 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
22179 + if (p_Memac->indAddrRegUsed[paddrNum])
22180 + if (p_Memac->paddr[paddrNum] == ethAddr)
22181 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
22182 +
22183 + /* Find first unused PADDR */
22184 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
22185 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
22186 + {
22187 + /* mark this PADDR as used */
22188 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
22189 + /* store address */
22190 + p_Memac->paddr[paddrNum] = ethAddr;
22191 +
22192 + /* put in hardware */
22193 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
22194 + p_Memac->numOfIndAddrInRegs++;
22195 +
22196 + return E_OK;
22197 + }
22198 +
22199 + /* No free PADDR */
22200 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
22201 +}
22202 +
22203 +/* ......................................................................... */
22204 +
22205 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22206 +{
22207 + t_Memac *p_Memac = (t_Memac *) h_Memac;
22208 + uint64_t ethAddr;
22209 + uint8_t paddrNum;
22210 +
22211 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22212 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22213 +
22214 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22215 +
22216 + /* Find used PADDR containing this address */
22217 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
22218 + {
22219 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
22220 + (p_Memac->paddr[paddrNum] == ethAddr))
22221 + {
22222 + /* mark this PADDR as not used */
22223 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
22224 + /* clear in hardware */
22225 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
22226 + p_Memac->numOfIndAddrInRegs--;
22227 +
22228 + return E_OK;
22229 + }
22230 + }
22231 +
22232 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
22233 +}
22234 +
22235 +/* ......................................................................... */
22236 +
22237 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
22238 +{
22239 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22240 +
22241 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22242 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22243 +
22244 + *macId = p_Memac->macId;
22245 +
22246 + return E_OK;
22247 +}
22248 +
22249 +/* ......................................................................... */
22250 +
22251 +
22252 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22253 +{
22254 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22255 + t_EthHashEntry *p_HashEntry;
22256 + uint32_t hash;
22257 + uint64_t ethAddr;
22258 +
22259 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22260 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22261 +
22262 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22263 +
22264 + if (!(ethAddr & GROUP_ADDRESS))
22265 + /* Unicast addresses not supported in hash */
22266 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22267 +
22268 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
22269 +
22270 + /* Create element to be added to the driver hash table */
22271 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22272 + p_HashEntry->addr = ethAddr;
22273 + INIT_LIST(&p_HashEntry->node);
22274 +
22275 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
22276 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
22277 +
22278 + return E_OK;
22279 +}
22280 +
22281 +/* ......................................................................... */
22282 +
22283 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22284 +{
22285 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22286 + t_EthHashEntry *p_HashEntry = NULL;
22287 + t_List *p_Pos;
22288 + uint32_t hash;
22289 + uint64_t ethAddr;
22290 +
22291 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22292 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22293 +
22294 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22295 +
22296 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
22297 +
22298 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
22299 + {
22300 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22301 + if (p_HashEntry->addr == ethAddr)
22302 + {
22303 + LIST_DelAndInit(&p_HashEntry->node);
22304 + XX_Free(p_HashEntry);
22305 + break;
22306 + }
22307 + }
22308 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
22309 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
22310 +
22311 + return E_OK;
22312 +}
22313 +
22314 +
22315 +/* ......................................................................... */
22316 +
22317 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
22318 +{
22319 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22320 + uint32_t bitMask = 0;
22321 +
22322 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22323 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22324 +
22325 + GET_EXCEPTION_FLAG(bitMask, exception);
22326 + if (bitMask)
22327 + {
22328 + if (enable)
22329 + p_Memac->exceptions |= bitMask;
22330 + else
22331 + p_Memac->exceptions &= ~bitMask;
22332 + }
22333 + else
22334 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22335 +
22336 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
22337 +
22338 + return E_OK;
22339 +}
22340 +
22341 +/* ......................................................................... */
22342 +
22343 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
22344 +{
22345 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22346 +
22347 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
22348 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
22349 +
22350 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
22351 +}
22352 +
22353 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
22354 +{
22355 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22356 + uint8_t i, phyAddr;
22357 +
22358 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
22359 + {
22360 + /* Configure internal SGMII PHY */
22361 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
22362 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
22363 + else
22364 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
22365 + }
22366 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
22367 + {
22368 + /* Configure 4 internal SGMII PHYs */
22369 + for (i = 0; i < 4; i++)
22370 + {
22371 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
22372 + phyAddress; the lower 2 bits are used to extend
22373 + register address space and access each one of 4
22374 + ports inside QSGMII. */
22375 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
22376 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
22377 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
22378 + else
22379 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
22380 + }
22381 + }
22382 + return E_OK;
22383 +}
22384 +
22385 +/*****************************************************************************/
22386 +/* mEMAC Init & Free API */
22387 +/*****************************************************************************/
22388 +
22389 +/* ......................................................................... */
22390 +void *g_MemacRegs;
22391 +static t_Error MemacInit(t_Handle h_Memac)
22392 +{
22393 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22394 + struct memac_cfg *p_MemacDriverParam;
22395 + enum enet_interface enet_interface;
22396 + enum enet_speed enet_speed;
22397 + t_EnetAddr ethAddr;
22398 + e_FmMacType portType;
22399 + t_Error err;
22400 + bool slow_10g_if = FALSE;
22401 + if (p_Memac->macId == 3) /* This is a quick WA */
22402 + g_MemacRegs = p_Memac->p_MemMap;
22403 +
22404 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22405 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22406 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22407 +
22408 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
22409 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
22410 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
22411 + slow_10g_if = TRUE;
22412 +
22413 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
22414 +
22415 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
22416 +
22417 + portType =
22418 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
22419 +
22420 + /* First, reset the MAC if desired. */
22421 + if (p_MemacDriverParam->reset_on_init)
22422 + fman_memac_reset(p_Memac->p_MemMap);
22423 +
22424 + /* MAC Address */
22425 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
22426 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
22427 +
22428 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
22429 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
22430 +
22431 + fman_memac_init(p_Memac->p_MemMap,
22432 + p_Memac->p_MemacDriverParam,
22433 + enet_interface,
22434 + enet_speed,
22435 + slow_10g_if,
22436 + p_Memac->exceptions);
22437 +
22438 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
22439 + {
22440 + uint32_t tmpReg = 0;
22441 +
22442 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
22443 + /* check the FMAN version - the bug exists only in rev1 */
22444 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
22445 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
22446 + {
22447 + /* MAC strips CRC from received frames - this workaround should
22448 + decrease the likelihood of bug appearance
22449 + */
22450 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
22451 + tmpReg &= ~CMD_CFG_CRC_FWD;
22452 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
22453 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
22454 + }
22455 + }
22456 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
22457 +
22458 + MemacInitInternalPhy(h_Memac);
22459 +
22460 + /* Max Frame Length */
22461 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
22462 + portType,
22463 + p_Memac->fmMacControllerDriver.macId,
22464 + p_MemacDriverParam->max_frame_length);
22465 + if (err)
22466 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
22467 +
22468 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22469 + if (!p_Memac->p_MulticastAddrHash)
22470 + {
22471 + FreeInitResources(p_Memac);
22472 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22473 + }
22474 +
22475 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22476 + if (!p_Memac->p_UnicastAddrHash)
22477 + {
22478 + FreeInitResources(p_Memac);
22479 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22480 + }
22481 +
22482 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
22483 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
22484 + p_Memac->macId,
22485 + e_FM_INTR_TYPE_ERR,
22486 + MemacErrException,
22487 + p_Memac);
22488 +
22489 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
22490 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
22491 + p_Memac->macId,
22492 + e_FM_INTR_TYPE_NORMAL,
22493 + MemacException,
22494 + p_Memac);
22495 +
22496 + XX_Free(p_MemacDriverParam);
22497 + p_Memac->p_MemacDriverParam = NULL;
22498 +
22499 + return E_OK;
22500 +}
22501 +
22502 +/* ......................................................................... */
22503 +
22504 +static t_Error MemacFree(t_Handle h_Memac)
22505 +{
22506 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22507 +
22508 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22509 +
22510 + if (p_Memac->p_MemacDriverParam)
22511 + {
22512 + /* Called after config */
22513 + XX_Free(p_Memac->p_MemacDriverParam);
22514 + p_Memac->p_MemacDriverParam = NULL;
22515 + }
22516 + else
22517 + /* Called after init */
22518 + FreeInitResources(p_Memac);
22519 +
22520 + XX_Free(p_Memac);
22521 +
22522 + return E_OK;
22523 +}
22524 +
22525 +/* ......................................................................... */
22526 +
22527 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22528 +{
22529 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
22530 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
22531 +
22532 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22533 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
22534 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
22535 +
22536 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
22537 +
22538 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
22539 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
22540 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
22541 +
22542 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
22543 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
22544 +
22545 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
22546 +
22547 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
22548 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
22549 +
22550 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
22551 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
22552 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22553 +
22554 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
22555 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
22556 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
22557 +
22558 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
22559 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
22560 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
22561 +
22562 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
22563 +
22564 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
22565 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
22566 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters;
22567 +
22568 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
22569 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
22570 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
22571 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
22572 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
22573 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
22574 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
22575 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
22576 +
22577 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
22578 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
22579 +}
22580 +
22581 +
22582 +/*****************************************************************************/
22583 +/* mEMAC Config Main Entry */
22584 +/*****************************************************************************/
22585 +
22586 +/* ......................................................................... */
22587 +
22588 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
22589 +{
22590 + t_Memac *p_Memac;
22591 + struct memac_cfg *p_MemacDriverParam;
22592 + uintptr_t baseAddr;
22593 +
22594 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22595 +
22596 + baseAddr = p_FmMacParam->baseAddr;
22597 + /* Allocate memory for the mEMAC data structure */
22598 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
22599 + if (!p_Memac)
22600 + {
22601 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
22602 + return NULL;
22603 + }
22604 + memset(p_Memac, 0, sizeof(t_Memac));
22605 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
22606 +
22607 + /* Allocate memory for the mEMAC driver parameters data structure */
22608 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
22609 + if (!p_MemacDriverParam)
22610 + {
22611 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
22612 + XX_Free(p_Memac);
22613 + return NULL;
22614 + }
22615 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
22616 +
22617 + /* Plant parameter structure pointer */
22618 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
22619 +
22620 + fman_memac_defconfig(p_MemacDriverParam);
22621 +
22622 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22623 +
22624 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
22625 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
22626 +
22627 + p_Memac->enetMode = p_FmMacParam->enetMode;
22628 + p_Memac->macId = p_FmMacParam->macId;
22629 + p_Memac->exceptions = MEMAC_default_exceptions;
22630 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
22631 + p_Memac->f_Event = p_FmMacParam->f_Event;
22632 + p_Memac->h_App = p_FmMacParam->h_App;
22633 +
22634 + return p_Memac;
22635 +}
22636 --- /dev/null
22637 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
22638 @@ -0,0 +1,110 @@
22639 +/*
22640 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22641 + *
22642 + * Redistribution and use in source and binary forms, with or without
22643 + * modification, are permitted provided that the following conditions are met:
22644 + * * Redistributions of source code must retain the above copyright
22645 + * notice, this list of conditions and the following disclaimer.
22646 + * * Redistributions in binary form must reproduce the above copyright
22647 + * notice, this list of conditions and the following disclaimer in the
22648 + * documentation and/or other materials provided with the distribution.
22649 + * * Neither the name of Freescale Semiconductor nor the
22650 + * names of its contributors may be used to endorse or promote products
22651 + * derived from this software without specific prior written permission.
22652 + *
22653 + *
22654 + * ALTERNATIVELY, this software may be distributed under the terms of the
22655 + * GNU General Public License ("GPL") as published by the Free Software
22656 + * Foundation, either version 2 of that License or (at your option) any
22657 + * later version.
22658 + *
22659 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22660 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22661 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22662 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22663 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22664 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22665 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22666 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22667 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22668 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22669 + */
22670 +
22671 +
22672 +/******************************************************************************
22673 + @File memac.h
22674 +
22675 + @Description FM Multirate Ethernet MAC (mEMAC)
22676 +*//***************************************************************************/
22677 +#ifndef __MEMAC_H
22678 +#define __MEMAC_H
22679 +
22680 +#include "std_ext.h"
22681 +#include "error_ext.h"
22682 +#include "list_ext.h"
22683 +
22684 +#include "fsl_fman_memac_mii_acc.h"
22685 +#include "fm_mac.h"
22686 +#include "fsl_fman_memac.h"
22687 +
22688 +
22689 +#define MEMAC_default_exceptions \
22690 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
22691 +
22692 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22693 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22694 + bitMask = MEMAC_IMASK_TECC_ER; break; \
22695 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22696 + bitMask = MEMAC_IMASK_RECC_ER; break; \
22697 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
22698 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
22699 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
22700 + bitMask = MEMAC_IMASK_MGI; break; \
22701 + default: bitMask = 0;break;}
22702 +
22703 +
22704 +typedef struct
22705 +{
22706 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22707 + t_Handle h_App; /**< Handle to the upper layer application */
22708 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
22709 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
22710 + uint64_t addr; /**< MAC address of device */
22711 + e_EnetMode enetMode; /**< Ethernet physical interface */
22712 + t_FmMacExceptionCallback *f_Exception;
22713 + int mdioIrq;
22714 + t_FmMacExceptionCallback *f_Event;
22715 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22716 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22717 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22718 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
22719 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
22720 + bool debugMode;
22721 + uint8_t macId;
22722 + uint32_t exceptions;
22723 + struct memac_cfg *p_MemacDriverParam;
22724 +} t_Memac;
22725 +
22726 +
22727 +/* Internal PHY access */
22728 +#define PHY_MDIO_ADDR 0
22729 +
22730 +/* Internal PHY Registers - SGMII */
22731 +#define PHY_SGMII_CR_PHY_RESET 0x8000
22732 +#define PHY_SGMII_CR_RESET_AN 0x0200
22733 +#define PHY_SGMII_CR_DEF_VAL 0x1140
22734 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
22735 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
22736 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
22737 +#define PHY_SGMII_IF_MODE_AN 0x0002
22738 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
22739 +#define PHY_SGMII_IF_MODE_1000X 0x0000
22740 +
22741 +
22742 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
22743 +
22744 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
22745 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22746 +
22747 +
22748 +#endif /* __MEMAC_H */
22749 --- /dev/null
22750 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
22751 @@ -0,0 +1,78 @@
22752 +/*
22753 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22754 + *
22755 + * Redistribution and use in source and binary forms, with or without
22756 + * modification, are permitted provided that the following conditions are met:
22757 + * * Redistributions of source code must retain the above copyright
22758 + * notice, this list of conditions and the following disclaimer.
22759 + * * Redistributions in binary form must reproduce the above copyright
22760 + * notice, this list of conditions and the following disclaimer in the
22761 + * documentation and/or other materials provided with the distribution.
22762 + * * Neither the name of Freescale Semiconductor nor the
22763 + * names of its contributors may be used to endorse or promote products
22764 + * derived from this software without specific prior written permission.
22765 + *
22766 + *
22767 + * ALTERNATIVELY, this software may be distributed under the terms of the
22768 + * GNU General Public License ("GPL") as published by the Free Software
22769 + * Foundation, either version 2 of that License or (at your option) any
22770 + * later version.
22771 + *
22772 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22773 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22774 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22775 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22776 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22777 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22778 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22779 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22780 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22781 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22782 + */
22783 +
22784 +
22785 +#include "error_ext.h"
22786 +#include "std_ext.h"
22787 +#include "fm_mac.h"
22788 +#include "memac.h"
22789 +#include "xx_ext.h"
22790 +
22791 +#include "fm_common.h"
22792 +#include "memac_mii_acc.h"
22793 +
22794 +
22795 +/*****************************************************************************/
22796 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
22797 + uint8_t phyAddr,
22798 + uint8_t reg,
22799 + uint16_t data)
22800 +{
22801 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22802 +
22803 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22804 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
22805 +
22806 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
22807 + phyAddr,
22808 + reg,
22809 + data,
22810 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
22811 +}
22812 +
22813 +/*****************************************************************************/
22814 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
22815 + uint8_t phyAddr,
22816 + uint8_t reg,
22817 + uint16_t *p_Data)
22818 +{
22819 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22820 +
22821 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22822 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
22823 +
22824 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
22825 + phyAddr,
22826 + reg,
22827 + p_Data,
22828 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
22829 +}
22830 --- /dev/null
22831 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
22832 @@ -0,0 +1,73 @@
22833 +/*
22834 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22835 + *
22836 + * Redistribution and use in source and binary forms, with or without
22837 + * modification, are permitted provided that the following conditions are met:
22838 + * * Redistributions of source code must retain the above copyright
22839 + * notice, this list of conditions and the following disclaimer.
22840 + * * Redistributions in binary form must reproduce the above copyright
22841 + * notice, this list of conditions and the following disclaimer in the
22842 + * documentation and/or other materials provided with the distribution.
22843 + * * Neither the name of Freescale Semiconductor nor the
22844 + * names of its contributors may be used to endorse or promote products
22845 + * derived from this software without specific prior written permission.
22846 + *
22847 + *
22848 + * ALTERNATIVELY, this software may be distributed under the terms of the
22849 + * GNU General Public License ("GPL") as published by the Free Software
22850 + * Foundation, either version 2 of that License or (at your option) any
22851 + * later version.
22852 + *
22853 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22854 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22855 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22856 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22857 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22858 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22859 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22860 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22861 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22862 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22863 + */
22864 +
22865 +
22866 +#ifndef __MEMAC_MII_ACC_H
22867 +#define __MEMAC_MII_ACC_H
22868 +
22869 +#include "std_ext.h"
22870 +
22871 +
22872 +/* MII Management Registers */
22873 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
22874 +#define MDIO_CFG_CLK_DIV_SHIFT 7
22875 +#define MDIO_CFG_HOLD_MASK 0x0000001c
22876 +#define MDIO_CFG_ENC45 0x00000040
22877 +#define MDIO_CFG_READ_ERR 0x00000002
22878 +#define MDIO_CFG_BSY 0x00000001
22879 +
22880 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
22881 +#define MDIO_CTL_READ 0x00008000
22882 +
22883 +#define MDIO_DATA_BSY 0x80000000
22884 +
22885 +#if defined(__MWERKS__) && !defined(__GNUC__)
22886 +#pragma pack(push,1)
22887 +#endif /* defined(__MWERKS__) && ... */
22888 +
22889 +/*----------------------------------------------------*/
22890 +/* MII Configuration Control Memory Map Registers */
22891 +/*----------------------------------------------------*/
22892 +typedef struct t_MemacMiiAccessMemMap
22893 +{
22894 + volatile uint32_t mdio_cfg; /* 0x030 */
22895 + volatile uint32_t mdio_ctrl; /* 0x034 */
22896 + volatile uint32_t mdio_data; /* 0x038 */
22897 + volatile uint32_t mdio_addr; /* 0x03c */
22898 +} t_MemacMiiAccessMemMap ;
22899 +
22900 +#if defined(__MWERKS__) && !defined(__GNUC__)
22901 +#pragma pack(pop)
22902 +#endif /* defined(__MWERKS__) && ... */
22903 +
22904 +
22905 +#endif /* __MEMAC_MII_ACC_H */
22906 --- /dev/null
22907 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
22908 @@ -0,0 +1,1017 @@
22909 +/*
22910 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22911 + *
22912 + * Redistribution and use in source and binary forms, with or without
22913 + * modification, are permitted provided that the following conditions are met:
22914 + * * Redistributions of source code must retain the above copyright
22915 + * notice, this list of conditions and the following disclaimer.
22916 + * * Redistributions in binary form must reproduce the above copyright
22917 + * notice, this list of conditions and the following disclaimer in the
22918 + * documentation and/or other materials provided with the distribution.
22919 + * * Neither the name of Freescale Semiconductor nor the
22920 + * names of its contributors may be used to endorse or promote products
22921 + * derived from this software without specific prior written permission.
22922 + *
22923 + *
22924 + * ALTERNATIVELY, this software may be distributed under the terms of the
22925 + * GNU General Public License ("GPL") as published by the Free Software
22926 + * Foundation, either version 2 of that License or (at your option) any
22927 + * later version.
22928 + *
22929 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22930 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22931 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22932 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22933 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22934 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22935 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22936 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22937 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22938 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22939 + */
22940 +
22941 +
22942 +/******************************************************************************
22943 + @File tgec.c
22944 +
22945 + @Description FM 10G MAC ...
22946 +*//***************************************************************************/
22947 +
22948 +#include "std_ext.h"
22949 +#include "string_ext.h"
22950 +#include "error_ext.h"
22951 +#include "xx_ext.h"
22952 +#include "endian_ext.h"
22953 +#include "debug_ext.h"
22954 +#include "crc_mac_addr_ext.h"
22955 +
22956 +#include "fm_common.h"
22957 +#include "fsl_fman_tgec.h"
22958 +#include "tgec.h"
22959 +
22960 +
22961 +/*****************************************************************************/
22962 +/* Internal routines */
22963 +/*****************************************************************************/
22964 +
22965 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
22966 +{
22967 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
22968 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
22969 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
22970 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
22971 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
22972 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
22973 +
22974 + if (p_Tgec->addr == 0)
22975 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
22976 + if (!p_Tgec->f_Exception)
22977 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
22978 + if (!p_Tgec->f_Event)
22979 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
22980 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
22981 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
22982 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
22983 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
22984 + return E_OK;
22985 +}
22986 +
22987 +/* ......................................................................... */
22988 +
22989 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
22990 +{
22991 + uint32_t crc;
22992 +
22993 + /* CRC calculation */
22994 + GET_MAC_ADDR_CRC(ethAddr, crc);
22995 +
22996 + crc = GetMirror32(crc);
22997 +
22998 + return crc;
22999 +}
23000 +
23001 +/* ......................................................................... */
23002 +
23003 +static void TgecErrException(t_Handle h_Tgec)
23004 +{
23005 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23006 + uint32_t event;
23007 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
23008 +
23009 + /* do not handle MDIO events */
23010 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
23011 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
23012 +
23013 + fman_tgec_ack_event(p_TgecMemMap, event);
23014 +
23015 + if (event & TGEC_IMASK_REM_FAULT)
23016 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
23017 + if (event & TGEC_IMASK_LOC_FAULT)
23018 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
23019 + if (event & TGEC_IMASK_TX_ECC_ER)
23020 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
23021 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
23022 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
23023 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
23024 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
23025 + if (event & TGEC_IMASK_TX_ER)
23026 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
23027 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
23028 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
23029 + if (event & TGEC_IMASK_RX_ECC_ER)
23030 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
23031 + if (event & TGEC_IMASK_RX_JAB_FRM)
23032 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
23033 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
23034 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
23035 + if (event & TGEC_IMASK_RX_RUNT_FRM)
23036 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
23037 + if (event & TGEC_IMASK_RX_FRAG_FRM)
23038 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
23039 + if (event & TGEC_IMASK_RX_LEN_ER)
23040 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
23041 + if (event & TGEC_IMASK_RX_CRC_ER)
23042 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
23043 + if (event & TGEC_IMASK_RX_ALIGN_ER)
23044 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
23045 +}
23046 +
23047 +/* ......................................................................... */
23048 +
23049 +static void TgecException(t_Handle h_Tgec)
23050 +{
23051 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23052 + uint32_t event;
23053 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
23054 +
23055 + /* handle only MDIO events */
23056 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
23057 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
23058 +
23059 + fman_tgec_ack_event(p_TgecMemMap, event);
23060 +
23061 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
23062 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
23063 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
23064 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
23065 +}
23066 +
23067 +/* ......................................................................... */
23068 +
23069 +static void FreeInitResources(t_Tgec *p_Tgec)
23070 +{
23071 + if (p_Tgec->mdioIrq != NO_IRQ)
23072 + {
23073 + XX_DisableIntr(p_Tgec->mdioIrq);
23074 + XX_FreeIntr(p_Tgec->mdioIrq);
23075 + }
23076 +
23077 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
23078 +
23079 + /* release the driver's group hash table */
23080 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
23081 + p_Tgec->p_MulticastAddrHash = NULL;
23082 +
23083 + /* release the driver's individual hash table */
23084 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
23085 + p_Tgec->p_UnicastAddrHash = NULL;
23086 +}
23087 +
23088 +
23089 +/*****************************************************************************/
23090 +/* 10G MAC API routines */
23091 +/*****************************************************************************/
23092 +
23093 +/* ......................................................................... */
23094 +
23095 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
23096 +{
23097 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23098 +
23099 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23100 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23101 +
23102 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
23103 +
23104 + return E_OK;
23105 +}
23106 +
23107 +/* ......................................................................... */
23108 +
23109 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
23110 +{
23111 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23112 +
23113 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23114 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23115 +
23116 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
23117 +
23118 + return E_OK;
23119 +}
23120 +
23121 +/* ......................................................................... */
23122 +
23123 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
23124 +{
23125 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23126 +
23127 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23128 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23129 +
23130 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
23131 +
23132 + return E_OK;
23133 +}
23134 +
23135 +
23136 +/*****************************************************************************/
23137 +/* Tgec Configs modification functions */
23138 +/*****************************************************************************/
23139 +
23140 +/* ......................................................................... */
23141 +
23142 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
23143 +{
23144 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23145 +
23146 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23147 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23148 +
23149 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
23150 +
23151 + return E_OK;
23152 +}
23153 +
23154 +/* ......................................................................... */
23155 +
23156 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
23157 +{
23158 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23159 +
23160 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23161 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23162 +
23163 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
23164 +
23165 + return E_OK;
23166 +}
23167 +
23168 +/* ......................................................................... */
23169 +
23170 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
23171 +{
23172 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23173 +
23174 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23175 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23176 +
23177 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
23178 +
23179 + return E_OK;
23180 +}
23181 +
23182 +/* ......................................................................... */
23183 +
23184 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
23185 +{
23186 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23187 +
23188 + UNUSED(newVal);
23189 +
23190 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23191 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23192 +
23193 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
23194 +
23195 + return E_OK;
23196 +}
23197 +
23198 +/* ......................................................................... */
23199 +
23200 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
23201 +{
23202 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23203 + uint32_t bitMask = 0;
23204 +
23205 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23206 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23207 +
23208 + GET_EXCEPTION_FLAG(bitMask, exception);
23209 + if (bitMask)
23210 + {
23211 + if (enable)
23212 + p_Tgec->exceptions |= bitMask;
23213 + else
23214 + p_Tgec->exceptions &= ~bitMask;
23215 + }
23216 + else
23217 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23218 +
23219 + return E_OK;
23220 +}
23221 +
23222 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
23223 +/* ......................................................................... */
23224 +
23225 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
23226 +{
23227 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23228 +
23229 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23230 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23231 +
23232 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
23233 +
23234 + return E_OK;
23235 +}
23236 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
23237 +
23238 +
23239 +/*****************************************************************************/
23240 +/* Tgec Run Time API functions */
23241 +/*****************************************************************************/
23242 +
23243 +/* ......................................................................... */
23244 +/* backward compatibility. will be removed in the future. */
23245 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
23246 +{
23247 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23248 +
23249 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
23250 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23251 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
23252 +
23253 +
23254 + return E_OK;
23255 +}
23256 +
23257 +/* ......................................................................... */
23258 +
23259 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
23260 + uint8_t priority,
23261 + uint16_t pauseTime,
23262 + uint16_t threshTime)
23263 +{
23264 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23265 +
23266 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
23267 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23268 +
23269 + UNUSED(priority); UNUSED(threshTime);
23270 +
23271 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
23272 +
23273 + return E_OK;
23274 +}
23275 +
23276 +/* ......................................................................... */
23277 +
23278 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
23279 +{
23280 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23281 +
23282 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
23283 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23284 +
23285 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
23286 +
23287 + return E_OK;
23288 +}
23289 +
23290 +/* ......................................................................... */
23291 +
23292 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
23293 +{
23294 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23295 + struct tgec_regs *p_TgecMemMap;
23296 +
23297 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23298 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23299 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
23300 +
23301 + p_TgecMemMap = p_Tgec->p_MemMap;
23302 +
23303 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
23304 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
23305 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
23306 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
23307 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
23308 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
23309 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
23310 +/* */
23311 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
23312 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
23313 +
23314 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
23315 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
23316 +
23317 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
23318 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
23319 +/* Pause */
23320 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
23321 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
23322 +
23323 +/* MIB II */
23324 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
23325 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
23326 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
23327 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
23328 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
23329 + + p_Statistics->ifInMcastPkts
23330 + + p_Statistics->ifInBcastPkts;
23331 + p_Statistics->ifInDiscards = 0;
23332 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
23333 +
23334 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
23335 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
23336 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
23337 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
23338 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
23339 + + p_Statistics->ifOutMcastPkts
23340 + + p_Statistics->ifOutBcastPkts;
23341 + p_Statistics->ifOutDiscards = 0;
23342 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
23343 +
23344 + return E_OK;
23345 +}
23346 +
23347 +/* ......................................................................... */
23348 +
23349 +static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
23350 +{
23351 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23352 + struct tgec_regs *p_TgecMemMap;
23353 +
23354 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23355 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23356 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
23357 +
23358 + p_TgecMemMap = p_Tgec->p_MemMap;
23359 +
23360 + switch (type)
23361 + {
23362 + case e_COMM_MODE_NONE:
23363 + break;
23364 +
23365 + case e_COMM_MODE_RX:
23366 + p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
23367 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
23368 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
23369 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
23370 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
23371 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
23372 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
23373 + break;
23374 +
23375 + case e_COMM_MODE_TX:
23376 + //Tx counters not supported
23377 + break;
23378 +
23379 + case e_COMM_MODE_RX_AND_TX:
23380 + //Tx counters not supported
23381 + break;
23382 + }
23383 +
23384 + return E_OK;
23385 +}
23386 +
23387 +
23388 +/* ......................................................................... */
23389 +
23390 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
23391 +{
23392 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23393 +
23394 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23395 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23396 +
23397 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
23398 +
23399 + return E_OK;
23400 +}
23401 +
23402 +/* ......................................................................... */
23403 +
23404 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
23405 +{
23406 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23407 +
23408 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23409 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23410 +
23411 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
23412 +
23413 + return E_OK;
23414 +}
23415 +
23416 +/* ......................................................................... */
23417 +
23418 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
23419 +{
23420 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23421 +
23422 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23423 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23424 +
23425 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
23426 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
23427 +
23428 + return E_OK;
23429 +}
23430 +
23431 +/* ......................................................................... */
23432 +
23433 +static t_Error TgecResetCounters (t_Handle h_Tgec)
23434 +{
23435 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23436 +
23437 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23438 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23439 +
23440 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
23441 +
23442 + return E_OK;
23443 +}
23444 +
23445 +/* ......................................................................... */
23446 +
23447 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23448 +{
23449 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
23450 + uint64_t ethAddr;
23451 + uint8_t paddrNum;
23452 +
23453 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23454 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23455 +
23456 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
23457 +
23458 + if (ethAddr & GROUP_ADDRESS)
23459 + /* Multicast address has no effect in PADDR */
23460 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
23461 +
23462 + /* Make sure no PADDR contains this address */
23463 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
23464 + if (p_Tgec->indAddrRegUsed[paddrNum])
23465 + if (p_Tgec->paddr[paddrNum] == ethAddr)
23466 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
23467 +
23468 + /* Find first unused PADDR */
23469 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
23470 + {
23471 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
23472 + {
23473 + /* mark this PADDR as used */
23474 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
23475 + /* store address */
23476 + p_Tgec->paddr[paddrNum] = ethAddr;
23477 +
23478 + /* put in hardware */
23479 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
23480 + p_Tgec->numOfIndAddrInRegs++;
23481 +
23482 + return E_OK;
23483 + }
23484 + }
23485 +
23486 + /* No free PADDR */
23487 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
23488 +}
23489 +
23490 +/* ......................................................................... */
23491 +
23492 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23493 +{
23494 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
23495 + uint64_t ethAddr;
23496 + uint8_t paddrNum;
23497 +
23498 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23499 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23500 +
23501 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
23502 +
23503 + /* Find used PADDR containing this address */
23504 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
23505 + {
23506 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
23507 + (p_Tgec->paddr[paddrNum] == ethAddr))
23508 + {
23509 + /* mark this PADDR as not used */
23510 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
23511 + /* clear in hardware */
23512 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
23513 + p_Tgec->numOfIndAddrInRegs--;
23514 +
23515 + return E_OK;
23516 + }
23517 + }
23518 +
23519 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
23520 +}
23521 +
23522 +/* ......................................................................... */
23523 +
23524 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23525 +{
23526 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23527 + t_EthHashEntry *p_HashEntry;
23528 + uint32_t crc;
23529 + uint32_t hash;
23530 + uint64_t ethAddr;
23531 +
23532 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23533 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23534 +
23535 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
23536 +
23537 + if (!(ethAddr & GROUP_ADDRESS))
23538 + /* Unicast addresses not supported in hash */
23539 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
23540 +
23541 + /* CRC calculation */
23542 + crc = GetMacAddrHashCode(ethAddr);
23543 +
23544 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
23545 +
23546 + /* Create element to be added to the driver hash table */
23547 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
23548 + p_HashEntry->addr = ethAddr;
23549 + INIT_LIST(&p_HashEntry->node);
23550 +
23551 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
23552 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
23553 +
23554 + return E_OK;
23555 +}
23556 +
23557 +/* ......................................................................... */
23558 +
23559 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23560 +{
23561 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23562 + t_EthHashEntry *p_HashEntry = NULL;
23563 + t_List *p_Pos;
23564 + uint32_t crc;
23565 + uint32_t hash;
23566 + uint64_t ethAddr;
23567 +
23568 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23569 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23570 +
23571 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
23572 +
23573 + /* CRC calculation */
23574 + crc = GetMacAddrHashCode(ethAddr);
23575 +
23576 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
23577 +
23578 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
23579 + {
23580 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
23581 + if (p_HashEntry->addr == ethAddr)
23582 + {
23583 + LIST_DelAndInit(&p_HashEntry->node);
23584 + XX_Free(p_HashEntry);
23585 + break;
23586 + }
23587 + }
23588 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
23589 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
23590 +
23591 + return E_OK;
23592 +}
23593 +
23594 +/* ......................................................................... */
23595 +
23596 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
23597 +{
23598 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23599 +
23600 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23601 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23602 +
23603 + UNUSED(p_Tgec);
23604 + UNUSED(macId);
23605 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
23606 +}
23607 +
23608 +/* ......................................................................... */
23609 +
23610 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
23611 +{
23612 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23613 +
23614 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23615 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23616 +
23617 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
23618 +
23619 + return E_OK;
23620 +}
23621 +
23622 +/* ......................................................................... */
23623 +
23624 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
23625 +{
23626 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23627 + uint32_t bitMask = 0;
23628 +
23629 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23630 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23631 +
23632 + GET_EXCEPTION_FLAG(bitMask, exception);
23633 + if (bitMask)
23634 + {
23635 + if (enable)
23636 + p_Tgec->exceptions |= bitMask;
23637 + else
23638 + p_Tgec->exceptions &= ~bitMask;
23639 + }
23640 + else
23641 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23642 +
23643 + if (enable)
23644 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
23645 + else
23646 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
23647 +
23648 + return E_OK;
23649 +}
23650 +
23651 +/* ......................................................................... */
23652 +
23653 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
23654 +{
23655 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23656 +
23657 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
23658 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
23659 +
23660 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
23661 +}
23662 +
23663 +/* ......................................................................... */
23664 +
23665 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
23666 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
23667 +{
23668 + t_Error err;
23669 +
23670 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
23671 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
23672 +#endif /* (DEBUG_ERRORS > 0) */
23673 + /* enable and set promiscuous */
23674 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
23675 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
23676 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
23677 + /* disable */
23678 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
23679 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
23680 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
23681 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
23682 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
23683 + if (err)
23684 + XX_Print("FAILED!\n");
23685 + else
23686 + XX_Print("done.\n");
23687 +#endif /* (DEBUG_ERRORS > 0) */
23688 +
23689 + return err;
23690 +}
23691 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
23692 +
23693 +/*****************************************************************************/
23694 +/* FM Init & Free API */
23695 +/*****************************************************************************/
23696 +
23697 +/* ......................................................................... */
23698 +
23699 +static t_Error TgecInit(t_Handle h_Tgec)
23700 +{
23701 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23702 + struct tgec_cfg *p_TgecDriverParam;
23703 + t_EnetAddr ethAddr;
23704 + t_Error err;
23705 +
23706 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23707 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23708 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
23709 +
23710 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
23711 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
23712 +
23713 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
23714 +
23715 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
23716 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
23717 +
23718 + /* interrupts */
23719 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
23720 + {
23721 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
23722 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
23723 + }
23724 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
23725 +
23726 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
23727 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
23728 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
23729 + {
23730 + FreeInitResources(p_Tgec);
23731 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
23732 + }
23733 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
23734 +
23735 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
23736 + if (err)
23737 + {
23738 + FreeInitResources(p_Tgec);
23739 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
23740 + }
23741 +
23742 + /* Max Frame Length */
23743 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
23744 + e_FM_MAC_10G,
23745 + p_Tgec->fmMacControllerDriver.macId,
23746 + p_TgecDriverParam->max_frame_length);
23747 + if (err != E_OK)
23748 + {
23749 + FreeInitResources(p_Tgec);
23750 + RETURN_ERROR(MINOR, err, NO_MSG);
23751 + }
23752 +/* we consider having no IPC a non crasher... */
23753 +
23754 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
23755 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
23756 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
23757 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
23758 +
23759 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
23760 + if (!p_Tgec->p_MulticastAddrHash)
23761 + {
23762 + FreeInitResources(p_Tgec);
23763 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
23764 + }
23765 +
23766 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
23767 + if (!p_Tgec->p_UnicastAddrHash)
23768 + {
23769 + FreeInitResources(p_Tgec);
23770 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
23771 + }
23772 +
23773 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
23774 + e_FM_MOD_10G_MAC,
23775 + p_Tgec->macId,
23776 + e_FM_INTR_TYPE_ERR,
23777 + TgecErrException,
23778 + p_Tgec);
23779 + if (p_Tgec->mdioIrq != NO_IRQ)
23780 + {
23781 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
23782 + XX_EnableIntr(p_Tgec->mdioIrq);
23783 + }
23784 +
23785 + XX_Free(p_TgecDriverParam);
23786 + p_Tgec->p_TgecDriverParam = NULL;
23787 +
23788 + return E_OK;
23789 +}
23790 +
23791 +/* ......................................................................... */
23792 +
23793 +static t_Error TgecFree(t_Handle h_Tgec)
23794 +{
23795 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23796 +
23797 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23798 +
23799 + if (p_Tgec->p_TgecDriverParam)
23800 + {
23801 + /* Called after config */
23802 + XX_Free(p_Tgec->p_TgecDriverParam);
23803 + p_Tgec->p_TgecDriverParam = NULL;
23804 + }
23805 + else
23806 + /* Called after init */
23807 + FreeInitResources(p_Tgec);
23808 +
23809 + XX_Free(p_Tgec);
23810 +
23811 + return E_OK;
23812 +}
23813 +
23814 +/* ......................................................................... */
23815 +
23816 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
23817 +{
23818 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
23819 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
23820 +
23821 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
23822 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
23823 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
23824 +
23825 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
23826 +
23827 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
23828 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
23829 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
23830 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
23831 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
23832 +
23833 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
23834 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
23835 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
23836 +
23837 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
23838 +
23839 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
23840 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
23841 +
23842 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
23843 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
23844 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
23845 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
23846 +
23847 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
23848 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
23849 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
23850 +
23851 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
23852 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
23853 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
23854 +
23855 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
23856 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
23857 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters;
23858 +
23859 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
23860 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
23861 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
23862 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
23863 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
23864 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
23865 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
23866 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
23867 +
23868 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
23869 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
23870 +}
23871 +
23872 +
23873 +/*****************************************************************************/
23874 +/* Tgec Config Main Entry */
23875 +/*****************************************************************************/
23876 +
23877 +/* ......................................................................... */
23878 +
23879 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
23880 +{
23881 + t_Tgec *p_Tgec;
23882 + struct tgec_cfg *p_TgecDriverParam;
23883 + uintptr_t baseAddr;
23884 +
23885 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
23886 +
23887 + baseAddr = p_FmMacParam->baseAddr;
23888 + /* allocate memory for the UCC GETH data structure. */
23889 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
23890 + if (!p_Tgec)
23891 + {
23892 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
23893 + return NULL;
23894 + }
23895 + memset(p_Tgec, 0, sizeof(t_Tgec));
23896 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
23897 +
23898 + /* allocate memory for the 10G MAC driver parameters data structure. */
23899 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
23900 + if (!p_TgecDriverParam)
23901 + {
23902 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
23903 + XX_Free(p_Tgec);
23904 + return NULL;
23905 + }
23906 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
23907 +
23908 + /* Plant parameter structure pointer */
23909 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
23910 +
23911 + fman_tgec_defconfig(p_TgecDriverParam);
23912 +
23913 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
23914 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
23915 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
23916 + p_Tgec->enetMode = p_FmMacParam->enetMode;
23917 + p_Tgec->macId = p_FmMacParam->macId;
23918 + p_Tgec->exceptions = DEFAULT_exceptions;
23919 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
23920 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
23921 + p_Tgec->f_Event = p_FmMacParam->f_Event;
23922 + p_Tgec->h_App = p_FmMacParam->h_App;
23923 +
23924 + return p_Tgec;
23925 +}
23926 --- /dev/null
23927 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
23928 @@ -0,0 +1,151 @@
23929 +/*
23930 + * Copyright 2008-2012 Freescale Semiconductor Inc.
23931 + *
23932 + * Redistribution and use in source and binary forms, with or without
23933 + * modification, are permitted provided that the following conditions are met:
23934 + * * Redistributions of source code must retain the above copyright
23935 + * notice, this list of conditions and the following disclaimer.
23936 + * * Redistributions in binary form must reproduce the above copyright
23937 + * notice, this list of conditions and the following disclaimer in the
23938 + * documentation and/or other materials provided with the distribution.
23939 + * * Neither the name of Freescale Semiconductor nor the
23940 + * names of its contributors may be used to endorse or promote products
23941 + * derived from this software without specific prior written permission.
23942 + *
23943 + *
23944 + * ALTERNATIVELY, this software may be distributed under the terms of the
23945 + * GNU General Public License ("GPL") as published by the Free Software
23946 + * Foundation, either version 2 of that License or (at your option) any
23947 + * later version.
23948 + *
23949 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23950 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23951 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23952 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23953 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23954 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23955 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23956 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23957 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23958 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23959 + */
23960 +
23961 +
23962 +/******************************************************************************
23963 + @File tgec.h
23964 +
23965 + @Description FM 10G MAC ...
23966 +*//***************************************************************************/
23967 +#ifndef __TGEC_H
23968 +#define __TGEC_H
23969 +
23970 +#include "std_ext.h"
23971 +#include "error_ext.h"
23972 +#include "list_ext.h"
23973 +#include "enet_ext.h"
23974 +
23975 +#include "tgec_mii_acc.h"
23976 +#include "fm_mac.h"
23977 +
23978 +
23979 +#define DEFAULT_exceptions \
23980 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
23981 + TGEC_IMASK_REM_FAULT | \
23982 + TGEC_IMASK_LOC_FAULT | \
23983 + TGEC_IMASK_TX_ECC_ER | \
23984 + TGEC_IMASK_TX_FIFO_UNFL | \
23985 + TGEC_IMASK_TX_FIFO_OVFL | \
23986 + TGEC_IMASK_TX_ER | \
23987 + TGEC_IMASK_RX_FIFO_OVFL | \
23988 + TGEC_IMASK_RX_ECC_ER | \
23989 + TGEC_IMASK_RX_JAB_FRM | \
23990 + TGEC_IMASK_RX_OVRSZ_FRM | \
23991 + TGEC_IMASK_RX_RUNT_FRM | \
23992 + TGEC_IMASK_RX_FRAG_FRM | \
23993 + TGEC_IMASK_RX_CRC_ER | \
23994 + TGEC_IMASK_RX_ALIGN_ER))
23995 +
23996 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
23997 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
23998 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
23999 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
24000 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
24001 + case e_FM_MAC_EX_10G_REM_FAULT: \
24002 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
24003 + case e_FM_MAC_EX_10G_LOC_FAULT: \
24004 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
24005 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
24006 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
24007 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
24008 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
24009 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
24010 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
24011 + case e_FM_MAC_EX_10G_TX_ER: \
24012 + bitMask = TGEC_IMASK_TX_ER ; break; \
24013 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
24014 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
24015 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
24016 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
24017 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
24018 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
24019 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
24020 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
24021 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
24022 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
24023 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
24024 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
24025 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
24026 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
24027 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
24028 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
24029 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
24030 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
24031 + default: bitMask = 0;break;}
24032 +
24033 +#define MAX_PACKET_ALIGNMENT 31
24034 +#define MAX_INTER_PACKET_GAP 0x7f
24035 +#define MAX_INTER_PALTERNATE_BEB 0x0f
24036 +#define MAX_RETRANSMISSION 0x0f
24037 +#define MAX_COLLISION_WINDOW 0x03ff
24038 +
24039 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
24040 +
24041 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
24042 +
24043 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
24044 +
24045 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
24046 +
24047 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
24048 +#define TGEC_ID_ID 0xffff0000
24049 +#define TGEC_ID_MAC_VERSION 0x0000FF00
24050 +#define TGEC_ID_MAC_REV 0x000000ff
24051 +
24052 +
24053 +typedef struct {
24054 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
24055 + t_Handle h_App; /**< Handle to the upper layer application */
24056 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
24057 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
24058 + uint64_t addr; /**< MAC address of device; */
24059 + e_EnetMode enetMode; /**< Ethernet physical interface */
24060 + t_FmMacExceptionCallback *f_Exception;
24061 + int mdioIrq;
24062 + t_FmMacExceptionCallback *f_Event;
24063 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
24064 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
24065 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
24066 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
24067 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
24068 + bool debugMode;
24069 + uint8_t macId;
24070 + uint32_t exceptions;
24071 + struct tgec_cfg *p_TgecDriverParam;
24072 +} t_Tgec;
24073 +
24074 +
24075 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
24076 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
24077 +
24078 +
24079 +#endif /* __TGEC_H */
24080 --- /dev/null
24081 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
24082 @@ -0,0 +1,139 @@
24083 +/*
24084 + * Copyright 2008-2012 Freescale Semiconductor Inc.
24085 + *
24086 + * Redistribution and use in source and binary forms, with or without
24087 + * modification, are permitted provided that the following conditions are met:
24088 + * * Redistributions of source code must retain the above copyright
24089 + * notice, this list of conditions and the following disclaimer.
24090 + * * Redistributions in binary form must reproduce the above copyright
24091 + * notice, this list of conditions and the following disclaimer in the
24092 + * documentation and/or other materials provided with the distribution.
24093 + * * Neither the name of Freescale Semiconductor nor the
24094 + * names of its contributors may be used to endorse or promote products
24095 + * derived from this software without specific prior written permission.
24096 + *
24097 + *
24098 + * ALTERNATIVELY, this software may be distributed under the terms of the
24099 + * GNU General Public License ("GPL") as published by the Free Software
24100 + * Foundation, either version 2 of that License or (at your option) any
24101 + * later version.
24102 + *
24103 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24104 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24105 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24106 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24107 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24108 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24109 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24110 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24111 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24112 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24113 + */
24114 +
24115 +
24116 +
24117 +#include "error_ext.h"
24118 +#include "std_ext.h"
24119 +#include "fm_mac.h"
24120 +#include "tgec.h"
24121 +#include "xx_ext.h"
24122 +
24123 +#include "fm_common.h"
24124 +
24125 +
24126 +/*****************************************************************************/
24127 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
24128 + uint8_t phyAddr,
24129 + uint8_t reg,
24130 + uint16_t data)
24131 +{
24132 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24133 + t_TgecMiiAccessMemMap *p_MiiAccess;
24134 + uint32_t cfgStatusReg;
24135 +
24136 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
24137 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
24138 +
24139 + p_MiiAccess = p_Tgec->p_MiiMemMap;
24140 +
24141 + /* Configure MII */
24142 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
24143 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
24144 + /* (one half of fm clock => 2.5Mhz) */
24145 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
24146 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
24147 +
24148 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24149 + XX_UDelay (1);
24150 +
24151 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
24152 +
24153 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
24154 +
24155 + CORE_MemoryBarrier();
24156 +
24157 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24158 + XX_UDelay (1);
24159 +
24160 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
24161 +
24162 + CORE_MemoryBarrier();
24163 +
24164 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
24165 + XX_UDelay (1);
24166 +
24167 + return E_OK;
24168 +}
24169 +
24170 +/*****************************************************************************/
24171 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
24172 + uint8_t phyAddr,
24173 + uint8_t reg,
24174 + uint16_t *p_Data)
24175 +{
24176 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24177 + t_TgecMiiAccessMemMap *p_MiiAccess;
24178 + uint32_t cfgStatusReg;
24179 +
24180 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
24181 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
24182 +
24183 + p_MiiAccess = p_Tgec->p_MiiMemMap;
24184 +
24185 + /* Configure MII */
24186 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
24187 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
24188 + /* (one half of fm clock => 2.5Mhz) */
24189 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
24190 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
24191 +
24192 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24193 + XX_UDelay (1);
24194 +
24195 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
24196 +
24197 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
24198 +
24199 + CORE_MemoryBarrier();
24200 +
24201 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24202 + XX_UDelay (1);
24203 +
24204 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
24205 +
24206 + CORE_MemoryBarrier();
24207 +
24208 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
24209 + XX_UDelay (1);
24210 +
24211 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
24212 +
24213 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
24214 +
24215 + if (cfgStatusReg & MIIMIND_READ_ERROR)
24216 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
24217 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
24218 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
24219 +
24220 + return E_OK;
24221 +}
24222 --- /dev/null
24223 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
24224 @@ -0,0 +1,80 @@
24225 +/*
24226 + * Copyright 2008-2012 Freescale Semiconductor Inc.
24227 + *
24228 + * Redistribution and use in source and binary forms, with or without
24229 + * modification, are permitted provided that the following conditions are met:
24230 + * * Redistributions of source code must retain the above copyright
24231 + * notice, this list of conditions and the following disclaimer.
24232 + * * Redistributions in binary form must reproduce the above copyright
24233 + * notice, this list of conditions and the following disclaimer in the
24234 + * documentation and/or other materials provided with the distribution.
24235 + * * Neither the name of Freescale Semiconductor nor the
24236 + * names of its contributors may be used to endorse or promote products
24237 + * derived from this software without specific prior written permission.
24238 + *
24239 + *
24240 + * ALTERNATIVELY, this software may be distributed under the terms of the
24241 + * GNU General Public License ("GPL") as published by the Free Software
24242 + * Foundation, either version 2 of that License or (at your option) any
24243 + * later version.
24244 + *
24245 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24246 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24247 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24248 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24249 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24250 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24251 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24252 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24253 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24254 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24255 + */
24256 +
24257 +
24258 +#ifndef __TGEC_MII_ACC_H
24259 +#define __TGEC_MII_ACC_H
24260 +
24261 +#include "std_ext.h"
24262 +
24263 +
24264 +/* MII Management Command Register */
24265 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
24266 +#define MIIMCOM_READ_CYCLE 0x00008000
24267 +#define MIIMCOM_SCAN_CYCLE 0x00000800
24268 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
24269 +
24270 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
24271 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
24272 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
24273 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
24274 +
24275 +#define MIIMCOM_DIV_MASK 0x0000ff00
24276 +#define MIIMCOM_DIV_SHIFT 8
24277 +
24278 +/* MII Management Indicator Register */
24279 +#define MIIMIND_BUSY 0x00000001
24280 +#define MIIMIND_READ_ERROR 0x00000002
24281 +
24282 +#define MIIDATA_BUSY 0x80000000
24283 +
24284 +#if defined(__MWERKS__) && !defined(__GNUC__)
24285 +#pragma pack(push,1)
24286 +#endif /* defined(__MWERKS__) && ... */
24287 +
24288 +/*----------------------------------------------------*/
24289 +/* MII Configuration Control Memory Map Registers */
24290 +/*----------------------------------------------------*/
24291 +typedef _Packed struct t_TgecMiiAccessMemMap
24292 +{
24293 + volatile uint32_t mdio_cfg_status; /* 0x030 */
24294 + volatile uint32_t mdio_command; /* 0x034 */
24295 + volatile uint32_t mdio_data; /* 0x038 */
24296 + volatile uint32_t mdio_regaddr; /* 0x03c */
24297 +} _PackedType t_TgecMiiAccessMemMap ;
24298 +
24299 +#if defined(__MWERKS__) && !defined(__GNUC__)
24300 +#pragma pack(pop)
24301 +#endif /* defined(__MWERKS__) && ... */
24302 +
24303 +
24304 +#endif /* __TGEC_MII_ACC_H */
24305 --- /dev/null
24306 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
24307 @@ -0,0 +1,15 @@
24308 +#
24309 +# Makefile for the Freescale Ethernet controllers
24310 +#
24311 +ccflags-y += -DVERSION=\"\"
24312 +#
24313 +#Include netcomm SW specific definitions
24314 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
24315 +
24316 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
24317 +
24318 +ccflags-y += -I$(NCSW_FM_INC)
24319 +
24320 +obj-y += fsl-ncsw-macsec.o
24321 +
24322 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
24323 --- /dev/null
24324 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
24325 @@ -0,0 +1,237 @@
24326 +/*
24327 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24328 + *
24329 + * Redistribution and use in source and binary forms, with or without
24330 + * modification, are permitted provided that the following conditions are met:
24331 + * * Redistributions of source code must retain the above copyright
24332 + * notice, this list of conditions and the following disclaimer.
24333 + * * Redistributions in binary form must reproduce the above copyright
24334 + * notice, this list of conditions and the following disclaimer in the
24335 + * documentation and/or other materials provided with the distribution.
24336 + * * Neither the name of Freescale Semiconductor nor the
24337 + * names of its contributors may be used to endorse or promote products
24338 + * derived from this software without specific prior written permission.
24339 + *
24340 + *
24341 + * ALTERNATIVELY, this software may be distributed under the terms of the
24342 + * GNU General Public License ("GPL") as published by the Free Software
24343 + * Foundation, either version 2 of that License or (at your option) any
24344 + * later version.
24345 + *
24346 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24347 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24348 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24349 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24350 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24351 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24352 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24353 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24354 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24355 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24356 + */
24357 +/******************************************************************************
24358 +
24359 + @File fm_macsec.c
24360 +
24361 + @Description FM MACSEC driver routines implementation.
24362 +*//***************************************************************************/
24363 +
24364 +#include "std_ext.h"
24365 +#include "error_ext.h"
24366 +#include "xx_ext.h"
24367 +#include "string_ext.h"
24368 +#include "sprint_ext.h"
24369 +#include "debug_ext.h"
24370 +
24371 +#include "fm_macsec.h"
24372 +
24373 +
24374 +/****************************************/
24375 +/* API Init unit functions */
24376 +/****************************************/
24377 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
24378 +{
24379 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
24380 +
24381 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
24382 +
24383 + if (p_FmMacsecParam->guestMode)
24384 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
24385 + else
24386 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
24387 +
24388 + if (!p_FmMacsecControllerDriver)
24389 + return NULL;
24390 +
24391 + return (t_Handle)p_FmMacsecControllerDriver;
24392 +}
24393 +
24394 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
24395 +{
24396 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24397 +
24398 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24399 +
24400 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
24401 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
24402 +
24403 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24404 +}
24405 +
24406 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
24407 +{
24408 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24409 +
24410 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24411 +
24412 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
24413 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
24414 +
24415 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24416 +}
24417 +
24418 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
24419 +{
24420 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24421 +
24422 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24423 +
24424 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
24425 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
24426 +
24427 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24428 +}
24429 +
24430 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
24431 +{
24432 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24433 +
24434 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24435 +
24436 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
24437 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
24438 +
24439 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24440 +}
24441 +
24442 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
24443 +{
24444 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24445 +
24446 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24447 +
24448 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
24449 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
24450 +
24451 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24452 +}
24453 +
24454 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
24455 +{
24456 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24457 +
24458 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24459 +
24460 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
24461 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
24462 +
24463 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24464 +}
24465 +
24466 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
24467 +{
24468 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24469 +
24470 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24471 +
24472 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
24473 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
24474 +
24475 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24476 +}
24477 +
24478 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
24479 +{
24480 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24481 +
24482 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24483 +
24484 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
24485 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
24486 +
24487 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24488 +}
24489 +
24490 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
24491 +{
24492 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24493 +
24494 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24495 +
24496 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
24497 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
24498 +
24499 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24500 +}
24501 +
24502 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
24503 +{
24504 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24505 +
24506 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24507 +
24508 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
24509 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
24510 +
24511 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24512 +}
24513 +
24514 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
24515 +{
24516 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24517 +
24518 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24519 +
24520 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
24521 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
24522 +
24523 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24524 +}
24525 +
24526 +
24527 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
24528 +{
24529 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24530 +
24531 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24532 +
24533 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
24534 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
24535 +
24536 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24537 +}
24538 +
24539 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
24540 +{
24541 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24542 +
24543 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24544 +
24545 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
24546 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
24547 +
24548 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24549 +}
24550 +
24551 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
24552 +{
24553 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24554 +
24555 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24556 +
24557 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
24558 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
24559 +
24560 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24561 +}
24562 +
24563 --- /dev/null
24564 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
24565 @@ -0,0 +1,203 @@
24566 +/*
24567 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24568 + *
24569 + * Redistribution and use in source and binary forms, with or without
24570 + * modification, are permitted provided that the following conditions are met:
24571 + * * Redistributions of source code must retain the above copyright
24572 + * notice, this list of conditions and the following disclaimer.
24573 + * * Redistributions in binary form must reproduce the above copyright
24574 + * notice, this list of conditions and the following disclaimer in the
24575 + * documentation and/or other materials provided with the distribution.
24576 + * * Neither the name of Freescale Semiconductor nor the
24577 + * names of its contributors may be used to endorse or promote products
24578 + * derived from this software without specific prior written permission.
24579 + *
24580 + *
24581 + * ALTERNATIVELY, this software may be distributed under the terms of the
24582 + * GNU General Public License ("GPL") as published by the Free Software
24583 + * Foundation, either version 2 of that License or (at your option) any
24584 + * later version.
24585 + *
24586 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24587 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24588 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24589 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24590 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24591 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24592 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24593 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24594 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24595 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24596 + */
24597 +
24598 +/******************************************************************************
24599 + @File fm_macsec.h
24600 +
24601 + @Description FM MACSEC internal structures and definitions.
24602 +*//***************************************************************************/
24603 +#ifndef __FM_MACSEC_H
24604 +#define __FM_MACSEC_H
24605 +
24606 +#include "error_ext.h"
24607 +#include "std_ext.h"
24608 +#include "fm_macsec_ext.h"
24609 +
24610 +#include "fm_common.h"
24611 +
24612 +
24613 +#define __ERR_MODULE__ MODULE_FM_MACSEC
24614 +
24615 +
24616 +typedef struct
24617 +{
24618 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
24619 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
24620 +
24621 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
24622 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
24623 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
24624 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
24625 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
24626 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
24627 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
24628 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
24629 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
24630 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
24631 +
24632 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
24633 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
24634 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
24635 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
24636 +
24637 +} t_FmMacsecControllerDriver;
24638 +
24639 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
24640 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
24641 +
24642 +/***********************************************************************/
24643 +/* MACSEC internal routines */
24644 +/***********************************************************************/
24645 +
24646 +/**************************************************************************//**
24647 +
24648 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
24649 +
24650 + @Description FM MACSEC Inter Module functions -
24651 + These are not User API routines but routines that may be called
24652 + from other modules. This will be the case in a single core environment,
24653 + where instead of using the XX messaging mechanism, the routines may be
24654 + called from other modules. In a multicore environment, the other modules may
24655 + be run by other cores and therefore these routines may not be called directly.
24656 +
24657 + @{
24658 +*//***************************************************************************/
24659 +
24660 +#define MAX_NUM_OF_SA_PER_SC 4
24661 +
24662 +typedef enum
24663 +{
24664 + e_SC_RX = 0,
24665 + e_SC_TX
24666 +} e_ScType;
24667 +
24668 +typedef enum
24669 +{
24670 + e_SC_SA_A = 0,
24671 + e_SC_SA_B ,
24672 + e_SC_SA_C ,
24673 + e_SC_SA_D
24674 +} e_ScSaId;
24675 +
24676 +typedef struct
24677 +{
24678 + uint32_t scId;
24679 + macsecSCI_t sci;
24680 + bool replayProtect;
24681 + uint32_t replayWindow;
24682 + e_FmMacsecValidFrameBehavior validateFrames;
24683 + uint16_t confidentialityOffset;
24684 + e_FmMacsecSecYCipherSuite cipherSuite;
24685 +} t_RxScParams;
24686 +
24687 +typedef struct
24688 +{
24689 + uint32_t scId;
24690 + macsecSCI_t sci;
24691 + bool protectFrames;
24692 + e_FmMacsecSciInsertionMode sciInsertionMode;
24693 + bool confidentialityEnable;
24694 + uint16_t confidentialityOffset;
24695 + e_FmMacsecSecYCipherSuite cipherSuite;
24696 +} t_TxScParams;
24697 +
24698 +typedef enum e_FmMacsecGlobalExceptions {
24699 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
24700 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
24701 +} e_FmMacsecGlobalExceptions;
24702 +
24703 +typedef enum e_FmMacsecGlobalEvents {
24704 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
24705 +} e_FmMacsecGlobalEvents;
24706 +
24707 +/**************************************************************************//**
24708 + @Description Enum for inter-module interrupts registration
24709 +*//***************************************************************************/
24710 +typedef enum e_FmMacsecEventModules{
24711 + e_FM_MACSEC_MOD_SC_TX,
24712 + e_FM_MACSEC_MOD_DUMMY_LAST
24713 +} e_FmMacsecEventModules;
24714 +
24715 +typedef enum e_FmMacsecInterModuleEvent {
24716 + e_FM_MACSEC_EV_SC_TX,
24717 + e_FM_MACSEC_EV_ERR_SC_TX,
24718 + e_FM_MACSEC_EV_DUMMY_LAST
24719 +} e_FmMacsecInterModuleEvent;
24720 +
24721 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
24722 +
24723 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
24724 + switch(mod){ \
24725 + case e_FM_MACSEC_MOD_SC_TX: \
24726 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
24727 + e_FM_MACSEC_EV_ERR_SC_TX: \
24728 + e_FM_MACSEC_EV_SC_TX; \
24729 + event += (uint8_t)(2 * id);break; \
24730 + break; \
24731 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
24732 + break;}
24733 +
24734 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
24735 + e_FmMacsecEventModules module,
24736 + uint8_t modId,
24737 + e_FmIntrType intrType,
24738 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
24739 + t_Handle h_Arg);
24740 +
24741 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
24742 + e_FmMacsecEventModules module,
24743 + uint8_t modId,
24744 + e_FmIntrType intrType);
24745 +
24746 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
24747 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
24748 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
24749 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
24750 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
24751 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
24752 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
24753 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
24754 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
24755 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
24756 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
24757 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
24758 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
24759 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
24760 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
24761 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
24762 +
24763 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
24764 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
24765 +
24766 +
24767 +
24768 +#endif /* __FM_MACSEC_H */
24769 --- /dev/null
24770 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
24771 @@ -0,0 +1,59 @@
24772 +/*
24773 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24774 + *
24775 + * Redistribution and use in source and binary forms, with or without
24776 + * modification, are permitted provided that the following conditions are met:
24777 + * * Redistributions of source code must retain the above copyright
24778 + * notice, this list of conditions and the following disclaimer.
24779 + * * Redistributions in binary form must reproduce the above copyright
24780 + * notice, this list of conditions and the following disclaimer in the
24781 + * documentation and/or other materials provided with the distribution.
24782 + * * Neither the name of Freescale Semiconductor nor the
24783 + * names of its contributors may be used to endorse or promote products
24784 + * derived from this software without specific prior written permission.
24785 + *
24786 + *
24787 + * ALTERNATIVELY, this software may be distributed under the terms of the
24788 + * GNU General Public License ("GPL") as published by the Free Software
24789 + * Foundation, either version 2 of that License or (at your option) any
24790 + * later version.
24791 + *
24792 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24793 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24794 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24795 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24796 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24797 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24798 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24799 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24800 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24801 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24802 + */
24803 +
24804 +/******************************************************************************
24805 + @File fm_macsec.c
24806 +
24807 + @Description FM MACSEC driver routines implementation.
24808 +*//***************************************************************************/
24809 +
24810 +#include "std_ext.h"
24811 +#include "error_ext.h"
24812 +#include "xx_ext.h"
24813 +#include "string_ext.h"
24814 +#include "sprint_ext.h"
24815 +#include "debug_ext.h"
24816 +#include "fm_macsec.h"
24817 +
24818 +
24819 +/****************************************/
24820 +/* static functions */
24821 +/****************************************/
24822 +
24823 +/****************************************/
24824 +/* API Init unit functions */
24825 +/****************************************/
24826 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
24827 +{
24828 + UNUSED(p_FmMacsecParam);
24829 + return NULL;
24830 +}
24831 --- /dev/null
24832 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
24833 @@ -0,0 +1,1031 @@
24834 +/*
24835 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24836 + *
24837 + * Redistribution and use in source and binary forms, with or without
24838 + * modification, are permitted provided that the following conditions are met:
24839 + * * Redistributions of source code must retain the above copyright
24840 + * notice, this list of conditions and the following disclaimer.
24841 + * * Redistributions in binary form must reproduce the above copyright
24842 + * notice, this list of conditions and the following disclaimer in the
24843 + * documentation and/or other materials provided with the distribution.
24844 + * * Neither the name of Freescale Semiconductor nor the
24845 + * names of its contributors may be used to endorse or promote products
24846 + * derived from this software without specific prior written permission.
24847 + *
24848 + *
24849 + * ALTERNATIVELY, this software may be distributed under the terms of the
24850 + * GNU General Public License ("GPL") as published by the Free Software
24851 + * Foundation, either version 2 of that License or (at your option) any
24852 + * later version.
24853 + *
24854 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24855 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24856 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24857 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24858 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24859 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24860 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24861 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24862 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24863 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24864 + */
24865 +
24866 +/******************************************************************************
24867 + @File fm_macsec.c
24868 +
24869 + @Description FM MACSEC driver routines implementation.
24870 +*//***************************************************************************/
24871 +
24872 +#include "std_ext.h"
24873 +#include "error_ext.h"
24874 +#include "xx_ext.h"
24875 +#include "string_ext.h"
24876 +#include "sprint_ext.h"
24877 +#include "fm_mac_ext.h"
24878 +
24879 +#include "fm_macsec_master.h"
24880 +
24881 +
24882 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
24883 +
24884 +
24885 +/****************************************/
24886 +/* static functions */
24887 +/****************************************/
24888 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
24889 +{
24890 + if (!p_FmMacsec->f_Exception)
24891 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
24892 +
24893 + return E_OK;
24894 +}
24895 +
24896 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
24897 +{
24898 + UNUSED(h_Arg); UNUSED(id);
24899 +
24900 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
24901 +}
24902 +
24903 +static void MacsecEventIsr(t_Handle h_FmMacsec)
24904 +{
24905 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24906 + uint32_t events,event,i;
24907 +
24908 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
24909 +
24910 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
24911 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
24912 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
24913 +
24914 + for (i=0; i<NUM_OF_TX_SC; i++)
24915 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
24916 + {
24917 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
24918 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
24919 + }
24920 +}
24921 +
24922 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
24923 +{
24924 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24925 + uint32_t errors,error,i;
24926 +
24927 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
24928 +
24929 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
24930 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
24931 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
24932 +
24933 + for (i=0; i<NUM_OF_TX_SC; i++)
24934 + if (errors & FM_MACSEC_EX_TX_SC(i))
24935 + {
24936 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
24937 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
24938 + }
24939 +
24940 + if (errors & FM_MACSEC_EX_ECC)
24941 + {
24942 + uint8_t eccType;
24943 + uint32_t tmpReg;
24944 +
24945 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
24946 + ASSERT_COND(tmpReg & MECC_CAP);
24947 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
24948 +
24949 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
24950 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
24951 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
24952 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
24953 + else
24954 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
24955 + }
24956 +}
24957 +
24958 +static t_Error MacsecInit(t_Handle h_FmMacsec)
24959 +{
24960 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24961 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
24962 + uint32_t tmpReg,i,macId;
24963 +
24964 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24965 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24966 +
24967 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
24968 +
24969 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
24970 +
24971 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
24972 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
24973 +
24974 + tmpReg = 0;
24975 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
24976 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
24977 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
24978 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
24979 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
24980 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
24981 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
24982 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
24983 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
24984 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
24985 +
24986 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
24987 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
24988 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
24989 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
24990 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
24991 +
24992 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
24993 +
24994 + if (!p_FmMacsec->userExceptions)
24995 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
24996 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24997 +
24998 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
24999 + if (p_FmMacsecDriverParam->reservedSc0)
25000 + p_FmMacsec->numRxScAvailable --;
25001 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
25002 +
25003 + XX_Free(p_FmMacsecDriverParam);
25004 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
25005 +
25006 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
25007 + FmRegisterIntr(p_FmMacsec->h_Fm,
25008 + e_FM_MOD_MACSEC,
25009 + (uint8_t)macId,
25010 + e_FM_INTR_TYPE_NORMAL,
25011 + MacsecEventIsr,
25012 + p_FmMacsec);
25013 +
25014 + FmRegisterIntr(p_FmMacsec->h_Fm,
25015 + e_FM_MOD_MACSEC,
25016 + 0,
25017 + e_FM_INTR_TYPE_ERR,
25018 + MacsecErrorIsr,
25019 + p_FmMacsec);
25020 +
25021 + return E_OK;
25022 +}
25023 +
25024 +static t_Error MacsecFree(t_Handle h_FmMacsec)
25025 +{
25026 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25027 + uint32_t macId;
25028 +
25029 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25030 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25031 +
25032 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
25033 + FmUnregisterIntr(p_FmMacsec->h_Fm,
25034 + e_FM_MOD_MACSEC,
25035 + (uint8_t)macId,
25036 + e_FM_INTR_TYPE_NORMAL);
25037 +
25038 + FmUnregisterIntr(p_FmMacsec->h_Fm,
25039 + e_FM_MOD_MACSEC,
25040 + 0,
25041 + e_FM_INTR_TYPE_ERR);
25042 +
25043 + if (p_FmMacsec->rxScSpinLock)
25044 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
25045 + if (p_FmMacsec->txScSpinLock)
25046 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
25047 +
25048 + XX_Free(p_FmMacsec);
25049 +
25050 + return E_OK;
25051 +}
25052 +
25053 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
25054 +{
25055 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25056 +
25057 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25058 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25059 +
25060 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
25061 +
25062 + return E_OK;
25063 +}
25064 +
25065 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
25066 +{
25067 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25068 +
25069 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25070 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25071 +
25072 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
25073 +
25074 + return E_OK;
25075 +}
25076 +
25077 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
25078 +{
25079 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25080 +
25081 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25082 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25083 +
25084 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
25085 +
25086 + return E_OK;
25087 +}
25088 +
25089 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
25090 +{
25091 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25092 +
25093 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25094 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25095 +
25096 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
25097 +
25098 + return E_OK;
25099 +}
25100 +
25101 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
25102 +{
25103 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25104 +
25105 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25106 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25107 +
25108 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
25109 +
25110 + return E_OK;
25111 +}
25112 +
25113 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
25114 +{
25115 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25116 +
25117 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25118 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25119 +
25120 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
25121 +
25122 + return E_OK;
25123 +}
25124 +
25125 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
25126 +{
25127 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25128 +
25129 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25130 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25131 +
25132 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
25133 +
25134 + return E_OK;
25135 +}
25136 +
25137 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
25138 +{
25139 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25140 +
25141 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25142 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25143 +
25144 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
25145 +
25146 + return E_OK;
25147 +}
25148 +
25149 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
25150 +{
25151 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25152 +
25153 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25154 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25155 +
25156 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
25157 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
25158 +
25159 + return E_OK;
25160 +}
25161 +
25162 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
25163 +{
25164 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25165 + uint32_t bitMask = 0;
25166 +
25167 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25168 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25169 +
25170 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
25171 + if (bitMask)
25172 + {
25173 + if (enable)
25174 + p_FmMacsec->userExceptions |= bitMask;
25175 + else
25176 + p_FmMacsec->userExceptions &= ~bitMask;
25177 + }
25178 + else
25179 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25180 +
25181 + return E_OK;
25182 +}
25183 +
25184 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
25185 +{
25186 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25187 +
25188 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25189 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25190 +
25191 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
25192 +
25193 + return E_OK;
25194 +}
25195 +
25196 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
25197 +{
25198 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25199 + uint32_t tmpReg;
25200 +
25201 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25202 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25203 +
25204 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
25205 + tmpReg |= CFG_BYPN;
25206 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
25207 +
25208 + return E_OK;
25209 +}
25210 +
25211 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
25212 +{
25213 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25214 + uint32_t tmpReg;
25215 +
25216 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25217 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25218 +
25219 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
25220 + tmpReg &= ~CFG_BYPN;
25221 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
25222 +
25223 + return E_OK;
25224 +}
25225 +
25226 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
25227 +{
25228 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25229 + uint32_t bitMask;
25230 +
25231 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25232 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25233 +
25234 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
25235 + if (bitMask)
25236 + {
25237 + if (enable)
25238 + p_FmMacsec->userExceptions |= bitMask;
25239 + else
25240 + p_FmMacsec->userExceptions &= ~bitMask;
25241 + }
25242 + else
25243 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25244 +
25245 + if (!p_FmMacsec->userExceptions)
25246 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
25247 + else
25248 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
25249 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
25250 +
25251 + return E_OK;
25252 +}
25253 +
25254 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
25255 +{
25256 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
25257 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
25258 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
25259 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
25260 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
25261 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
25262 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
25263 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
25264 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
25265 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
25266 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
25267 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
25268 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
25269 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
25270 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
25271 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
25272 +}
25273 +
25274 +/****************************************/
25275 +/* Inter-Module functions */
25276 +/****************************************/
25277 +
25278 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
25279 + e_FmMacsecEventModules module,
25280 + uint8_t modId,
25281 + e_FmIntrType intrType,
25282 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
25283 + t_Handle h_Arg)
25284 +{
25285 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25286 + uint8_t event= 0;
25287 +
25288 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
25289 +
25290 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
25291 +
25292 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
25293 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
25294 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
25295 +}
25296 +
25297 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
25298 + e_FmMacsecEventModules module,
25299 + uint8_t modId,
25300 + e_FmIntrType intrType)
25301 +{
25302 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25303 + uint8_t event= 0;
25304 +
25305 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
25306 +
25307 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
25308 +
25309 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
25310 + p_FmMacsec->intrMng[event].f_Isr = NULL;
25311 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
25312 +}
25313 +
25314 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
25315 +{
25316 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25317 + t_Error err = E_OK;
25318 + bool *p_ScTable;
25319 + uint32_t *p_ScAvailable,i;
25320 +
25321 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25322 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
25323 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
25324 +
25325 + if (type == e_SC_RX)
25326 + {
25327 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
25328 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
25329 + i = (NUM_OF_RX_SC - 1);
25330 + }
25331 + else
25332 + {
25333 + p_ScTable = (bool *)p_FmMacsec->txScTable;
25334 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
25335 + i = (NUM_OF_TX_SC - 1);
25336 +
25337 + }
25338 + if (*p_ScAvailable < numOfScs)
25339 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
25340 +
25341 + if (isPtp)
25342 + {
25343 + i = 0;
25344 + if (p_ScTable[i])
25345 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
25346 + }
25347 +
25348 + for (;numOfScs;i--)
25349 + {
25350 + if (p_ScTable[i])
25351 + continue;
25352 + numOfScs --;
25353 + (*p_ScAvailable)--;
25354 + p_ScIds[numOfScs] = i;
25355 + p_ScTable[i] = TRUE;
25356 + }
25357 +
25358 + return err;
25359 +}
25360 +
25361 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
25362 +{
25363 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25364 + t_Error err = E_OK;
25365 + bool *p_ScTable;
25366 + uint32_t *p_ScAvailable,maxNumOfSc,i;
25367 +
25368 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25369 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
25370 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
25371 +
25372 + if (type == e_SC_RX)
25373 + {
25374 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
25375 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
25376 + maxNumOfSc = NUM_OF_RX_SC;
25377 + }
25378 + else
25379 + {
25380 + p_ScTable = (bool *)p_FmMacsec->txScTable;
25381 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
25382 + maxNumOfSc = NUM_OF_TX_SC;
25383 + }
25384 +
25385 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
25386 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
25387 +
25388 + for (i=0;i<numOfScs;i++)
25389 + {
25390 + p_ScTable[p_ScIds[i]] = FALSE;
25391 + (*p_ScAvailable)++;
25392 + }
25393 +
25394 + return err;
25395 +
25396 +}
25397 +
25398 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
25399 +{
25400 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25401 + uint32_t tmpReg = 0;
25402 +
25403 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25404 +
25405 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
25406 + if (enable && (tmpReg & CFG_S0I))
25407 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
25408 +
25409 + if (enable)
25410 + tmpReg |= CFG_S0I;
25411 + else
25412 + tmpReg &= ~CFG_S0I;
25413 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
25414 +
25415 + return E_OK;
25416 +}
25417 +
25418 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
25419 +{
25420 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25421 + t_Error err = E_OK;
25422 + uint32_t tmpReg = 0, intFlags;
25423 +
25424 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25425 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
25426 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25427 +
25428 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25429 +
25430 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
25431 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
25432 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
25433 + {
25434 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25435 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
25436 + }
25437 +
25438 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
25439 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
25440 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
25441 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
25442 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
25443 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
25444 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
25445 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
25446 +
25447 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
25448 +
25449 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25450 +
25451 + return err;
25452 +}
25453 +
25454 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
25455 +{
25456 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25457 + t_Error err = E_OK;
25458 + uint32_t tmpReg = 0, intFlags;
25459 +
25460 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25461 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25462 +
25463 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25464 +
25465 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
25466 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25467 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
25468 +
25469 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25470 +
25471 + return err;
25472 +}
25473 +
25474 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
25475 +{
25476 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25477 + t_Error err = E_OK;
25478 + uint32_t tmpReg = 0, intFlags;
25479 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
25480 +
25481 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25482 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
25483 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
25484 +
25485 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25486 +
25487 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
25488 +
25489 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
25490 + if (tmpReg & TX_SCCFG_SCE_MASK)
25491 + {
25492 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25493 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
25494 + }
25495 +
25496 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
25497 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
25498 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
25499 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
25500 +
25501 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
25502 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
25503 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
25504 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
25505 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
25506 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
25507 + tmpReg |= TX_SCCFG_SCE_MASK;
25508 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
25509 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
25510 +
25511 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25512 +
25513 + return err;
25514 +}
25515 +
25516 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
25517 +{
25518 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25519 + t_Error err = E_OK;
25520 + uint32_t tmpReg = 0, intFlags;
25521 +
25522 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25523 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
25524 +
25525 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25526 +
25527 + tmpReg &= ~TX_SCCFG_SCE_MASK;
25528 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25529 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
25530 +
25531 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25532 +
25533 + return err;
25534 +}
25535 +
25536 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25537 +{
25538 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25539 + t_Error err = E_OK;
25540 + uint32_t tmpReg = 0, intFlags;
25541 +
25542 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25543 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25544 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25545 +
25546 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25547 +
25548 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25549 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
25550 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
25551 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
25552 +
25553 + tmpReg |= RX_SACFG_ACTIVE;
25554 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
25555 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
25556 +
25557 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25558 +
25559 + return err;
25560 +}
25561 +
25562 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
25563 +{
25564 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25565 + t_Error err = E_OK;
25566 + uint32_t tmpReg = 0, intFlags;
25567 +
25568 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25569 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25570 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
25571 +
25572 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25573 +
25574 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25575 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
25576 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
25577 +
25578 + tmpReg |= TX_SACFG_ACTIVE;
25579 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
25580 +
25581 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25582 +
25583 + return err;
25584 +}
25585 +
25586 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
25587 +{
25588 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25589 + t_Error err = E_OK;
25590 + uint32_t tmpReg = 0, i, intFlags;
25591 +
25592 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25593 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25594 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25595 +
25596 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25597 +
25598 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25599 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
25600 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
25601 + for (i=0; i<4; i++)
25602 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
25603 +
25604 + tmpReg |= RX_SACFG_ACTIVE;
25605 + tmpReg &= ~RX_SACFG_EN_MASK;
25606 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
25607 +
25608 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25609 +
25610 + return err;
25611 +}
25612 +
25613 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
25614 +{
25615 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25616 + t_Error err = E_OK;
25617 + uint32_t tmpReg = 0, i, intFlags;
25618 +
25619 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25620 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25621 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
25622 +
25623 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25624 +
25625 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25626 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
25627 + for (i=0; i<4; i++)
25628 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
25629 +
25630 + tmpReg |= TX_SACFG_ACTIVE;
25631 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
25632 +
25633 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25634 +
25635 + return err;
25636 +}
25637 +
25638 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
25639 +{
25640 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25641 + t_Error err = E_OK;
25642 + uint32_t tmpReg = 0, intFlags;
25643 +
25644 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25645 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25646 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25647 +
25648 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25649 +
25650 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25651 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
25652 + if (enableReceive)
25653 + tmpReg |= RX_SACFG_EN_MASK;
25654 + else
25655 + tmpReg &= ~RX_SACFG_EN_MASK;
25656 +
25657 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
25658 +
25659 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25660 +
25661 + return err;
25662 +}
25663 +
25664 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
25665 +{
25666 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25667 + t_Error err = E_OK;
25668 + uint32_t intFlags;
25669 +
25670 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25671 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25672 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25673 +
25674 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25675 +
25676 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25677 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
25678 +
25679 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25680 +
25681 + return err;
25682 +}
25683 +
25684 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
25685 +{
25686 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25687 + t_Error err = E_OK;
25688 + uint32_t intFlags;
25689 +
25690 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25691 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25692 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25693 +
25694 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25695 +
25696 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25697 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
25698 +
25699 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25700 +
25701 + return err;
25702 +}
25703 +
25704 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
25705 +{
25706 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25707 + t_Error err = E_OK;
25708 + uint32_t tmpReg = 0, intFlags;
25709 +
25710 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25711 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25712 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
25713 +
25714 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25715 +
25716 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25717 +
25718 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
25719 +
25720 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
25721 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
25722 +
25723 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
25724 +
25725 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25726 +
25727 + return err;
25728 +}
25729 +
25730 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
25731 +{
25732 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25733 + t_Error err = E_OK;
25734 + uint32_t tmpReg = 0, intFlags;
25735 +
25736 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25737 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25738 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
25739 +
25740 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25741 +
25742 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25743 +
25744 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
25745 +
25746 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25747 +
25748 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
25749 +
25750 + return err;
25751 +}
25752 +
25753 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
25754 +{
25755 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25756 + uint32_t bitMask;
25757 +
25758 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25759 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25760 +
25761 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
25762 + if (bitMask)
25763 + {
25764 + if (enable)
25765 + p_FmMacsec->exceptions |= bitMask;
25766 + else
25767 + p_FmMacsec->exceptions &= ~bitMask;
25768 + }
25769 + else
25770 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25771 +
25772 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
25773 +
25774 + return E_OK;
25775 +}
25776 +
25777 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
25778 +{
25779 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25780 + uint32_t bitMask;
25781 +
25782 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25783 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25784 +
25785 + GET_EVENT_FLAG(bitMask, event, scId);
25786 + if (bitMask)
25787 + {
25788 + if (enable)
25789 + p_FmMacsec->events |= bitMask;
25790 + else
25791 + p_FmMacsec->events &= ~bitMask;
25792 + }
25793 + else
25794 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25795 +
25796 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
25797 +
25798 + return E_OK;
25799 +}
25800 +
25801 +/****************************************/
25802 +/* API Init unit functions */
25803 +/****************************************/
25804 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
25805 +{
25806 + t_FmMacsec *p_FmMacsec;
25807 + uint32_t macId;
25808 +
25809 + /* Allocate FM MACSEC structure */
25810 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
25811 + if (!p_FmMacsec)
25812 + {
25813 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
25814 + return NULL;
25815 + }
25816 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
25817 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
25818 +
25819 + /* Allocate the FM MACSEC driver's parameters structure */
25820 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
25821 + if (!p_FmMacsec->p_FmMacsecDriverParam)
25822 + {
25823 + XX_Free(p_FmMacsec);
25824 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
25825 + return NULL;
25826 + }
25827 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
25828 +
25829 + /* Initialize FM MACSEC parameters which will be kept by the driver */
25830 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
25831 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
25832 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
25833 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
25834 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
25835 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
25836 + p_FmMacsec->exceptions = DEFAULT_exceptions;
25837 + p_FmMacsec->events = DEFAULT_events;
25838 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
25839 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
25840 +
25841 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
25842 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
25843 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
25844 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
25845 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
25846 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
25847 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
25848 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
25849 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
25850 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
25851 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
25852 + /* build the FM MACSEC master IPC address */
25853 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
25854 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
25855 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
25856 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
25857 + {
25858 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
25859 + XX_Free(p_FmMacsec);
25860 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
25861 + return NULL;
25862 + }
25863 + return p_FmMacsec;
25864 +}
25865 --- /dev/null
25866 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
25867 @@ -0,0 +1,479 @@
25868 +/*
25869 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25870 + *
25871 + * Redistribution and use in source and binary forms, with or without
25872 + * modification, are permitted provided that the following conditions are met:
25873 + * * Redistributions of source code must retain the above copyright
25874 + * notice, this list of conditions and the following disclaimer.
25875 + * * Redistributions in binary form must reproduce the above copyright
25876 + * notice, this list of conditions and the following disclaimer in the
25877 + * documentation and/or other materials provided with the distribution.
25878 + * * Neither the name of Freescale Semiconductor nor the
25879 + * names of its contributors may be used to endorse or promote products
25880 + * derived from this software without specific prior written permission.
25881 + *
25882 + *
25883 + * ALTERNATIVELY, this software may be distributed under the terms of the
25884 + * GNU General Public License ("GPL") as published by the Free Software
25885 + * Foundation, either version 2 of that License or (at your option) any
25886 + * later version.
25887 + *
25888 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25889 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25890 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25891 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25892 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25893 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25894 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25895 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25896 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25897 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25898 + */
25899 +
25900 +/******************************************************************************
25901 + @File fm_macsec_master.h
25902 +
25903 + @Description FM MACSEC internal structures and definitions.
25904 +*//***************************************************************************/
25905 +#ifndef __FM_MACSEC_MASTER_H
25906 +#define __FM_MACSEC_MASTER_H
25907 +
25908 +#include "error_ext.h"
25909 +#include "std_ext.h"
25910 +
25911 +#include "fm_macsec.h"
25912 +
25913 +
25914 +#define MACSEC_ICV_SIZE 16
25915 +#define MACSEC_SECTAG_SIZE 16
25916 +#define MACSEC_SCI_SIZE 8
25917 +#define MACSEC_FCS_SIZE 4
25918 +
25919 +/**************************************************************************//**
25920 + @Description Exceptions
25921 +*//***************************************************************************/
25922 +
25923 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
25924 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
25925 +#define FM_MACSEC_EX_ECC 0x00000001
25926 +
25927 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
25928 + case e_FM_MACSEC_EX_TX_SC: \
25929 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
25930 + case e_FM_MACSEC_EX_ECC: \
25931 + bitMask = FM_MACSEC_EX_ECC; break; \
25932 + default: bitMask = 0;break;}
25933 +
25934 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
25935 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
25936 +
25937 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25938 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
25939 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
25940 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
25941 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
25942 + default: bitMask = 0;break;}
25943 +
25944 +/**************************************************************************//**
25945 + @Description Events
25946 +*//***************************************************************************/
25947 +
25948 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
25949 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
25950 +
25951 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
25952 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
25953 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
25954 + default: bitMask = 0;break;}
25955 +
25956 +/**************************************************************************//**
25957 + @Description Defaults
25958 +*//***************************************************************************/
25959 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
25960 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
25961 +
25962 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
25963 + FM_MACSEC_EX_TX_SC(1) |\
25964 + FM_MACSEC_EX_TX_SC(2) |\
25965 + FM_MACSEC_EX_TX_SC(3) |\
25966 + FM_MACSEC_EX_TX_SC(4) |\
25967 + FM_MACSEC_EX_TX_SC(5) |\
25968 + FM_MACSEC_EX_TX_SC(6) |\
25969 + FM_MACSEC_EX_TX_SC(7) |\
25970 + FM_MACSEC_EX_TX_SC(8) |\
25971 + FM_MACSEC_EX_TX_SC(9) |\
25972 + FM_MACSEC_EX_TX_SC(10) |\
25973 + FM_MACSEC_EX_TX_SC(11) |\
25974 + FM_MACSEC_EX_TX_SC(12) |\
25975 + FM_MACSEC_EX_TX_SC(13) |\
25976 + FM_MACSEC_EX_TX_SC(14) |\
25977 + FM_MACSEC_EX_TX_SC(15) |\
25978 + FM_MACSEC_EX_ECC )
25979 +
25980 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
25981 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
25982 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
25983 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
25984 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
25985 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
25986 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
25987 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
25988 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
25989 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
25990 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
25991 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
25992 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
25993 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
25994 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
25995 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
25996 +
25997 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
25998 +#define DEFAULT_invalidTagsFrameTreatment FALSE
25999 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
26000 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
26001 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
26002 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
26003 +#define DEFAULT_keysUnreadable FALSE
26004 +#define DEFAULT_normalMode TRUE
26005 +#define DEFAULT_sc0ReservedForPTP FALSE
26006 +#define DEFAULT_initNextPn 1
26007 +#define DEFAULT_pnExhThr 0xffffffff
26008 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
26009 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
26010 +
26011 +
26012 +/**************************************************************************//**
26013 + @Description Memory Mapped Registers
26014 +*//***************************************************************************/
26015 +
26016 +#if defined(__MWERKS__) && !defined(__GNUC__)
26017 +#pragma pack(push,1)
26018 +#endif /* defined(__MWERKS__) && ... */
26019 +
26020 +typedef _Packed struct
26021 +{
26022 + /* MACsec configuration */
26023 + volatile uint32_t cfg; /**< MACsec configuration */
26024 + volatile uint32_t et; /**< MACsec EtherType */
26025 + volatile uint8_t res1[56]; /**< reserved */
26026 + volatile uint32_t mfl; /**< Maximum Frame Length */
26027 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
26028 + volatile uint8_t res2[56]; /**< reserved */
26029 + volatile uint32_t rxsca; /**< RX SC access select */
26030 + volatile uint8_t res3[60]; /**< reserved */
26031 + volatile uint32_t txsca; /**< TX SC access select */
26032 + volatile uint8_t res4[60]; /**< reserved */
26033 +
26034 + /* RX configuration, status and statistic */
26035 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
26036 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
26037 + volatile uint8_t res5[8]; /**< reserved */
26038 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
26039 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
26040 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
26041 + volatile uint8_t res6[4]; /**< reserved */
26042 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
26043 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
26044 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
26045 + volatile uint32_t rpw; /**< replayWindow */
26046 + volatile uint8_t res7[16]; /**< reserved */
26047 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
26048 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
26049 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
26050 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
26051 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
26052 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
26053 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
26054 + volatile uint8_t res8[4]; /**< reserved */
26055 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
26056 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
26057 + _Packed struct
26058 + {
26059 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
26060 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
26061 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
26062 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
26063 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
26064 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
26065 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
26066 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
26067 + volatile uint8_t res9[8]; /**< reserved */
26068 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
26069 +
26070 + /* TX configuration, status and statistic */
26071 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
26072 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
26073 + volatile uint8_t res10[8]; /**< reserved */
26074 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
26075 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
26076 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
26077 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
26078 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
26079 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
26080 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
26081 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
26082 + volatile uint8_t res11[16]; /**< reserved */
26083 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
26084 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
26085 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
26086 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
26087 + volatile uint8_t res12[48]; /**< reserved */
26088 + _Packed struct
26089 + {
26090 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
26091 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
26092 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
26093 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
26094 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
26095 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
26096 + volatile uint8_t res13[16]; /**< reserved */
26097 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
26098 + volatile uint8_t res14[248]; /**< reserved */
26099 +
26100 + /* Global configuration and status */
26101 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
26102 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
26103 + volatile uint32_t evr; /**< MACsec Event Register */
26104 + volatile uint32_t ever; /**< MACsec Event Enable Register */
26105 + volatile uint32_t evfr; /**< MACsec Event Force Register */
26106 + volatile uint32_t err; /**< MACsec Error Register */
26107 + volatile uint32_t erer; /**< MACsec Error Enable Register */
26108 + volatile uint32_t erfr; /**< MACsec Error Force Register */
26109 + volatile uint8_t res15[40]; /**< reserved */
26110 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
26111 + volatile uint32_t idle; /**< MACsec Idle status Register */
26112 + volatile uint8_t res16[184]; /**< reserved */
26113 + /* DEBUG */
26114 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
26115 + volatile uint8_t res17[28]; /**< reserved */
26116 + volatile uint32_t txec; /**< MACsec TX error capture Register */
26117 + volatile uint8_t res18[220]; /**< reserved */
26118 +
26119 + /* Macsec Rx global statistic */
26120 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
26121 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
26122 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
26123 + volatile uint8_t res19[4]; /**< reserved */
26124 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
26125 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
26126 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
26127 + volatile uint8_t res20[4]; /**< reserved */
26128 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
26129 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
26130 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
26131 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
26132 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
26133 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
26134 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
26135 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
26136 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
26137 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
26138 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
26139 + volatile uint8_t res21[52]; /**< reserved */
26140 +
26141 + /* Macsec Tx global statistic */
26142 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
26143 +#if (DPAA_VERSION >= 11)
26144 + volatile uint8_t res22[124]; /**< reserved */
26145 + _Packed struct
26146 + {
26147 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
26148 + volatile uint8_t res23[32]; /**< reserved */
26149 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
26150 + _Packed struct
26151 + {
26152 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
26153 + volatile uint8_t res24[32]; /**< reserved */
26154 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
26155 +#endif /* (DPAA_VERSION >= 11) */
26156 +} _PackedType t_FmMacsecRegs;
26157 +
26158 +#if defined(__MWERKS__) && !defined(__GNUC__)
26159 +#pragma pack(pop)
26160 +#endif /* defined(__MWERKS__) && ... */
26161 +
26162 +
26163 +/**************************************************************************//**
26164 + @Description General defines
26165 +*//***************************************************************************/
26166 +
26167 +#define SCI_HIGH_MASK 0xffffffff00000000LL
26168 +#define SCI_LOW_MASK 0x00000000ffffffffLL
26169 +
26170 +#define LONG_SHIFT 32
26171 +
26172 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
26173 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
26174 +
26175 +/**************************************************************************//**
26176 + @Description Configuration defines
26177 +*//***************************************************************************/
26178 +
26179 +/* masks */
26180 +#define CFG_UECT 0x00000800
26181 +#define CFG_ESCBT 0x00000400
26182 +#define CFG_USFT 0x00000300
26183 +#define CFG_ITT 0x00000080
26184 +#define CFG_KFT 0x00000040
26185 +#define CFG_UFT 0x00000030
26186 +#define CFG_KSS 0x00000004
26187 +#define CFG_BYPN 0x00000002
26188 +#define CFG_S0I 0x00000001
26189 +
26190 +#define ET_TYPE 0x0000ffff
26191 +
26192 +#define MFL_MAX_LEN 0x0000ffff
26193 +
26194 +#define RXSCA_SC_SEL 0x0000000f
26195 +
26196 +#define TXSCA_SC_SEL 0x0000000f
26197 +
26198 +#define IP_REV_1_IP_ID 0xffff0000
26199 +#define IP_REV_1_IP_MJ 0x0000ff00
26200 +#define IP_REV_1_IP_MM 0x000000ff
26201 +
26202 +#define IP_REV_2_IP_INT 0x00ff0000
26203 +#define IP_REV_2_IP_ERR 0x0000ff00
26204 +#define IP_REV_2_IP_CFG 0x000000ff
26205 +
26206 +#define MECC_CAP 0x80000000
26207 +#define MECC_CET 0x40000000
26208 +#define MECC_SERCNT 0x00ff0000
26209 +#define MECC_MEMADDR 0x000001ff
26210 +
26211 +/* shifts */
26212 +#define CFG_UECT_SHIFT (31-20)
26213 +#define CFG_ESCBT_SHIFT (31-21)
26214 +#define CFG_USFT_SHIFT (31-23)
26215 +#define CFG_ITT_SHIFT (31-24)
26216 +#define CFG_KFT_SHIFT (31-25)
26217 +#define CFG_UFT_SHIFT (31-27)
26218 +#define CFG_KSS_SHIFT (31-29)
26219 +#define CFG_BYPN_SHIFT (31-30)
26220 +#define CFG_S0I_SHIFT (31-31)
26221 +
26222 +#define IP_REV_1_IP_ID_SHIFT (31-15)
26223 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
26224 +#define IP_REV_1_IP_MM_SHIFT (31-31)
26225 +
26226 +#define IP_REV_2_IP_INT_SHIFT (31-15)
26227 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
26228 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
26229 +
26230 +#define MECC_CAP_SHIFT (31-0)
26231 +#define MECC_CET_SHIFT (31-1)
26232 +#define MECC_SERCNT_SHIFT (31-15)
26233 +#define MECC_MEMADDR_SHIFT (31-31)
26234 +
26235 +/**************************************************************************//**
26236 + @Description RX SC defines
26237 +*//***************************************************************************/
26238 +
26239 +/* masks */
26240 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
26241 +#define RX_SCCFG_RP_MASK 0x00000400
26242 +#define RX_SCCFG_VF_MASK 0x00000300
26243 +#define RX_SCCFG_CO_MASK 0x0000003f
26244 +
26245 +/* shifts */
26246 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
26247 +#define RX_SCCFG_RP_SHIFT (31-21)
26248 +#define RX_SCCFG_VF_SHIFT (31-23)
26249 +#define RX_SCCFG_CO_SHIFT (31-31)
26250 +#define RX_SCCFG_CS_SHIFT (31-7)
26251 +
26252 +/**************************************************************************//**
26253 + @Description RX SA defines
26254 +*//***************************************************************************/
26255 +
26256 +/* masks */
26257 +#define RX_SACFG_ACTIVE 0x80000000
26258 +#define RX_SACFG_AN_MASK 0x00000006
26259 +#define RX_SACFG_EN_MASK 0x00000001
26260 +
26261 +/* shifts */
26262 +#define RX_SACFG_AN_SHIFT (31-30)
26263 +#define RX_SACFG_EN_SHIFT (31-31)
26264 +
26265 +/**************************************************************************//**
26266 + @Description TX SC defines
26267 +*//***************************************************************************/
26268 +
26269 +/* masks */
26270 +#define TX_SCCFG_AN_MASK 0x000c0000
26271 +#define TX_SCCFG_ASA_MASK 0x00020000
26272 +#define TX_SCCFG_SCE_MASK 0x00010000
26273 +#define TX_SCCFG_CO_MASK 0x00003f00
26274 +#define TX_SCCFG_CE_MASK 0x00000010
26275 +#define TX_SCCFG_PF_MASK 0x00000008
26276 +#define TX_SCCFG_AIS_MASK 0x00000004
26277 +#define TX_SCCFG_UES_MASK 0x00000002
26278 +#define TX_SCCFG_USCB_MASK 0x00000001
26279 +
26280 +/* shifts */
26281 +#define TX_SCCFG_AN_SHIFT (31-13)
26282 +#define TX_SCCFG_ASA_SHIFT (31-14)
26283 +#define TX_SCCFG_SCE_SHIFT (31-15)
26284 +#define TX_SCCFG_CO_SHIFT (31-23)
26285 +#define TX_SCCFG_CE_SHIFT (31-27)
26286 +#define TX_SCCFG_PF_SHIFT (31-28)
26287 +#define TX_SCCFG_AIS_SHIFT (31-29)
26288 +#define TX_SCCFG_UES_SHIFT (31-30)
26289 +#define TX_SCCFG_USCB_SHIFT (31-31)
26290 +#define TX_SCCFG_CS_SHIFT (31-7)
26291 +
26292 +/**************************************************************************//**
26293 + @Description TX SA defines
26294 +*//***************************************************************************/
26295 +
26296 +/* masks */
26297 +#define TX_SACFG_ACTIVE 0x80000000
26298 +
26299 +
26300 +typedef struct
26301 +{
26302 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
26303 + t_Handle h_SrcHandle;
26304 +} t_FmMacsecIntrSrc;
26305 +
26306 +typedef struct
26307 +{
26308 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
26309 + bool invalidTagsDeliverUncontrolled;
26310 + bool changedTextWithNoEncryptDeliverUncontrolled;
26311 + bool onlyScbIsSetDeliverUncontrolled;
26312 + bool encryptWithNoChangedTextDiscardUncontrolled;
26313 + e_FmMacsecUntagFrameTreatment untagTreatMode;
26314 + uint32_t pnExhThr;
26315 + bool keysUnreadable;
26316 + bool byPassMode;
26317 + bool reservedSc0;
26318 + uint32_t sectagOverhead;
26319 + uint32_t mflSubtract;
26320 +} t_FmMacsecDriverParam;
26321 +
26322 +typedef struct
26323 +{
26324 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
26325 + t_Handle h_Fm;
26326 + t_FmMacsecRegs *p_FmMacsecRegs;
26327 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
26328 + char fmMacsecModuleName[MODULE_NAME_SIZE];
26329 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
26330 + uint32_t events;
26331 + uint32_t exceptions;
26332 + uint32_t userExceptions;
26333 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
26334 + t_Handle h_App; /**< A handle to an application layer object; This handle will
26335 + be passed by the driver upon calling the above callbacks */
26336 + bool rxScTable[NUM_OF_RX_SC];
26337 + uint32_t numRxScAvailable;
26338 + bool txScTable[NUM_OF_TX_SC];
26339 + uint32_t numTxScAvailable;
26340 + t_Handle rxScSpinLock;
26341 + t_Handle txScSpinLock;
26342 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
26343 +} t_FmMacsec;
26344 +
26345 +
26346 +#endif /* __FM_MACSEC_MASTER_H */
26347 --- /dev/null
26348 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
26349 @@ -0,0 +1,883 @@
26350 +/*
26351 + * Copyright 2008-2015 Freescale Semiconductor Inc.
26352 + *
26353 + * Redistribution and use in source and binary forms, with or without
26354 + * modification, are permitted provided that the following conditions are met:
26355 + * * Redistributions of source code must retain the above copyright
26356 + * notice, this list of conditions and the following disclaimer.
26357 + * * Redistributions in binary form must reproduce the above copyright
26358 + * notice, this list of conditions and the following disclaimer in the
26359 + * documentation and/or other materials provided with the distribution.
26360 + * * Neither the name of Freescale Semiconductor nor the
26361 + * names of its contributors may be used to endorse or promote products
26362 + * derived from this software without specific prior written permission.
26363 + *
26364 + *
26365 + * ALTERNATIVELY, this software may be distributed under the terms of the
26366 + * GNU General Public License ("GPL") as published by the Free Software
26367 + * Foundation, either version 2 of that License or (at your option) any
26368 + * later version.
26369 + *
26370 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26371 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26372 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26373 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26374 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26375 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26376 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26377 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26378 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26379 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26380 + */
26381 +
26382 +/******************************************************************************
26383 + @File fm_macsec_secy.c
26384 +
26385 + @Description FM MACSEC SECY driver routines implementation.
26386 +*//***************************************************************************/
26387 +
26388 +#include "std_ext.h"
26389 +#include "error_ext.h"
26390 +#include "xx_ext.h"
26391 +#include "string_ext.h"
26392 +#include "sprint_ext.h"
26393 +
26394 +#include "fm_macsec_secy.h"
26395 +
26396 +
26397 +/****************************************/
26398 +/* static functions */
26399 +/****************************************/
26400 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
26401 +{
26402 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26403 +
26404 + UNUSED(id);
26405 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
26406 +
26407 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
26408 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
26409 +}
26410 +
26411 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
26412 +{
26413 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26414 +
26415 + UNUSED(id);
26416 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
26417 +
26418 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
26419 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
26420 +}
26421 +
26422 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
26423 +{
26424 + if (!p_FmMacsecSecY->f_Exception)
26425 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
26426 +
26427 + if (!p_FmMacsecSecY->f_Event)
26428 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
26429 +
26430 + if (!p_FmMacsecSecY->numOfRxSc)
26431 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
26432 +
26433 +
26434 + return E_OK;
26435 +}
26436 +
26437 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
26438 + macsecSCI_t sci,
26439 + e_FmMacsecSecYCipherSuite cipherSuite,
26440 + e_ScType type)
26441 +{
26442 + t_SecYSc *p_ScTable;
26443 + void *p_Params;
26444 + uint32_t numOfSc,i;
26445 + t_Error err = E_OK;
26446 + t_RxScParams rxScParams;
26447 + t_TxScParams txScParams;
26448 +
26449 + ASSERT_COND(p_FmMacsecSecY);
26450 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
26451 +
26452 + if (type == e_SC_RX)
26453 + {
26454 + memset(&rxScParams, 0, sizeof(rxScParams));
26455 + i = (NUM_OF_RX_SC - 1);
26456 + p_ScTable = p_FmMacsecSecY->p_RxSc;
26457 + numOfSc = p_FmMacsecSecY->numOfRxSc;
26458 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
26459 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
26460 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
26461 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
26462 + rxScParams.cipherSuite = cipherSuite;
26463 + p_Params = &rxScParams;
26464 + }
26465 + else
26466 + {
26467 + memset(&txScParams, 0, sizeof(txScParams));
26468 + i = (NUM_OF_TX_SC - 1);
26469 + p_ScTable = p_FmMacsecSecY->p_TxSc;
26470 + numOfSc = p_FmMacsecSecY->numOfTxSc;
26471 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
26472 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
26473 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
26474 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
26475 + txScParams.cipherSuite = cipherSuite;
26476 + p_Params = &txScParams;
26477 + }
26478 +
26479 + for (i=0;i<numOfSc;i++)
26480 + if (!p_ScTable[i].inUse)
26481 + break;
26482 + if (i == numOfSc)
26483 + {
26484 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
26485 + return NULL;
26486 + }
26487 +
26488 + if (type == e_SC_RX)
26489 + {
26490 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
26491 + ((t_RxScParams *)p_Params)->sci = sci;
26492 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
26493 + {
26494 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
26495 + return NULL;
26496 + }
26497 + }
26498 + else
26499 + {
26500 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
26501 + ((t_TxScParams *)p_Params)->sci = sci;
26502 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
26503 + {
26504 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
26505 + return NULL;
26506 + }
26507 + }
26508 +
26509 + p_ScTable[i].inUse = TRUE;
26510 + return &p_ScTable[i];
26511 +}
26512 +
26513 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
26514 +{
26515 + t_Error err = E_OK;
26516 +
26517 + ASSERT_COND(p_FmMacsecSecY);
26518 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
26519 + ASSERT_COND(p_FmSecYSc);
26520 +
26521 + if (type == e_SC_RX)
26522 + {
26523 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
26524 + RETURN_ERROR(MINOR, err, NO_MSG);
26525 + }
26526 + else
26527 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
26528 + RETURN_ERROR(MINOR, err, NO_MSG);
26529 +
26530 + p_FmSecYSc->inUse = FALSE;
26531 +
26532 + return err;
26533 +}
26534 +
26535 +/****************************************/
26536 +/* API Init unit functions */
26537 +/****************************************/
26538 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
26539 +{
26540 + t_FmMacsecSecY *p_FmMacsecSecY;
26541 +
26542 + /* Allocate FM MACSEC structure */
26543 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
26544 + if (!p_FmMacsecSecY)
26545 + {
26546 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
26547 + return NULL;
26548 + }
26549 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
26550 +
26551 + /* Allocate the FM MACSEC driver's parameters structure */
26552 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
26553 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
26554 + {
26555 + XX_Free(p_FmMacsecSecY);
26556 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
26557 + return NULL;
26558 + }
26559 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
26560 +
26561 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
26562 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
26563 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
26564 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
26565 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
26566 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
26567 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
26568 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
26569 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
26570 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
26571 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
26572 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
26573 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
26574 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
26575 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
26576 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
26577 + p_FmMacsecSecY->events = DEFAULT_events;
26578 +
26579 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
26580 + &p_FmMacsecSecYParam->txScParams,
26581 + sizeof(t_FmMacsecSecYSCParams));
26582 + return p_FmMacsecSecY;
26583 +}
26584 +
26585 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
26586 +{
26587 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26588 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
26589 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
26590 + t_Error err;
26591 +
26592 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26593 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
26594 +
26595 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
26596 +
26597 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
26598 +
26599 + if ((p_FmMacsecSecY->isPointToPoint) &&
26600 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
26601 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
26602 +
26603 + /* Rx Sc Allocation */
26604 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
26605 + if (!p_FmMacsecSecY->p_RxSc)
26606 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
26607 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
26608 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
26609 + {
26610 + if (p_FmMacsecSecY->p_TxSc)
26611 + XX_Free(p_FmMacsecSecY->p_TxSc);
26612 + if (p_FmMacsecSecY->p_RxSc)
26613 + XX_Free(p_FmMacsecSecY->p_RxSc);
26614 + return ERROR_CODE(err);
26615 + }
26616 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
26617 + {
26618 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
26619 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
26620 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
26621 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
26622 + }
26623 +
26624 + /* Tx Sc Allocation */
26625 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
26626 + if (!p_FmMacsecSecY->p_TxSc)
26627 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
26628 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
26629 +
26630 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
26631 + {
26632 + if (p_FmMacsecSecY->p_TxSc)
26633 + XX_Free(p_FmMacsecSecY->p_TxSc);
26634 + if (p_FmMacsecSecY->p_RxSc)
26635 + XX_Free(p_FmMacsecSecY->p_RxSc);
26636 + return ERROR_CODE(err);
26637 + }
26638 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
26639 + {
26640 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
26641 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
26642 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
26643 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
26644 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
26645 + e_FM_MACSEC_MOD_SC_TX,
26646 + (uint8_t)txScIds[i],
26647 + e_FM_INTR_TYPE_ERR,
26648 + FmMacsecSecYExceptionsIsr,
26649 + p_FmMacsecSecY);
26650 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
26651 + e_FM_MACSEC_MOD_SC_TX,
26652 + (uint8_t)txScIds[i],
26653 + e_FM_INTR_TYPE_NORMAL,
26654 + FmMacsecSecYEventsIsr,
26655 + p_FmMacsecSecY);
26656 +
26657 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
26658 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
26659 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
26660 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
26661 + }
26662 +
26663 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
26664 + p_FmMacsecSecYDriverParam->txScParams.sci,
26665 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
26666 + e_SC_TX);
26667 + XX_Free(p_FmMacsecSecYDriverParam);
26668 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
26669 +
26670 + return E_OK;
26671 +}
26672 +
26673 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
26674 +{
26675 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26676 + t_Error err = E_OK;
26677 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
26678 +
26679 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26680 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26681 +
26682 + if (p_FmMacsecSecY->isPointToPoint)
26683 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
26684 + if (p_FmMacsecSecY->p_RxSc)
26685 + {
26686 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
26687 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
26688 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
26689 + return ERROR_CODE(err);
26690 + XX_Free(p_FmMacsecSecY->p_RxSc);
26691 + }
26692 + if (p_FmMacsecSecY->p_TxSc)
26693 + {
26694 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
26695 +
26696 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
26697 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
26698 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
26699 + e_FM_MACSEC_MOD_SC_TX,
26700 + (uint8_t)txScIds[i],
26701 + e_FM_INTR_TYPE_ERR);
26702 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
26703 + e_FM_MACSEC_MOD_SC_TX,
26704 + (uint8_t)txScIds[i],
26705 + e_FM_INTR_TYPE_NORMAL);
26706 +
26707 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
26708 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
26709 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
26710 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
26711 + }
26712 +
26713 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
26714 + return ERROR_CODE(err);
26715 + XX_Free(p_FmMacsecSecY->p_TxSc);
26716 + }
26717 +
26718 + XX_Free(p_FmMacsecSecY);
26719 +
26720 + return err;
26721 +}
26722 +
26723 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
26724 +{
26725 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26726 +
26727 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26728 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26729 +
26730 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
26731 +
26732 + return E_OK;
26733 +}
26734 +
26735 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
26736 +{
26737 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26738 +
26739 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26740 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26741 +
26742 + p_FmMacsecSecY->protectFrames = protectFrames;
26743 +
26744 + return E_OK;
26745 +}
26746 +
26747 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
26748 +{
26749 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26750 +
26751 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26752 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26753 +
26754 + p_FmMacsecSecY->replayProtect = replayProtect;
26755 + p_FmMacsecSecY->replayWindow = replayWindow;
26756 +
26757 + return E_OK;
26758 +}
26759 +
26760 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
26761 +{
26762 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26763 +
26764 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26765 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26766 +
26767 + p_FmMacsecSecY->validateFrames = validateFrames;
26768 +
26769 + return E_OK;
26770 +}
26771 +
26772 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
26773 +{
26774 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26775 +
26776 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26777 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26778 +
26779 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
26780 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
26781 +
26782 + return E_OK;
26783 +}
26784 +
26785 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
26786 +{
26787 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26788 +
26789 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26790 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26791 +
26792 + p_FmMacsecSecY->numOfRxSc = 1;
26793 + p_FmMacsecSecY->isPointToPoint = TRUE;
26794 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
26795 +
26796 + return E_OK;
26797 +}
26798 +
26799 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
26800 +{
26801 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26802 + uint32_t bitMask = 0;
26803 +
26804 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26805 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26806 +
26807 + GET_EXCEPTION_FLAG(bitMask, exception);
26808 + if (bitMask)
26809 + {
26810 + if (enable)
26811 + p_FmMacsecSecY->exceptions |= bitMask;
26812 + else
26813 + p_FmMacsecSecY->exceptions &= ~bitMask;
26814 + }
26815 + else
26816 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
26817 +
26818 + return E_OK;
26819 +}
26820 +
26821 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
26822 +{
26823 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26824 + uint32_t bitMask = 0;
26825 +
26826 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26827 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26828 +
26829 + GET_EVENT_FLAG(bitMask, event);
26830 + if (bitMask)
26831 + {
26832 + if (enable)
26833 + p_FmMacsecSecY->events |= bitMask;
26834 + else
26835 + p_FmMacsecSecY->events &= ~bitMask;
26836 + }
26837 + else
26838 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
26839 +
26840 + return E_OK;
26841 +}
26842 +
26843 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
26844 +{
26845 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26846 +
26847 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
26848 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
26849 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
26850 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
26851 +
26852 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
26853 +}
26854 +
26855 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
26856 +{
26857 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26858 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26859 +
26860 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26861 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26862 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26863 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26864 +
26865 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
26866 +}
26867 +
26868 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
26869 +{
26870 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26871 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26872 + t_Error err = E_OK;
26873 +
26874 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26875 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26876 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26877 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26878 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
26879 +
26880 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
26881 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
26882 +
26883 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
26884 + RETURN_ERROR(MINOR, err, NO_MSG);
26885 +
26886 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
26887 + return err;
26888 +}
26889 +
26890 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
26891 +{
26892 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26893 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26894 + t_Error err = E_OK;
26895 +
26896 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26897 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26898 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26899 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26900 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
26901 +
26902 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
26903 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
26904 +
26905 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
26906 + RETURN_ERROR(MINOR, err, NO_MSG);
26907 +
26908 + p_FmSecYSc->numOfSa--;
26909 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
26910 + /* TODO - check if statistics need to be read*/
26911 + return err;
26912 +}
26913 +
26914 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
26915 +{
26916 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26917 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26918 + t_Error err = E_OK;
26919 +
26920 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26921 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26922 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26923 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26924 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
26925 +
26926 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
26927 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
26928 +
26929 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
26930 + RETURN_ERROR(MINOR, err, NO_MSG);
26931 +
26932 + p_FmSecYSc->sa[an].active = TRUE;
26933 + return err;
26934 +}
26935 +
26936 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
26937 +{
26938 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26939 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26940 + t_Error err = E_OK;
26941 +
26942 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26943 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26944 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26945 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26946 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
26947 +
26948 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
26949 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
26950 +
26951 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
26952 + RETURN_ERROR(MINOR, err, NO_MSG);
26953 +
26954 + p_FmSecYSc->sa[an].active = FALSE;
26955 + return err;
26956 +}
26957 +
26958 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
26959 +{
26960 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26961 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26962 + t_Error err = E_OK;
26963 +
26964 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26965 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26966 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26967 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26968 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
26969 +
26970 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
26971 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
26972 +
26973 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
26974 + RETURN_ERROR(MINOR, err, NO_MSG);
26975 +
26976 + return err;
26977 +}
26978 +
26979 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
26980 +{
26981 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26982 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
26983 + t_Error err = E_OK;
26984 +
26985 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26986 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
26987 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
26988 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
26989 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
26990 +
26991 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
26992 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
26993 +
26994 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
26995 + RETURN_ERROR(MINOR, err, NO_MSG);
26996 +
26997 + return err;
26998 +}
26999 +
27000 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
27001 +{
27002 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27003 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27004 + t_Error err = E_OK;
27005 +
27006 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27007 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27008 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27009 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27010 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27011 +
27012 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27013 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27014 +
27015 + if (p_FmSecYSc->sa[an].active)
27016 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
27017 + RETURN_ERROR(MINOR, err, NO_MSG);
27018 +
27019 + /* TODO - statistics should be read */
27020 +
27021 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
27022 + RETURN_ERROR(MINOR, err, NO_MSG);
27023 +
27024 + if (p_FmSecYSc->sa[an].active)
27025 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
27026 + RETURN_ERROR(MINOR, err, NO_MSG);
27027 + return err;
27028 +}
27029 +
27030 +
27031 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
27032 +{
27033 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27034 + t_SecYSc *p_FmSecYSc;
27035 + t_Error err = E_OK;
27036 +
27037 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27038 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27039 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27040 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27041 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27042 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27043 +
27044 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
27045 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
27046 +
27047 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
27048 + RETURN_ERROR(MINOR, err, NO_MSG);
27049 +
27050 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
27051 + return err;
27052 +}
27053 +
27054 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
27055 +{
27056 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27057 + t_SecYSc *p_FmSecYSc;
27058 + t_Error err = E_OK;
27059 +
27060 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27061 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27062 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27063 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27064 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27065 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27066 +
27067 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27068 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
27069 +
27070 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
27071 + RETURN_ERROR(MINOR, err, NO_MSG);
27072 +
27073 + p_FmSecYSc->numOfSa--;
27074 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
27075 + /* TODO - check if statistics need to be read*/
27076 + return err;
27077 +}
27078 +
27079 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
27080 +{
27081 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27082 + t_SecYSc *p_FmSecYSc;
27083 + macsecAN_t currentAn;
27084 + t_Error err = E_OK;
27085 +
27086 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27087 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27088 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27089 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27090 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27091 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27092 +
27093 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
27094 + p_FmSecYSc->scId,
27095 + &currentAn)) != E_OK)
27096 + RETURN_ERROR(MINOR, err, NO_MSG);
27097 +
27098 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
27099 + p_FmSecYSc->scId,
27100 + p_FmSecYSc->sa[nextActiveAn].saId,
27101 + nextActiveAn)) != E_OK)
27102 + RETURN_ERROR(MINOR, err, NO_MSG);
27103 +
27104 + /* TODO - statistics should be read */
27105 +
27106 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
27107 + RETURN_ERROR(MINOR, err, NO_MSG);
27108 +
27109 + return err;
27110 +}
27111 +
27112 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
27113 +{
27114 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27115 + t_SecYSc *p_FmSecYSc;
27116 + t_Error err = E_OK;
27117 +
27118 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27119 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27120 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27121 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27122 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27123 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27124 +
27125 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27126 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27127 +
27128 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
27129 + p_FmSecYSc->scId,
27130 + p_FmSecYSc->sa[an].saId,
27131 + an)) != E_OK)
27132 + RETURN_ERROR(MINOR, err, NO_MSG);
27133 +
27134 + return err;
27135 +}
27136 +
27137 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
27138 +{
27139 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27140 + t_SecYSc *p_FmSecYSc;
27141 + t_Error err = E_OK;
27142 +
27143 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27144 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27145 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27146 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27147 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27148 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
27149 +
27150 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
27151 + p_FmSecYSc->scId,
27152 + p_An)) != E_OK)
27153 + RETURN_ERROR(MINOR, err, NO_MSG);
27154 +
27155 + return err;
27156 +}
27157 +
27158 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
27159 +{
27160 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27161 + t_Error err = E_OK;
27162 +
27163 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
27164 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
27165 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27166 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27167 +#ifdef DISABLE_SANITY_CHECKS
27168 + UNUSED(h_FmMacsecSecY);
27169 +#endif /* DISABLE_SANITY_CHECKS */
27170 +
27171 + *p_ScPhysId = p_FmSecYSc->scId;
27172 + return err;
27173 +}
27174 +
27175 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
27176 +{
27177 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27178 + t_SecYSc *p_FmSecYSc;
27179 + t_Error err = E_OK;
27180 +
27181 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27182 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27183 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27184 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27185 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27186 +
27187 + *p_ScPhysId = p_FmSecYSc->scId;
27188 + return err;
27189 +}
27190 +
27191 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
27192 +{
27193 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
27194 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27195 +}
27196 +
27197 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
27198 +{
27199 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
27200 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27201 +}
27202 +
27203 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
27204 +{
27205 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
27206 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27207 +}
27208 +
27209 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
27210 +{
27211 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
27212 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27213 +}
27214 +
27215 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
27216 +{
27217 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
27218 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27219 +}
27220 +
27221 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
27222 +{
27223 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
27224 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27225 +}
27226 +
27227 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
27228 +{
27229 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
27230 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27231 +}
27232 +
27233 --- /dev/null
27234 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
27235 @@ -0,0 +1,144 @@
27236 +/*
27237 + * Copyright 2008-2015 Freescale Semiconductor Inc.
27238 + *
27239 + * Redistribution and use in source and binary forms, with or without
27240 + * modification, are permitted provided that the following conditions are met:
27241 + * * Redistributions of source code must retain the above copyright
27242 + * notice, this list of conditions and the following disclaimer.
27243 + * * Redistributions in binary form must reproduce the above copyright
27244 + * notice, this list of conditions and the following disclaimer in the
27245 + * documentation and/or other materials provided with the distribution.
27246 + * * Neither the name of Freescale Semiconductor nor the
27247 + * names of its contributors may be used to endorse or promote products
27248 + * derived from this software without specific prior written permission.
27249 + *
27250 + *
27251 + * ALTERNATIVELY, this software may be distributed under the terms of the
27252 + * GNU General Public License ("GPL") as published by the Free Software
27253 + * Foundation, either version 2 of that License or (at your option) any
27254 + * later version.
27255 + *
27256 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
27257 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27258 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27259 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27260 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27261 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27262 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27263 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27264 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27265 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27266 + */
27267 +
27268 +/******************************************************************************
27269 + @File fm_macsec_secy.h
27270 +
27271 + @Description FM MACSEC SecY internal structures and definitions.
27272 +*//***************************************************************************/
27273 +#ifndef __FM_MACSEC_SECY_H
27274 +#define __FM_MACSEC_SECY_H
27275 +
27276 +#include "error_ext.h"
27277 +#include "std_ext.h"
27278 +
27279 +#include "fm_macsec.h"
27280 +
27281 +
27282 +/**************************************************************************//**
27283 + @Description Exceptions
27284 +*//***************************************************************************/
27285 +
27286 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
27287 +
27288 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
27289 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
27290 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
27291 + default: bitMask = 0;break;}
27292 +
27293 +/**************************************************************************//**
27294 + @Description Events
27295 +*//***************************************************************************/
27296 +
27297 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
27298 +
27299 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
27300 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
27301 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
27302 + default: bitMask = 0;break;}
27303 +
27304 +/**************************************************************************//**
27305 + @Description Defaults
27306 +*//***************************************************************************/
27307 +
27308 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
27309 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
27310 +#define DEFAULT_numOfTxSc 1
27311 +#define DEFAULT_confidentialityEnable FALSE
27312 +#define DEFAULT_confidentialityOffset 0
27313 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
27314 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
27315 +#define DEFAULT_replayEnable FALSE
27316 +#define DEFAULT_replayWindow 0
27317 +#define DEFAULT_protectFrames TRUE
27318 +#define DEFAULT_ptp FALSE
27319 +
27320 +/**************************************************************************//**
27321 + @Description General defines
27322 +*//***************************************************************************/
27323 +
27324 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
27325 +
27326 +
27327 +typedef struct {
27328 + e_ScSaId saId;
27329 + bool active;
27330 + union {
27331 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
27332 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
27333 + };
27334 +} t_SecYSa;
27335 +
27336 +typedef struct {
27337 + bool inUse;
27338 + uint32_t scId;
27339 + e_ScType type;
27340 + uint8_t numOfSa;
27341 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
27342 + union {
27343 + t_FmMacsecSecYRxScStatistics rxScStatistics;
27344 + t_FmMacsecSecYTxScStatistics txScStatistics;
27345 + };
27346 +} t_SecYSc;
27347 +
27348 +typedef struct {
27349 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
27350 +} t_FmMacsecSecYDriverParam;
27351 +
27352 +typedef struct {
27353 + t_Handle h_FmMacsec;
27354 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
27355 + FALSE - no confidentiality protection, only integrity protection*/
27356 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
27357 + common values are 0, 30, and 50 */
27358 + bool replayProtect; /**< replay protection function mode */
27359 + uint32_t replayWindow; /**< the size of the replay window */
27360 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
27361 + e_FmMacsecSciInsertionMode sciInsertionMode;
27362 + bool protectFrames;
27363 + bool isPointToPoint;
27364 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
27365 + uint32_t numOfRxSc; /**< Number of receive channels */
27366 + uint32_t numOfTxSc; /**< Number of transmit channels */
27367 + t_SecYSc *p_RxSc;
27368 + t_SecYSc *p_TxSc;
27369 + uint32_t events;
27370 + uint32_t exceptions;
27371 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
27372 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
27373 + t_Handle h_App;
27374 + t_FmMacsecSecYStatistics statistics;
27375 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
27376 +} t_FmMacsecSecY;
27377 +
27378 +
27379 +#endif /* __FM_MACSEC_SECY_H */
27380 --- /dev/null
27381 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
27382 @@ -0,0 +1,23 @@
27383 +#
27384 +# Makefile for the Freescale Ethernet controllers
27385 +#
27386 +ccflags-y += -DVERSION=\"\"
27387 +#
27388 +#Include netcomm SW specific definitions
27389 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
27390 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
27391 +
27392 +ccflags-y += -I$(NCSW_FM_INC)
27393 +
27394 +
27395 +obj-y += fsl-ncsw-PFM1.o
27396 +
27397 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
27398 +
27399 +obj-y += MAC/
27400 +obj-y += Pcd/
27401 +obj-y += SP/
27402 +obj-y += Port/
27403 +obj-y += HC/
27404 +obj-y += Rtc/
27405 +obj-y += MACSEC/
27406 --- /dev/null
27407 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
27408 @@ -0,0 +1,26 @@
27409 +#
27410 +# Makefile for the Freescale Ethernet controllers
27411 +#
27412 +ccflags-y += -DVERSION=\"\"
27413 +#
27414 +#Include netcomm SW specific definitions
27415 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
27416 +
27417 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
27418 +
27419 +ccflags-y += -I$(NCSW_FM_INC)
27420 +
27421 +obj-y += fsl-ncsw-Pcd.o
27422 +
27423 +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
27424 +
27425 +ifeq ($(CONFIG_FMAN_V3H),y)
27426 +fsl-ncsw-Pcd-objs += fm_replic.o
27427 +endif
27428 +ifeq ($(CONFIG_FMAN_V3L),y)
27429 +fsl-ncsw-Pcd-objs += fm_replic.o
27430 +endif
27431 +ifeq ($(CONFIG_FMAN_ARM),y)
27432 +fsl-ncsw-Pcd-objs += fm_replic.o
27433 +endif
27434 +
27435 --- /dev/null
27436 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
27437 @@ -0,0 +1,360 @@
27438 +/*
27439 + * Copyright 2008-2012 Freescale Semiconductor Inc.
27440 + *
27441 + * Redistribution and use in source and binary forms, with or without
27442 + * modification, are permitted provided that the following conditions are met:
27443 + * * Redistributions of source code must retain the above copyright
27444 + * notice, this list of conditions and the following disclaimer.
27445 + * * Redistributions in binary form must reproduce the above copyright
27446 + * notice, this list of conditions and the following disclaimer in the
27447 + * documentation and/or other materials provided with the distribution.
27448 + * * Neither the name of Freescale Semiconductor nor the
27449 + * names of its contributors may be used to endorse or promote products
27450 + * derived from this software without specific prior written permission.
27451 + *
27452 + *
27453 + * ALTERNATIVELY, this software may be distributed under the terms of the
27454 + * GNU General Public License ("GPL") as published by the Free Software
27455 + * Foundation, either version 2 of that License or (at your option) any
27456 + * later version.
27457 + *
27458 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
27459 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27460 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27461 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27462 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27463 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27464 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27465 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27466 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27467 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27468 + */
27469 +
27470 +
27471 + /**************************************************************************//**
27472 + @File crc64.h
27473 +
27474 + @Description brief This file contains the CRC64 Table, and __inline__
27475 + functions used for calculating crc.
27476 +*//***************************************************************************/
27477 +#ifndef __CRC64_H
27478 +#define __CRC64_H
27479 +
27480 +#include "std_ext.h"
27481 +
27482 +
27483 +#define BITS_PER_BYTE 8
27484 +
27485 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
27486 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
27487 +
27488 +#define CRC64_BYTE_MASK 0xFF
27489 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
27490 +#define CRC64_ODD_MASK 1
27491 +
27492 +
27493 +/**
27494 + \brief '64 bit crc' Table
27495 + */
27496 +struct crc64_t {
27497 + uint64_t initial; /**< Initial seed */
27498 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
27499 +};
27500 +
27501 +
27502 +static struct crc64_t CRC64_ECMA_182 = {
27503 + CRC64_DEFAULT_INITVAL,
27504 + {
27505 + 0x0000000000000000ULL,
27506 + 0xb32e4cbe03a75f6fULL,
27507 + 0xf4843657a840a05bULL,
27508 + 0x47aa7ae9abe7ff34ULL,
27509 + 0x7bd0c384ff8f5e33ULL,
27510 + 0xc8fe8f3afc28015cULL,
27511 + 0x8f54f5d357cffe68ULL,
27512 + 0x3c7ab96d5468a107ULL,
27513 + 0xf7a18709ff1ebc66ULL,
27514 + 0x448fcbb7fcb9e309ULL,
27515 + 0x0325b15e575e1c3dULL,
27516 + 0xb00bfde054f94352ULL,
27517 + 0x8c71448d0091e255ULL,
27518 + 0x3f5f08330336bd3aULL,
27519 + 0x78f572daa8d1420eULL,
27520 + 0xcbdb3e64ab761d61ULL,
27521 + 0x7d9ba13851336649ULL,
27522 + 0xceb5ed8652943926ULL,
27523 + 0x891f976ff973c612ULL,
27524 + 0x3a31dbd1fad4997dULL,
27525 + 0x064b62bcaebc387aULL,
27526 + 0xb5652e02ad1b6715ULL,
27527 + 0xf2cf54eb06fc9821ULL,
27528 + 0x41e11855055bc74eULL,
27529 + 0x8a3a2631ae2dda2fULL,
27530 + 0x39146a8fad8a8540ULL,
27531 + 0x7ebe1066066d7a74ULL,
27532 + 0xcd905cd805ca251bULL,
27533 + 0xf1eae5b551a2841cULL,
27534 + 0x42c4a90b5205db73ULL,
27535 + 0x056ed3e2f9e22447ULL,
27536 + 0xb6409f5cfa457b28ULL,
27537 + 0xfb374270a266cc92ULL,
27538 + 0x48190ecea1c193fdULL,
27539 + 0x0fb374270a266cc9ULL,
27540 + 0xbc9d3899098133a6ULL,
27541 + 0x80e781f45de992a1ULL,
27542 + 0x33c9cd4a5e4ecdceULL,
27543 + 0x7463b7a3f5a932faULL,
27544 + 0xc74dfb1df60e6d95ULL,
27545 + 0x0c96c5795d7870f4ULL,
27546 + 0xbfb889c75edf2f9bULL,
27547 + 0xf812f32ef538d0afULL,
27548 + 0x4b3cbf90f69f8fc0ULL,
27549 + 0x774606fda2f72ec7ULL,
27550 + 0xc4684a43a15071a8ULL,
27551 + 0x83c230aa0ab78e9cULL,
27552 + 0x30ec7c140910d1f3ULL,
27553 + 0x86ace348f355aadbULL,
27554 + 0x3582aff6f0f2f5b4ULL,
27555 + 0x7228d51f5b150a80ULL,
27556 + 0xc10699a158b255efULL,
27557 + 0xfd7c20cc0cdaf4e8ULL,
27558 + 0x4e526c720f7dab87ULL,
27559 + 0x09f8169ba49a54b3ULL,
27560 + 0xbad65a25a73d0bdcULL,
27561 + 0x710d64410c4b16bdULL,
27562 + 0xc22328ff0fec49d2ULL,
27563 + 0x85895216a40bb6e6ULL,
27564 + 0x36a71ea8a7ace989ULL,
27565 + 0x0adda7c5f3c4488eULL,
27566 + 0xb9f3eb7bf06317e1ULL,
27567 + 0xfe5991925b84e8d5ULL,
27568 + 0x4d77dd2c5823b7baULL,
27569 + 0x64b62bcaebc387a1ULL,
27570 + 0xd7986774e864d8ceULL,
27571 + 0x90321d9d438327faULL,
27572 + 0x231c512340247895ULL,
27573 + 0x1f66e84e144cd992ULL,
27574 + 0xac48a4f017eb86fdULL,
27575 + 0xebe2de19bc0c79c9ULL,
27576 + 0x58cc92a7bfab26a6ULL,
27577 + 0x9317acc314dd3bc7ULL,
27578 + 0x2039e07d177a64a8ULL,
27579 + 0x67939a94bc9d9b9cULL,
27580 + 0xd4bdd62abf3ac4f3ULL,
27581 + 0xe8c76f47eb5265f4ULL,
27582 + 0x5be923f9e8f53a9bULL,
27583 + 0x1c4359104312c5afULL,
27584 + 0xaf6d15ae40b59ac0ULL,
27585 + 0x192d8af2baf0e1e8ULL,
27586 + 0xaa03c64cb957be87ULL,
27587 + 0xeda9bca512b041b3ULL,
27588 + 0x5e87f01b11171edcULL,
27589 + 0x62fd4976457fbfdbULL,
27590 + 0xd1d305c846d8e0b4ULL,
27591 + 0x96797f21ed3f1f80ULL,
27592 + 0x2557339fee9840efULL,
27593 + 0xee8c0dfb45ee5d8eULL,
27594 + 0x5da24145464902e1ULL,
27595 + 0x1a083bacedaefdd5ULL,
27596 + 0xa9267712ee09a2baULL,
27597 + 0x955cce7fba6103bdULL,
27598 + 0x267282c1b9c65cd2ULL,
27599 + 0x61d8f8281221a3e6ULL,
27600 + 0xd2f6b4961186fc89ULL,
27601 + 0x9f8169ba49a54b33ULL,
27602 + 0x2caf25044a02145cULL,
27603 + 0x6b055fede1e5eb68ULL,
27604 + 0xd82b1353e242b407ULL,
27605 + 0xe451aa3eb62a1500ULL,
27606 + 0x577fe680b58d4a6fULL,
27607 + 0x10d59c691e6ab55bULL,
27608 + 0xa3fbd0d71dcdea34ULL,
27609 + 0x6820eeb3b6bbf755ULL,
27610 + 0xdb0ea20db51ca83aULL,
27611 + 0x9ca4d8e41efb570eULL,
27612 + 0x2f8a945a1d5c0861ULL,
27613 + 0x13f02d374934a966ULL,
27614 + 0xa0de61894a93f609ULL,
27615 + 0xe7741b60e174093dULL,
27616 + 0x545a57dee2d35652ULL,
27617 + 0xe21ac88218962d7aULL,
27618 + 0x5134843c1b317215ULL,
27619 + 0x169efed5b0d68d21ULL,
27620 + 0xa5b0b26bb371d24eULL,
27621 + 0x99ca0b06e7197349ULL,
27622 + 0x2ae447b8e4be2c26ULL,
27623 + 0x6d4e3d514f59d312ULL,
27624 + 0xde6071ef4cfe8c7dULL,
27625 + 0x15bb4f8be788911cULL,
27626 + 0xa6950335e42fce73ULL,
27627 + 0xe13f79dc4fc83147ULL,
27628 + 0x521135624c6f6e28ULL,
27629 + 0x6e6b8c0f1807cf2fULL,
27630 + 0xdd45c0b11ba09040ULL,
27631 + 0x9aefba58b0476f74ULL,
27632 + 0x29c1f6e6b3e0301bULL,
27633 + 0xc96c5795d7870f42ULL,
27634 + 0x7a421b2bd420502dULL,
27635 + 0x3de861c27fc7af19ULL,
27636 + 0x8ec62d7c7c60f076ULL,
27637 + 0xb2bc941128085171ULL,
27638 + 0x0192d8af2baf0e1eULL,
27639 + 0x4638a2468048f12aULL,
27640 + 0xf516eef883efae45ULL,
27641 + 0x3ecdd09c2899b324ULL,
27642 + 0x8de39c222b3eec4bULL,
27643 + 0xca49e6cb80d9137fULL,
27644 + 0x7967aa75837e4c10ULL,
27645 + 0x451d1318d716ed17ULL,
27646 + 0xf6335fa6d4b1b278ULL,
27647 + 0xb199254f7f564d4cULL,
27648 + 0x02b769f17cf11223ULL,
27649 + 0xb4f7f6ad86b4690bULL,
27650 + 0x07d9ba1385133664ULL,
27651 + 0x4073c0fa2ef4c950ULL,
27652 + 0xf35d8c442d53963fULL,
27653 + 0xcf273529793b3738ULL,
27654 + 0x7c0979977a9c6857ULL,
27655 + 0x3ba3037ed17b9763ULL,
27656 + 0x888d4fc0d2dcc80cULL,
27657 + 0x435671a479aad56dULL,
27658 + 0xf0783d1a7a0d8a02ULL,
27659 + 0xb7d247f3d1ea7536ULL,
27660 + 0x04fc0b4dd24d2a59ULL,
27661 + 0x3886b22086258b5eULL,
27662 + 0x8ba8fe9e8582d431ULL,
27663 + 0xcc0284772e652b05ULL,
27664 + 0x7f2cc8c92dc2746aULL,
27665 + 0x325b15e575e1c3d0ULL,
27666 + 0x8175595b76469cbfULL,
27667 + 0xc6df23b2dda1638bULL,
27668 + 0x75f16f0cde063ce4ULL,
27669 + 0x498bd6618a6e9de3ULL,
27670 + 0xfaa59adf89c9c28cULL,
27671 + 0xbd0fe036222e3db8ULL,
27672 + 0x0e21ac88218962d7ULL,
27673 + 0xc5fa92ec8aff7fb6ULL,
27674 + 0x76d4de52895820d9ULL,
27675 + 0x317ea4bb22bfdfedULL,
27676 + 0x8250e80521188082ULL,
27677 + 0xbe2a516875702185ULL,
27678 + 0x0d041dd676d77eeaULL,
27679 + 0x4aae673fdd3081deULL,
27680 + 0xf9802b81de97deb1ULL,
27681 + 0x4fc0b4dd24d2a599ULL,
27682 + 0xfceef8632775faf6ULL,
27683 + 0xbb44828a8c9205c2ULL,
27684 + 0x086ace348f355aadULL,
27685 + 0x34107759db5dfbaaULL,
27686 + 0x873e3be7d8faa4c5ULL,
27687 + 0xc094410e731d5bf1ULL,
27688 + 0x73ba0db070ba049eULL,
27689 + 0xb86133d4dbcc19ffULL,
27690 + 0x0b4f7f6ad86b4690ULL,
27691 + 0x4ce50583738cb9a4ULL,
27692 + 0xffcb493d702be6cbULL,
27693 + 0xc3b1f050244347ccULL,
27694 + 0x709fbcee27e418a3ULL,
27695 + 0x3735c6078c03e797ULL,
27696 + 0x841b8ab98fa4b8f8ULL,
27697 + 0xadda7c5f3c4488e3ULL,
27698 + 0x1ef430e13fe3d78cULL,
27699 + 0x595e4a08940428b8ULL,
27700 + 0xea7006b697a377d7ULL,
27701 + 0xd60abfdbc3cbd6d0ULL,
27702 + 0x6524f365c06c89bfULL,
27703 + 0x228e898c6b8b768bULL,
27704 + 0x91a0c532682c29e4ULL,
27705 + 0x5a7bfb56c35a3485ULL,
27706 + 0xe955b7e8c0fd6beaULL,
27707 + 0xaeffcd016b1a94deULL,
27708 + 0x1dd181bf68bdcbb1ULL,
27709 + 0x21ab38d23cd56ab6ULL,
27710 + 0x9285746c3f7235d9ULL,
27711 + 0xd52f0e859495caedULL,
27712 + 0x6601423b97329582ULL,
27713 + 0xd041dd676d77eeaaULL,
27714 + 0x636f91d96ed0b1c5ULL,
27715 + 0x24c5eb30c5374ef1ULL,
27716 + 0x97eba78ec690119eULL,
27717 + 0xab911ee392f8b099ULL,
27718 + 0x18bf525d915feff6ULL,
27719 + 0x5f1528b43ab810c2ULL,
27720 + 0xec3b640a391f4fadULL,
27721 + 0x27e05a6e926952ccULL,
27722 + 0x94ce16d091ce0da3ULL,
27723 + 0xd3646c393a29f297ULL,
27724 + 0x604a2087398eadf8ULL,
27725 + 0x5c3099ea6de60cffULL,
27726 + 0xef1ed5546e415390ULL,
27727 + 0xa8b4afbdc5a6aca4ULL,
27728 + 0x1b9ae303c601f3cbULL,
27729 + 0x56ed3e2f9e224471ULL,
27730 + 0xe5c372919d851b1eULL,
27731 + 0xa26908783662e42aULL,
27732 + 0x114744c635c5bb45ULL,
27733 + 0x2d3dfdab61ad1a42ULL,
27734 + 0x9e13b115620a452dULL,
27735 + 0xd9b9cbfcc9edba19ULL,
27736 + 0x6a978742ca4ae576ULL,
27737 + 0xa14cb926613cf817ULL,
27738 + 0x1262f598629ba778ULL,
27739 + 0x55c88f71c97c584cULL,
27740 + 0xe6e6c3cfcadb0723ULL,
27741 + 0xda9c7aa29eb3a624ULL,
27742 + 0x69b2361c9d14f94bULL,
27743 + 0x2e184cf536f3067fULL,
27744 + 0x9d36004b35545910ULL,
27745 + 0x2b769f17cf112238ULL,
27746 + 0x9858d3a9ccb67d57ULL,
27747 + 0xdff2a94067518263ULL,
27748 + 0x6cdce5fe64f6dd0cULL,
27749 + 0x50a65c93309e7c0bULL,
27750 + 0xe388102d33392364ULL,
27751 + 0xa4226ac498dedc50ULL,
27752 + 0x170c267a9b79833fULL,
27753 + 0xdcd7181e300f9e5eULL,
27754 + 0x6ff954a033a8c131ULL,
27755 + 0x28532e49984f3e05ULL,
27756 + 0x9b7d62f79be8616aULL,
27757 + 0xa707db9acf80c06dULL,
27758 + 0x14299724cc279f02ULL,
27759 + 0x5383edcd67c06036ULL,
27760 + 0xe0ada17364673f59ULL
27761 + }
27762 +};
27763 +
27764 +
27765 +/**
27766 + \brief Initializes the crc seed
27767 + */
27768 +static __inline__ uint64_t crc64_init(void)
27769 +{
27770 + return CRC64_ECMA_182.initial;
27771 +}
27772 +
27773 +/**
27774 + \brief Computes 64 bit the crc
27775 + \param[in] data Pointer to the Data in the frame
27776 + \param[in] len Length of the Data
27777 + \param[in] crc seed
27778 + \return calculated crc
27779 + */
27780 +static __inline__ uint64_t crc64_compute(void const *data,
27781 + uint32_t len,
27782 + uint64_t seed)
27783 +{
27784 + uint32_t i;
27785 + uint64_t crc = seed;
27786 + uint8_t *bdata = (uint8_t *) data;
27787 +
27788 + for (i = 0; i < len; i++)
27789 + crc =
27790 + CRC64_ECMA_182.
27791 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
27792 +
27793 + return crc;
27794 +}
27795 +
27796 +
27797 +#endif /* __CRC64_H */
27798 --- /dev/null
27799 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
27800 @@ -0,0 +1,7582 @@
27801 +/*
27802 + * Copyright 2008-2012 Freescale Semiconductor Inc.
27803 + *
27804 + * Redistribution and use in source and binary forms, with or without
27805 + * modification, are permitted provided that the following conditions are met:
27806 + * * Redistributions of source code must retain the above copyright
27807 + * notice, this list of conditions and the following disclaimer.
27808 + * * Redistributions in binary form must reproduce the above copyright
27809 + * notice, this list of conditions and the following disclaimer in the
27810 + * documentation and/or other materials provided with the distribution.
27811 + * * Neither the name of Freescale Semiconductor nor the
27812 + * names of its contributors may be used to endorse or promote products
27813 + * derived from this software without specific prior written permission.
27814 + *
27815 + *
27816 + * ALTERNATIVELY, this software may be distributed under the terms of the
27817 + * GNU General Public License ("GPL") as published by the Free Software
27818 + * Foundation, either version 2 of that License or (at your option) any
27819 + * later version.
27820 + *
27821 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
27822 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27823 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27824 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27825 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27826 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27827 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27828 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27829 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27830 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27831 + */
27832 +
27833 +
27834 +/******************************************************************************
27835 + @File fm_cc.c
27836 +
27837 + @Description FM Coarse Classifier implementation
27838 + *//***************************************************************************/
27839 +#include <linux/math64.h>
27840 +#include "std_ext.h"
27841 +#include "error_ext.h"
27842 +#include "string_ext.h"
27843 +#include "debug_ext.h"
27844 +#include "fm_pcd_ext.h"
27845 +#include "fm_muram_ext.h"
27846 +
27847 +#include "fm_common.h"
27848 +#include "fm_pcd.h"
27849 +#include "fm_hc.h"
27850 +#include "fm_cc.h"
27851 +#include "crc64.h"
27852 +
27853 +/****************************************/
27854 +/* static functions */
27855 +/****************************************/
27856 +
27857 +
27858 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
27859 +{
27860 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
27861 +
27862 + ASSERT_COND(h_FmPcdCcTree);
27863 +
27864 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
27865 + return E_OK;
27866 +
27867 + return ERROR_CODE(E_BUSY);
27868 +}
27869 +
27870 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
27871 +{
27872 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
27873 +
27874 + ASSERT_COND(h_FmPcdCcTree);
27875 +
27876 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
27877 +}
27878 +
27879 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
27880 +{
27881 + uint32_t intFlags;
27882 +
27883 + ASSERT_COND(p_CcNode);
27884 +
27885 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
27886 +
27887 + if (add)
27888 + p_CcNode->owners++;
27889 + else
27890 + {
27891 + ASSERT_COND(p_CcNode->owners);
27892 + p_CcNode->owners--;
27893 + }
27894 +
27895 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
27896 +}
27897 +
27898 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
27899 +{
27900 + t_FmPcdStatsObj *p_StatsObj = NULL;
27901 + t_List *p_Next;
27902 +
27903 + if (!LIST_IsEmpty(p_List))
27904 + {
27905 + p_Next = LIST_FIRST(p_List);
27906 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
27907 + ASSERT_COND(p_StatsObj);
27908 + LIST_DelAndInit(p_Next);
27909 + }
27910 +
27911 + return p_StatsObj;
27912 +}
27913 +
27914 +static __inline__ void EnqueueStatsObj(t_List *p_List,
27915 + t_FmPcdStatsObj *p_StatsObj)
27916 +{
27917 + LIST_AddToTail(&p_StatsObj->node, p_List);
27918 +}
27919 +
27920 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
27921 +{
27922 + t_FmPcdStatsObj *p_StatsObj;
27923 +
27924 + while (!LIST_IsEmpty(p_List))
27925 + {
27926 + p_StatsObj = DequeueStatsObj(p_List);
27927 + ASSERT_COND(p_StatsObj);
27928 +
27929 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
27930 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
27931 +
27932 + XX_Free(p_StatsObj);
27933 + }
27934 +}
27935 +
27936 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
27937 +{
27938 + t_FmPcdStatsObj* p_StatsObj;
27939 + t_Handle h_FmMuram;
27940 +
27941 + ASSERT_COND(p_CcNode);
27942 +
27943 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
27944 + upon node initialization */
27945 + if (p_CcNode->maxNumOfKeys)
27946 + {
27947 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
27948 +
27949 + /* Clean statistics counters & ADs */
27950 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
27951 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
27952 + }
27953 + else
27954 + {
27955 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
27956 + ASSERT_COND(h_FmMuram);
27957 +
27958 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
27959 + if (!p_StatsObj)
27960 + {
27961 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
27962 + return NULL;
27963 + }
27964 +
27965 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
27966 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
27967 + if (!p_StatsObj->h_StatsAd)
27968 + {
27969 + XX_Free(p_StatsObj);
27970 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
27971 + return NULL;
27972 + }
27973 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
27974 +
27975 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
27976 + h_FmMuram, p_CcNode->countersArraySize,
27977 + FM_PCD_CC_AD_TABLE_ALIGN);
27978 + if (!p_StatsObj->h_StatsCounters)
27979 + {
27980 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
27981 + XX_Free(p_StatsObj);
27982 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
27983 + return NULL;
27984 + }
27985 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
27986 + }
27987 +
27988 + return p_StatsObj;
27989 +}
27990 +
27991 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
27992 +{
27993 + t_Handle h_FmMuram;
27994 +
27995 + ASSERT_COND(p_CcNode);
27996 + ASSERT_COND(p_StatsObj);
27997 +
27998 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
27999 + upon node initialization and now will be enqueued back to the list */
28000 + if (p_CcNode->maxNumOfKeys)
28001 + {
28002 + /* Clean statistics counters */
28003 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
28004 +
28005 + /* Clean statistics ADs */
28006 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
28007 +
28008 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
28009 + }
28010 + else
28011 + {
28012 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
28013 + ASSERT_COND(h_FmMuram);
28014 +
28015 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
28016 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
28017 +
28018 + XX_Free(p_StatsObj);
28019 + }
28020 +}
28021 +
28022 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
28023 + uint32_t statsCountersAddr)
28024 +{
28025 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
28026 +
28027 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
28028 +}
28029 +
28030 +
28031 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28032 + t_Handle h_Ad, uint64_t physicalMuramBase)
28033 +{
28034 + t_AdOfTypeStats *p_StatsAd;
28035 + uint32_t statsCountersAddr, nextActionAddr, tmp;
28036 +#if (DPAA_VERSION >= 11)
28037 + uint32_t frameLengthRangesAddr;
28038 +#endif /* (DPAA_VERSION >= 11) */
28039 +
28040 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
28041 +
28042 + tmp = FM_PCD_AD_STATS_TYPE;
28043 +
28044 +#if (DPAA_VERSION >= 11)
28045 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
28046 + {
28047 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
28048 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
28049 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
28050 + }
28051 +#endif /* (DPAA_VERSION >= 11) */
28052 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
28053 +
28054 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
28055 + tmp = 0;
28056 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
28057 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
28058 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
28059 +
28060 +#if (DPAA_VERSION >= 11)
28061 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
28062 + tmp |= FM_PCD_AD_STATS_FLR_EN;
28063 +#endif /* (DPAA_VERSION >= 11) */
28064 +
28065 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
28066 +
28067 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
28068 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
28069 + SetStatsCounters(p_StatsAd, statsCountersAddr);
28070 +}
28071 +
28072 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
28073 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28074 + t_Handle h_FmPcd, t_Handle p_CcNode,
28075 + t_Handle h_Manip, t_Handle h_FrmReplic)
28076 +{
28077 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
28078 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
28079 + t_Handle h_TmpAd;
28080 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
28081 + uint32_t tmpReg32;
28082 + t_Handle p_AdNewPtr = NULL;
28083 +
28084 + UNUSED(h_Manip);
28085 + UNUSED(h_FrmReplic);
28086 +
28087 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
28088 + * Case 1: No Manip. The action descriptor is built within the match table.
28089 + * p_AdResult = p_AdNewPtr;
28090 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28091 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28092 + * initialized and returned here.
28093 + * p_AdResult (within the match table) will be initialized after
28094 + * this routine returns and point to the existing AD.
28095 + * Case 3: Manip exists. The action descriptor is built within the match table.
28096 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
28097 + */
28098 +
28099 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28100 + * AD will be written into the match table itself (case (1))*/
28101 + p_AdNewPtr = p_AdContLookup;
28102 +
28103 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28104 + if (p_FmPcdCcStatsParams)
28105 + {
28106 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28107 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28108 +
28109 + /* Swapping addresses between statistics Ad and the current lookup AD */
28110 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28111 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28112 + h_Ad = h_TmpAd;
28113 +
28114 + p_AdNewPtr = h_Ad;
28115 + p_AdContLookup = h_Ad;
28116 +
28117 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28118 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28119 + }
28120 +
28121 +#if DPAA_VERSION >= 11
28122 + if (h_Manip && h_FrmReplic)
28123 + FmPcdManipUpdateAdContLookupForCc(
28124 + h_Manip,
28125 + h_Ad,
28126 + &p_AdNewPtr,
28127 + (uint32_t)((XX_VirtToPhys(
28128 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
28129 + - p_FmPcd->physicalMuramBase)));
28130 + else
28131 + if (h_FrmReplic)
28132 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
28133 + else
28134 +#endif /* (DPAA_VERSION >= 11) */
28135 + if (h_Manip)
28136 + FmPcdManipUpdateAdContLookupForCc(
28137 + h_Manip,
28138 + h_Ad,
28139 + &p_AdNewPtr,
28140 +
28141 +#ifdef FM_CAPWAP_SUPPORT
28142 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
28143 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
28144 +#else /* not FM_CAPWAP_SUPPORT */
28145 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
28146 + - p_FmPcd->physicalMuramBase))
28147 +#endif /* not FM_CAPWAP_SUPPORT */
28148 + );
28149 +
28150 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28151 + if (p_AdNewPtr)
28152 + {
28153 + /* cases (1) & (2) */
28154 + tmpReg32 = 0;
28155 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
28156 + tmpReg32 |=
28157 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
28158 + 0;
28159 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
28160 + - p_FmPcd->physicalMuramBase);
28161 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
28162 +
28163 + tmpReg32 = 0;
28164 + tmpReg32 |= p_Node->numOfKeys << 24;
28165 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
28166 + tmpReg32 |=
28167 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
28168 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
28169 + 0;
28170 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
28171 +
28172 + tmpReg32 = 0;
28173 + tmpReg32 |= p_Node->prsArrayOffset << 24;
28174 + tmpReg32 |= p_Node->offset << 16;
28175 + tmpReg32 |= p_Node->parseCode;
28176 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
28177 +
28178 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
28179 + CC_GLBL_MASK_SIZE);
28180 + }
28181 +}
28182 +
28183 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
28184 +{
28185 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
28186 + uint32_t intFlags;
28187 +
28188 + ASSERT_COND(p_CcNode);
28189 +
28190 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
28191 +
28192 + if (!p_CcNode->h_Ad)
28193 + {
28194 + if (p_CcNode->maxNumOfKeys)
28195 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
28196 + else
28197 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
28198 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
28199 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
28200 +
28201 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
28202 +
28203 + if (!p_CcNode->h_Ad)
28204 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28205 + ("MURAM allocation for CC action descriptor"));
28206 +
28207 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
28208 +
28209 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
28210 + p_CcNode, NULL, NULL);
28211 + }
28212 + else
28213 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
28214 +
28215 + return E_OK;
28216 +}
28217 +
28218 +static t_Error SetRequiredAction1(
28219 + t_Handle h_FmPcd, uint32_t requiredAction,
28220 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
28221 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
28222 +{
28223 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
28224 + uint32_t tmpReg32;
28225 + t_Error err;
28226 + t_FmPcdCcNode *p_CcNode;
28227 + int i = 0;
28228 + uint16_t tmp = 0;
28229 + uint16_t profileId;
28230 + uint8_t relativeSchemeId, physicalSchemeId;
28231 + t_CcNodeInformation ccNodeInfo;
28232 +
28233 + for (i = 0; i < numOfEntries; i++)
28234 + {
28235 + if (i == 0)
28236 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
28237 + else
28238 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
28239 +
28240 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
28241 + {
28242 + case (e_FM_PCD_CC):
28243 + if (requiredAction)
28244 + {
28245 + p_CcNode =
28246 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
28247 + ASSERT_COND(p_CcNode);
28248 + if (p_CcNode->shadowAction == requiredAction)
28249 + break;
28250 + if ((requiredAction & UPDATE_CC_WITH_TREE)
28251 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
28252 + {
28253 +
28254 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
28255 + ccNodeInfo.h_CcNode = h_Tree;
28256 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
28257 + &ccNodeInfo, NULL);
28258 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28259 + UPDATE_CC_WITH_TREE;
28260 + }
28261 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
28262 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
28263 + {
28264 +
28265 + p_CcNode->shadowAction = 0;
28266 + }
28267 +
28268 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
28269 + && !(p_CcNode->shadowAction
28270 + & UPDATE_CC_WITH_DELETE_TREE))
28271 + {
28272 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
28273 + h_Tree, NULL);
28274 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28275 + UPDATE_CC_WITH_DELETE_TREE;
28276 + }
28277 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
28278 + != e_FM_PCD_INVALID)
28279 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
28280 + else
28281 + tmp = p_CcNode->numOfKeys;
28282 + err = SetRequiredAction1(h_FmPcd, requiredAction,
28283 + p_CcNode->keyAndNextEngineParams,
28284 + p_CcNode->h_AdTable, tmp, h_Tree);
28285 + if (err != E_OK)
28286 + return err;
28287 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
28288 + p_CcNode->shadowAction |= requiredAction;
28289 + }
28290 + break;
28291 +
28292 + case (e_FM_PCD_KG):
28293 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
28294 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
28295 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
28296 + {
28297 + physicalSchemeId =
28298 + FmPcdKgGetSchemeId(
28299 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
28300 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
28301 + h_FmPcd, physicalSchemeId);
28302 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
28303 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
28304 + if (!FmPcdKgIsSchemeValidSw(
28305 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
28306 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28307 + ("Invalid direct scheme."));
28308 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
28309 + RETURN_ERROR(
28310 + MAJOR, E_INVALID_STATE,
28311 + ("For this action scheme has to be direct."));
28312 + err =
28313 + FmPcdKgCcGetSetParams(
28314 + h_FmPcd,
28315 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
28316 + requiredAction, 0);
28317 + if (err != E_OK)
28318 + RETURN_ERROR(MAJOR, err, NO_MSG);
28319 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28320 + requiredAction;
28321 + }
28322 + break;
28323 +
28324 + case (e_FM_PCD_PLCR):
28325 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
28326 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
28327 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
28328 + {
28329 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
28330 + RETURN_ERROR(
28331 + MAJOR,
28332 + E_NOT_SUPPORTED,
28333 + ("In this initialization only overrideFqid can be initialized"));
28334 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
28335 + RETURN_ERROR(
28336 + MAJOR,
28337 + E_NOT_SUPPORTED,
28338 + ("In this initialization only overrideFqid can be initialized"));
28339 + err =
28340 + FmPcdPlcrGetAbsoluteIdByProfileParams(
28341 + h_FmPcd,
28342 + e_FM_PCD_PLCR_SHARED,
28343 + NULL,
28344 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
28345 + &profileId);
28346 + if (err != E_OK)
28347 + RETURN_ERROR(MAJOR, err, NO_MSG);
28348 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
28349 + requiredAction);
28350 + if (err != E_OK)
28351 + RETURN_ERROR(MAJOR, err, NO_MSG);
28352 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28353 + requiredAction;
28354 + }
28355 + break;
28356 +
28357 + case (e_FM_PCD_DONE):
28358 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
28359 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
28360 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
28361 + {
28362 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
28363 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
28364 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
28365 + RETURN_ERROR(
28366 + MAJOR,
28367 + E_INVALID_STATE,
28368 + ("Next engine was previously assigned not as PCD_DONE"));
28369 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
28370 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
28371 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28372 + requiredAction;
28373 + }
28374 + break;
28375 +
28376 + default:
28377 + break;
28378 + }
28379 + }
28380 +
28381 + return E_OK;
28382 +}
28383 +
28384 +static t_Error SetRequiredAction(
28385 + t_Handle h_FmPcd, uint32_t requiredAction,
28386 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
28387 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
28388 +{
28389 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
28390 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
28391 + numOfEntries, h_Tree);
28392 + if (err != E_OK)
28393 + return err;
28394 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
28395 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
28396 + numOfEntries, h_Tree);
28397 +}
28398 +
28399 +static t_Error ReleaseModifiedDataStructure(
28400 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
28401 + t_List *h_FmPcdNewPointersLst,
28402 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
28403 + bool useShadowStructs)
28404 +{
28405 + t_List *p_Pos;
28406 + t_Error err = E_OK;
28407 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
28408 + t_Handle h_Muram;
28409 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
28410 + t_List *p_UpdateLst;
28411 + uint32_t intFlags;
28412 +
28413 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
28414 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
28415 + E_INVALID_HANDLE);
28416 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
28417 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
28418 +
28419 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
28420 + if (p_AdditionalParams->h_NodeForAdd)
28421 + {
28422 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
28423 +
28424 + if (!p_AdditionalParams->tree)
28425 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
28426 + else
28427 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
28428 +
28429 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28430 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
28431 + p_FmPcdCcNextNode->h_Spinlock);
28432 +
28433 + if (p_CcNodeInformation)
28434 + p_CcNodeInformation->index++;
28435 + else
28436 + {
28437 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
28438 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
28439 + ccNodeInfo.index = 1;
28440 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
28441 + p_FmPcdCcNextNode->h_Spinlock);
28442 + }
28443 + if (p_AdditionalParams->h_ManipForAdd)
28444 + {
28445 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28446 + FmPcdManipGetNodeLstPointedOnThisManip(
28447 + p_AdditionalParams->h_ManipForAdd),
28448 + p_AdditionalParams->h_CurrentNode,
28449 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
28450 +
28451 + if (p_CcNodeInformation)
28452 + p_CcNodeInformation->index++;
28453 + else
28454 + {
28455 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
28456 + ccNodeInfo.h_CcNode =
28457 + (t_Handle)p_AdditionalParams->h_CurrentNode;
28458 + ccNodeInfo.index = 1;
28459 + EnqueueNodeInfoToRelevantLst(
28460 + FmPcdManipGetNodeLstPointedOnThisManip(
28461 + p_AdditionalParams->h_ManipForAdd),
28462 + &ccNodeInfo,
28463 + FmPcdManipGetSpinlock(
28464 + p_AdditionalParams->h_ManipForAdd));
28465 + }
28466 + }
28467 + }
28468 +
28469 + if (p_AdditionalParams->h_NodeForRmv)
28470 + {
28471 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
28472 +
28473 + if (!p_AdditionalParams->tree)
28474 + {
28475 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
28476 + p_FmPcdCcWorkingOnNode =
28477 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
28478 +
28479 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
28480 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
28481 + LIST_NEXT(p_Pos))
28482 + {
28483 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
28484 +
28485 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
28486 +
28487 + err =
28488 + SetRequiredAction(
28489 + h_FmPcd,
28490 + UPDATE_CC_WITH_DELETE_TREE,
28491 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
28492 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
28493 + 1, p_CcNodeInformation->h_CcNode);
28494 + }
28495 + }
28496 + else
28497 + {
28498 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
28499 +
28500 + err =
28501 + SetRequiredAction(
28502 + h_FmPcd,
28503 + UPDATE_CC_WITH_DELETE_TREE,
28504 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
28505 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
28506 + 1, p_AdditionalParams->h_CurrentNode);
28507 + }
28508 + if (err)
28509 + return err;
28510 +
28511 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
28512 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
28513 + Update of the node owner */
28514 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28515 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
28516 + p_FmPcdCcNextNode->h_Spinlock);
28517 +
28518 + ASSERT_COND(p_CcNodeInformation);
28519 + ASSERT_COND(p_CcNodeInformation->index);
28520 +
28521 + p_CcNodeInformation->index--;
28522 +
28523 + if (p_CcNodeInformation->index == 0)
28524 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
28525 + p_AdditionalParams->h_CurrentNode,
28526 + p_FmPcdCcNextNode->h_Spinlock);
28527 +
28528 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
28529 +
28530 + if (p_AdditionalParams->h_ManipForRmv)
28531 + {
28532 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28533 + FmPcdManipGetNodeLstPointedOnThisManip(
28534 + p_AdditionalParams->h_ManipForRmv),
28535 + p_AdditionalParams->h_CurrentNode,
28536 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
28537 +
28538 + ASSERT_COND(p_CcNodeInformation);
28539 + ASSERT_COND(p_CcNodeInformation->index);
28540 +
28541 + p_CcNodeInformation->index--;
28542 +
28543 + if (p_CcNodeInformation->index == 0)
28544 + DequeueNodeInfoFromRelevantLst(
28545 + FmPcdManipGetNodeLstPointedOnThisManip(
28546 + p_AdditionalParams->h_ManipForRmv),
28547 + p_AdditionalParams->h_CurrentNode,
28548 + FmPcdManipGetSpinlock(
28549 + p_AdditionalParams->h_ManipForRmv));
28550 + }
28551 + }
28552 +
28553 + if (p_AdditionalParams->h_ManipForRmv)
28554 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
28555 +
28556 + if (p_AdditionalParams->p_StatsObjForRmv)
28557 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
28558 + p_AdditionalParams->p_StatsObjForRmv);
28559 +
28560 +#if (DPAA_VERSION >= 11)
28561 + if (p_AdditionalParams->h_FrmReplicForRmv)
28562 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
28563 + FALSE/* remove */);
28564 +#endif /* (DPAA_VERSION >= 11) */
28565 +
28566 + if (!useShadowStructs)
28567 + {
28568 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
28569 + ASSERT_COND(h_Muram);
28570 +
28571 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
28572 + || (!p_AdditionalParams->tree
28573 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
28574 + {
28575 + /* We release new AD which was allocated and updated for copy from to actual AD */
28576 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
28577 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
28578 + {
28579 +
28580 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
28581 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
28582 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
28583 + }
28584 + }
28585 +
28586 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
28587 + if (p_AdditionalParams->p_AdTableOld)
28588 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
28589 +
28590 + if (p_AdditionalParams->p_KeysMatchTableOld)
28591 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
28592 + }
28593 +
28594 + /* Update current modified node with changed fields if it's required*/
28595 + if (!p_AdditionalParams->tree)
28596 + {
28597 + if (p_AdditionalParams->p_AdTableNew)
28598 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
28599 + p_AdditionalParams->p_AdTableNew;
28600 +
28601 + if (p_AdditionalParams->p_KeysMatchTableNew)
28602 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
28603 + p_AdditionalParams->p_KeysMatchTableNew;
28604 +
28605 + /* Locking node's spinlock before updating 'keys and next engine' structure,
28606 + as it maybe used to retrieve keys statistics */
28607 + intFlags =
28608 + XX_LockIntrSpinlock(
28609 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
28610 +
28611 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
28612 + p_AdditionalParams->numOfKeys;
28613 +
28614 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
28615 + &p_AdditionalParams->keyAndNextEngineParams,
28616 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
28617 +
28618 + XX_UnlockIntrSpinlock(
28619 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
28620 + intFlags);
28621 + }
28622 + else
28623 + {
28624 + uint8_t numEntries =
28625 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
28626 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
28627 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
28628 + &p_AdditionalParams->keyAndNextEngineParams,
28629 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
28630 + }
28631 +
28632 + ReleaseLst(h_FmPcdOldPointersLst);
28633 + ReleaseLst(h_FmPcdNewPointersLst);
28634 +
28635 + XX_Free(p_AdditionalParams);
28636 +
28637 + return E_OK;
28638 +}
28639 +
28640 +static t_Handle BuildNewAd(
28641 + t_Handle h_Ad,
28642 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
28643 + t_FmPcdCcNode *p_CcNode,
28644 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
28645 +{
28646 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
28647 + t_Handle h_OrigAd = NULL;
28648 +
28649 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
28650 + if (!p_FmPcdCcNodeTmp)
28651 + {
28652 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
28653 + return NULL;
28654 + }
28655 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
28656 +
28657 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
28658 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
28659 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
28660 + p_FmPcdCcNodeTmp->h_AdTable =
28661 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
28662 +
28663 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
28664 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
28665 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
28666 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
28667 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
28668 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
28669 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
28670 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
28671 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
28672 +
28673 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
28674 + {
28675 + if (p_FmPcdCcNextEngineParams->h_Manip)
28676 + {
28677 + h_OrigAd = p_CcNode->h_Ad;
28678 + if (AllocAndFillAdForContLookupManip(
28679 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
28680 + != E_OK)
28681 + {
28682 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
28683 + XX_Free(p_FmPcdCcNodeTmp);
28684 + return NULL;
28685 + }
28686 + }
28687 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
28688 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
28689 + }
28690 +
28691 +#if (DPAA_VERSION >= 11)
28692 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
28693 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
28694 + {
28695 + FillAdOfTypeContLookup(
28696 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
28697 + p_FmPcdCcNextEngineParams->h_Manip,
28698 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
28699 + }
28700 +#endif /* (DPAA_VERSION >= 11) */
28701 +
28702 + XX_Free(p_FmPcdCcNodeTmp);
28703 +
28704 + return E_OK;
28705 +}
28706 +
28707 +static t_Error DynamicChangeHc(
28708 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
28709 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
28710 + bool useShadowStructs)
28711 +{
28712 + t_List *p_PosOld, *p_PosNew;
28713 + uint32_t oldAdAddrOffset, newAdAddrOffset;
28714 + uint16_t i = 0;
28715 + t_Error err = E_OK;
28716 + uint8_t numOfModifiedPtr;
28717 +
28718 + ASSERT_COND(h_FmPcd);
28719 + ASSERT_COND(h_OldPointersLst);
28720 + ASSERT_COND(h_NewPointersLst);
28721 +
28722 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
28723 +
28724 + if (numOfModifiedPtr)
28725 + {
28726 + p_PosNew = LIST_FIRST(h_NewPointersLst);
28727 + p_PosOld = LIST_FIRST(h_OldPointersLst);
28728 +
28729 + /* Retrieve address of new AD */
28730 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
28731 + p_PosNew);
28732 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
28733 + {
28734 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
28735 + h_NewPointersLst,
28736 + p_AdditionalParams, useShadowStructs);
28737 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
28738 + }
28739 +
28740 + for (i = 0; i < numOfModifiedPtr; i++)
28741 + {
28742 + /* Retrieve address of current AD */
28743 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
28744 + p_PosOld);
28745 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
28746 + {
28747 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
28748 + h_NewPointersLst,
28749 + p_AdditionalParams,
28750 + useShadowStructs);
28751 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
28752 + }
28753 +
28754 + /* Invoke host command to copy from new AD to old AD */
28755 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
28756 + oldAdAddrOffset, newAdAddrOffset);
28757 + if (err)
28758 + {
28759 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
28760 + h_NewPointersLst,
28761 + p_AdditionalParams,
28762 + useShadowStructs);
28763 + RETURN_ERROR(
28764 + MAJOR,
28765 + err,
28766 + ("For part of nodes changes are done - situation is danger"));
28767 + }
28768 +
28769 + p_PosOld = LIST_NEXT(p_PosOld);
28770 + }
28771 + }
28772 + return E_OK;
28773 +}
28774 +
28775 +static t_Error DoDynamicChange(
28776 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
28777 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
28778 + bool useShadowStructs)
28779 +{
28780 + t_FmPcdCcNode *p_CcNode =
28781 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
28782 + t_List *p_PosNew;
28783 + t_CcNodeInformation *p_CcNodeInfo;
28784 + t_FmPcdCcNextEngineParams nextEngineParams;
28785 + t_Handle h_Ad;
28786 + uint32_t keySize;
28787 + t_Error err = E_OK;
28788 + uint8_t numOfModifiedPtr;
28789 +
28790 + ASSERT_COND(h_FmPcd);
28791 +
28792 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
28793 +
28794 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
28795 +
28796 + if (numOfModifiedPtr)
28797 + {
28798 +
28799 + p_PosNew = LIST_FIRST(h_NewPointersLst);
28800 +
28801 + /* Invoke host-command to copy from the new Ad to existing Ads */
28802 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
28803 + p_AdditionalParams, useShadowStructs);
28804 + if (err)
28805 + RETURN_ERROR(MAJOR, err, NO_MSG);
28806 +
28807 + if (useShadowStructs)
28808 + {
28809 + /* When the host-command above has ended, the old structures are 'free'and we can update
28810 + them by copying from the new shadow structures. */
28811 + if (p_CcNode->lclMask)
28812 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
28813 + else
28814 + keySize = p_CcNode->ccKeySizeAccExtraction;
28815 +
28816 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
28817 + p_AdditionalParams->p_KeysMatchTableNew,
28818 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
28819 +
28820 + MemCpy8(
28821 + p_AdditionalParams->p_AdTableOld,
28822 + p_AdditionalParams->p_AdTableNew,
28823 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
28824 + * FM_PCD_CC_AD_ENTRY_SIZE));
28825 +
28826 + /* Retrieve the address of the allocated Ad */
28827 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
28828 + h_Ad = p_CcNodeInfo->h_CcNode;
28829 +
28830 + /* Build a new Ad that holds the old (now updated) structures */
28831 + p_AdditionalParams->p_KeysMatchTableNew =
28832 + p_AdditionalParams->p_KeysMatchTableOld;
28833 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
28834 +
28835 + nextEngineParams.nextEngine = e_FM_PCD_CC;
28836 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
28837 +
28838 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
28839 +
28840 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
28841 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
28842 + p_AdditionalParams, useShadowStructs);
28843 + if (err)
28844 + RETURN_ERROR(MAJOR, err, NO_MSG);
28845 + }
28846 + }
28847 +
28848 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
28849 + h_NewPointersLst,
28850 + p_AdditionalParams, useShadowStructs);
28851 + if (err)
28852 + RETURN_ERROR(MAJOR, err, NO_MSG);
28853 +
28854 + return E_OK;
28855 +}
28856 +
28857 +#ifdef FM_CAPWAP_SUPPORT
28858 +static bool IsCapwapApplSpecific(t_Handle h_Node)
28859 +{
28860 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
28861 + bool isManipForCapwapApplSpecificBuild = FALSE;
28862 + int i = 0;
28863 +
28864 + ASSERT_COND(h_Node);
28865 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
28866 + for (i = 0; i < p_CcNode->numOfKeys; i++)
28867 + {
28868 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
28869 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
28870 + {
28871 + isManipForCapwapApplSpecificBuild = TRUE;
28872 + break;
28873 + }
28874 + }
28875 + return isManipForCapwapApplSpecificBuild;
28876 +
28877 +}
28878 +#endif /* FM_CAPWAP_SUPPORT */
28879 +
28880 +static t_Error CcUpdateParam(
28881 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
28882 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
28883 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
28884 + t_Handle h_FmTree, bool modify)
28885 +{
28886 + t_FmPcdCcNode *p_CcNode;
28887 + t_Error err;
28888 + uint16_t tmp = 0;
28889 + int i = 0;
28890 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28891 +
28892 + level++;
28893 +
28894 + if (p_CcTree->h_IpReassemblyManip)
28895 + {
28896 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
28897 + p_CcTree->h_IpReassemblyManip, NULL, validate,
28898 + level, h_FmTree, modify);
28899 + if (err)
28900 + RETURN_ERROR(MAJOR, err, NO_MSG);
28901 + }
28902 +
28903 + if (p_CcTree->h_CapwapReassemblyManip)
28904 + {
28905 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
28906 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
28907 + level, h_FmTree, modify);
28908 + if (err)
28909 + RETURN_ERROR(MAJOR, err, NO_MSG);
28910 + }
28911 +
28912 + if (numOfEntries)
28913 + {
28914 + for (i = 0; i < numOfEntries; i++)
28915 + {
28916 + if (i == 0)
28917 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
28918 + else
28919 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
28920 +
28921 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
28922 + == e_FM_PCD_CC)
28923 + {
28924 + p_CcNode =
28925 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
28926 + ASSERT_COND(p_CcNode);
28927 +
28928 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
28929 + {
28930 + err =
28931 + FmPcdManipUpdate(
28932 + h_FmPcd,
28933 + NULL,
28934 + h_FmPort,
28935 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
28936 + h_Ad, validate, level, h_FmTree, modify);
28937 + if (err)
28938 + RETURN_ERROR(MAJOR, err, NO_MSG);
28939 + }
28940 +
28941 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
28942 + != e_FM_PCD_INVALID)
28943 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
28944 + else
28945 + tmp = p_CcNode->numOfKeys;
28946 +
28947 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28948 + p_CcNode->keyAndNextEngineParams, tmp,
28949 + p_CcNode->h_AdTable, validate, level,
28950 + h_FmTree, modify);
28951 + if (err)
28952 + RETURN_ERROR(MAJOR, err, NO_MSG);
28953 + }
28954 + else
28955 + {
28956 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
28957 + {
28958 + err =
28959 + FmPcdManipUpdate(
28960 + h_FmPcd,
28961 + NULL,
28962 + h_FmPort,
28963 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
28964 + h_Ad, validate, level, h_FmTree, modify);
28965 + if (err)
28966 + RETURN_ERROR(MAJOR, err, NO_MSG);
28967 + }
28968 + }
28969 + }
28970 + }
28971 +
28972 + return E_OK;
28973 +}
28974 +
28975 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
28976 +{
28977 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
28978 + {
28979 + case (e_FM_PCD_ACTION_EXACT_MATCH):
28980 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
28981 + {
28982 + case (e_FM_PCD_EXTRACT_FROM_KEY):
28983 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
28984 + case (e_FM_PCD_EXTRACT_FROM_HASH):
28985 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
28986 + default:
28987 + return CC_PRIVATE_INFO_NONE;
28988 + }
28989 +
28990 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
28991 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
28992 + {
28993 + case (e_FM_PCD_EXTRACT_FROM_HASH):
28994 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
28995 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
28996 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
28997 + default:
28998 + return CC_PRIVATE_INFO_NONE;
28999 + }
29000 +
29001 + default:
29002 + break;
29003 + }
29004 +
29005 + return CC_PRIVATE_INFO_NONE;
29006 +}
29007 +
29008 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
29009 + t_List *p_List)
29010 +{
29011 + t_CcNodeInformation *p_CcNodeInfo = NULL;
29012 +
29013 + if (!LIST_IsEmpty(p_List))
29014 + {
29015 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
29016 + LIST_DelAndInit(&p_CcNodeInfo->node);
29017 + }
29018 +
29019 + return p_CcNodeInfo;
29020 +}
29021 +
29022 +void ReleaseLst(t_List *p_List)
29023 +{
29024 + t_CcNodeInformation *p_CcNodeInfo = NULL;
29025 +
29026 + if (!LIST_IsEmpty(p_List))
29027 + {
29028 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
29029 + while (p_CcNodeInfo)
29030 + {
29031 + XX_Free(p_CcNodeInfo);
29032 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
29033 + }
29034 + }
29035 +
29036 + LIST_Del(p_List);
29037 +}
29038 +
29039 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
29040 +{
29041 + uint32_t i;
29042 +
29043 + if (!p_CcNode)
29044 + return;
29045 +
29046 + if (p_CcNode->p_GlblMask)
29047 + {
29048 + XX_Free(p_CcNode->p_GlblMask);
29049 + p_CcNode->p_GlblMask = NULL;
29050 + }
29051 +
29052 + if (p_CcNode->h_KeysMatchTable)
29053 + {
29054 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29055 + p_CcNode->h_KeysMatchTable);
29056 + p_CcNode->h_KeysMatchTable = NULL;
29057 + }
29058 +
29059 + if (p_CcNode->h_AdTable)
29060 + {
29061 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29062 + p_CcNode->h_AdTable);
29063 + p_CcNode->h_AdTable = NULL;
29064 + }
29065 +
29066 + if (p_CcNode->h_Ad)
29067 + {
29068 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29069 + p_CcNode->h_Ad);
29070 + p_CcNode->h_Ad = NULL;
29071 + p_CcNode->h_TmpAd = NULL;
29072 + }
29073 +
29074 + if (p_CcNode->h_StatsFLRs)
29075 + {
29076 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29077 + p_CcNode->h_StatsFLRs);
29078 + p_CcNode->h_StatsFLRs = NULL;
29079 + }
29080 +
29081 + if (p_CcNode->h_Spinlock)
29082 + {
29083 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
29084 + p_CcNode->h_Spinlock = NULL;
29085 + }
29086 +
29087 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
29088 + if (p_CcNode->isHashBucket
29089 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
29090 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
29091 + p_CcNode->h_PrivMissStatsCounters;
29092 +
29093 + /* Releasing all currently used statistics objects, including 'miss' entry */
29094 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
29095 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
29096 + PutStatsObj(p_CcNode,
29097 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
29098 +
29099 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
29100 + {
29101 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
29102 + ASSERT_COND(h_FmMuram);
29103 +
29104 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
29105 + }
29106 +
29107 + LIST_Del(&p_CcNode->availableStatsLst);
29108 +
29109 + ReleaseLst(&p_CcNode->availableStatsLst);
29110 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
29111 + ReleaseLst(&p_CcNode->ccTreeIdLst);
29112 + ReleaseLst(&p_CcNode->ccTreesLst);
29113 +
29114 + XX_Free(p_CcNode);
29115 +}
29116 +
29117 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
29118 +{
29119 + if (p_FmPcdTree)
29120 + {
29121 + if (p_FmPcdTree->ccTreeBaseAddr)
29122 + {
29123 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
29124 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
29125 + p_FmPcdTree->ccTreeBaseAddr = 0;
29126 + }
29127 +
29128 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
29129 +
29130 + XX_Free(p_FmPcdTree);
29131 + }
29132 +}
29133 +
29134 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
29135 + uint8_t *parseCodeCcSize)
29136 +{
29137 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
29138 + *parseCodeCcSize = 1;
29139 + else
29140 + if (parseCodeRealSize == 2)
29141 + *parseCodeCcSize = 2;
29142 + else
29143 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
29144 + *parseCodeCcSize = 4;
29145 + else
29146 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
29147 + *parseCodeCcSize = 8;
29148 + else
29149 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
29150 + *parseCodeCcSize = 16;
29151 + else
29152 + if ((parseCodeRealSize > 16)
29153 + && (parseCodeRealSize <= 24))
29154 + *parseCodeCcSize = 24;
29155 + else
29156 + if ((parseCodeRealSize > 24)
29157 + && (parseCodeRealSize <= 32))
29158 + *parseCodeCcSize = 32;
29159 + else
29160 + if ((parseCodeRealSize > 32)
29161 + && (parseCodeRealSize <= 40))
29162 + *parseCodeCcSize = 40;
29163 + else
29164 + if ((parseCodeRealSize > 40)
29165 + && (parseCodeRealSize <= 48))
29166 + *parseCodeCcSize = 48;
29167 + else
29168 + if ((parseCodeRealSize > 48)
29169 + && (parseCodeRealSize <= 56))
29170 + *parseCodeCcSize = 56;
29171 + else
29172 + *parseCodeCcSize = 0;
29173 +}
29174 +
29175 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
29176 + uint8_t *parseCodeRealSize)
29177 +{
29178 + switch (hdr)
29179 + {
29180 + case (HEADER_TYPE_ETH):
29181 + switch (field.eth)
29182 + {
29183 + case (NET_HEADER_FIELD_ETH_DA):
29184 + *parseCodeRealSize = 6;
29185 + break;
29186 +
29187 + case (NET_HEADER_FIELD_ETH_SA):
29188 + *parseCodeRealSize = 6;
29189 + break;
29190 +
29191 + case (NET_HEADER_FIELD_ETH_TYPE):
29192 + *parseCodeRealSize = 2;
29193 + break;
29194 +
29195 + default:
29196 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
29197 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29198 + break;
29199 + }
29200 + break;
29201 +
29202 + case (HEADER_TYPE_PPPoE):
29203 + switch (field.pppoe)
29204 + {
29205 + case (NET_HEADER_FIELD_PPPoE_PID):
29206 + *parseCodeRealSize = 2;
29207 + break;
29208 +
29209 + default:
29210 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
29211 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29212 + break;
29213 + }
29214 + break;
29215 +
29216 + case (HEADER_TYPE_VLAN):
29217 + switch (field.vlan)
29218 + {
29219 + case (NET_HEADER_FIELD_VLAN_TCI):
29220 + *parseCodeRealSize = 2;
29221 + break;
29222 +
29223 + default:
29224 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
29225 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29226 + break;
29227 + }
29228 + break;
29229 +
29230 + case (HEADER_TYPE_MPLS):
29231 + switch (field.mpls)
29232 + {
29233 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
29234 + *parseCodeRealSize = 4;
29235 + break;
29236 +
29237 + default:
29238 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
29239 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29240 + break;
29241 + }
29242 + break;
29243 +
29244 + case (HEADER_TYPE_IPv4):
29245 + switch (field.ipv4)
29246 + {
29247 + case (NET_HEADER_FIELD_IPv4_DST_IP):
29248 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
29249 + *parseCodeRealSize = 4;
29250 + break;
29251 +
29252 + case (NET_HEADER_FIELD_IPv4_TOS):
29253 + case (NET_HEADER_FIELD_IPv4_PROTO):
29254 + *parseCodeRealSize = 1;
29255 + break;
29256 +
29257 + case (NET_HEADER_FIELD_IPv4_DST_IP
29258 + | NET_HEADER_FIELD_IPv4_SRC_IP):
29259 + *parseCodeRealSize = 8;
29260 + break;
29261 +
29262 + case (NET_HEADER_FIELD_IPv4_TTL):
29263 + *parseCodeRealSize = 1;
29264 + break;
29265 +
29266 + default:
29267 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
29268 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29269 + break;
29270 + }
29271 + break;
29272 +
29273 + case (HEADER_TYPE_IPv6):
29274 + switch (field.ipv6)
29275 + {
29276 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
29277 + | NET_HEADER_FIELD_IPv6_TC):
29278 + *parseCodeRealSize = 4;
29279 + break;
29280 +
29281 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
29282 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
29283 + *parseCodeRealSize = 1;
29284 + break;
29285 +
29286 + case (NET_HEADER_FIELD_IPv6_DST_IP):
29287 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
29288 + *parseCodeRealSize = 16;
29289 + break;
29290 +
29291 + default:
29292 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
29293 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29294 + break;
29295 + }
29296 + break;
29297 +
29298 + case (HEADER_TYPE_IP):
29299 + switch (field.ip)
29300 + {
29301 + case (NET_HEADER_FIELD_IP_DSCP):
29302 + case (NET_HEADER_FIELD_IP_PROTO):
29303 + *parseCodeRealSize = 1;
29304 + break;
29305 +
29306 + default:
29307 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
29308 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29309 + break;
29310 + }
29311 + break;
29312 +
29313 + case (HEADER_TYPE_GRE):
29314 + switch (field.gre)
29315 + {
29316 + case (NET_HEADER_FIELD_GRE_TYPE):
29317 + *parseCodeRealSize = 2;
29318 + break;
29319 +
29320 + default:
29321 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
29322 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29323 + break;
29324 + }
29325 + break;
29326 +
29327 + case (HEADER_TYPE_MINENCAP):
29328 + switch (field.minencap)
29329 + {
29330 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
29331 + *parseCodeRealSize = 1;
29332 + break;
29333 +
29334 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
29335 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
29336 + *parseCodeRealSize = 4;
29337 + break;
29338 +
29339 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
29340 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
29341 + *parseCodeRealSize = 8;
29342 + break;
29343 +
29344 + default:
29345 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
29346 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29347 + break;
29348 + }
29349 + break;
29350 +
29351 + case (HEADER_TYPE_TCP):
29352 + switch (field.tcp)
29353 + {
29354 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
29355 + case (NET_HEADER_FIELD_TCP_PORT_DST):
29356 + *parseCodeRealSize = 2;
29357 + break;
29358 +
29359 + case (NET_HEADER_FIELD_TCP_PORT_SRC
29360 + | NET_HEADER_FIELD_TCP_PORT_DST):
29361 + *parseCodeRealSize = 4;
29362 + break;
29363 +
29364 + default:
29365 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
29366 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29367 + break;
29368 + }
29369 + break;
29370 +
29371 + case (HEADER_TYPE_UDP):
29372 + switch (field.udp)
29373 + {
29374 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
29375 + case (NET_HEADER_FIELD_UDP_PORT_DST):
29376 + *parseCodeRealSize = 2;
29377 + break;
29378 +
29379 + case (NET_HEADER_FIELD_UDP_PORT_SRC
29380 + | NET_HEADER_FIELD_UDP_PORT_DST):
29381 + *parseCodeRealSize = 4;
29382 + break;
29383 +
29384 + default:
29385 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
29386 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29387 + break;
29388 + }
29389 + break;
29390 +
29391 + default:
29392 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
29393 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29394 + break;
29395 + }
29396 +}
29397 +
29398 +t_Error ValidateNextEngineParams(
29399 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
29400 + e_FmPcdCcStatsMode statsMode)
29401 +{
29402 + uint16_t absoluteProfileId;
29403 + t_Error err = E_OK;
29404 + uint8_t relativeSchemeId;
29405 +
29406 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
29407 + && (p_FmPcdCcNextEngineParams->statisticsEn))
29408 + RETURN_ERROR(
29409 + MAJOR,
29410 + E_CONFLICT,
29411 + ("Statistics are requested for a key, but statistics mode was set"
29412 + "to 'NONE' upon initialization"));
29413 +
29414 + switch (p_FmPcdCcNextEngineParams->nextEngine)
29415 + {
29416 + case (e_FM_PCD_INVALID):
29417 + err = E_NOT_SUPPORTED;
29418 + break;
29419 +
29420 + case (e_FM_PCD_DONE):
29421 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
29422 + == e_FM_PCD_ENQ_FRAME)
29423 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
29424 + {
29425 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
29426 + RETURN_ERROR(
29427 + MAJOR,
29428 + E_CONFLICT,
29429 + ("When overrideFqid is set, newFqid must not be zero"));
29430 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
29431 + & ~0x00FFFFFF)
29432 + RETURN_ERROR(
29433 + MAJOR, E_INVALID_VALUE,
29434 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
29435 + }
29436 + break;
29437 +
29438 + case (e_FM_PCD_KG):
29439 + relativeSchemeId =
29440 + FmPcdKgGetRelativeSchemeId(
29441 + h_FmPcd,
29442 + FmPcdKgGetSchemeId(
29443 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
29444 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
29445 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
29446 + if (!FmPcdKgIsSchemeValidSw(
29447 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
29448 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
29449 + ("not valid schemeIndex in KG next engine param"));
29450 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
29451 + RETURN_ERROR(
29452 + MAJOR,
29453 + E_INVALID_STATE,
29454 + ("CC Node may point only to a scheme that is always direct."));
29455 + break;
29456 +
29457 + case (e_FM_PCD_PLCR):
29458 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
29459 + {
29460 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
29461 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
29462 + {
29463 + err =
29464 + FmPcdPlcrGetAbsoluteIdByProfileParams(
29465 + h_FmPcd,
29466 + e_FM_PCD_PLCR_SHARED,
29467 + NULL,
29468 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
29469 + &absoluteProfileId);
29470 + if (err)
29471 + RETURN_ERROR(MAJOR, err,
29472 + ("Shared profile offset is out of range"));
29473 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
29474 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
29475 + ("Invalid profile"));
29476 + }
29477 + }
29478 + break;
29479 +
29480 + case (e_FM_PCD_HASH):
29481 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
29482 + case (e_FM_PCD_CC):
29483 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
29484 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
29485 + ("handler to next Node is NULL"));
29486 + break;
29487 +
29488 +#if (DPAA_VERSION >= 11)
29489 + case (e_FM_PCD_FR):
29490 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
29491 + err = E_NOT_SUPPORTED;
29492 + break;
29493 +#endif /* (DPAA_VERSION >= 11) */
29494 +
29495 + default:
29496 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
29497 + ("Next engine is not correct"));
29498 + }
29499 +
29500 +
29501 + return err;
29502 +}
29503 +
29504 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
29505 + uint32_t offset, bool glblMask,
29506 + uint8_t *parseArrayOffset, bool fromIc,
29507 + ccPrivateInfo_t icCode)
29508 +{
29509 + if (!fromIc)
29510 + {
29511 + switch (src)
29512 + {
29513 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
29514 + if (glblMask)
29515 + return CC_PC_GENERIC_WITH_MASK;
29516 + else
29517 + return CC_PC_GENERIC_WITHOUT_MASK;
29518 +
29519 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
29520 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
29521 + if (offset)
29522 + return CC_PR_OFFSET;
29523 + else
29524 + return CC_PR_WITHOUT_OFFSET;
29525 +
29526 + default:
29527 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
29528 + return CC_PC_ILLEGAL;
29529 + }
29530 + }
29531 + else
29532 + {
29533 + switch (icCode)
29534 + {
29535 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
29536 + *parseArrayOffset = 0x50;
29537 + return CC_PC_GENERIC_IC_GMASK;
29538 +
29539 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
29540 + *parseArrayOffset = 0x48;
29541 + return CC_PC_GENERIC_IC_GMASK;
29542 +
29543 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
29544 + *parseArrayOffset = 0x48;
29545 + return CC_PC_GENERIC_IC_HASH_INDEXED;
29546 +
29547 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
29548 + *parseArrayOffset = 0x16;
29549 + return CC_PC_GENERIC_IC_HASH_INDEXED;
29550 +
29551 + default:
29552 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
29553 + break;
29554 + }
29555 + }
29556 +
29557 + return CC_PC_ILLEGAL;
29558 +}
29559 +
29560 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
29561 + t_FmPcdFields field)
29562 +{
29563 + switch (hdr)
29564 + {
29565 + case (HEADER_TYPE_NONE):
29566 + ASSERT_COND(FALSE);
29567 + return CC_PC_ILLEGAL;
29568 +
29569 + case (HEADER_TYPE_ETH):
29570 + switch (field.eth)
29571 + {
29572 + case (NET_HEADER_FIELD_ETH_DA):
29573 + return CC_PC_FF_MACDST;
29574 + case (NET_HEADER_FIELD_ETH_SA):
29575 + return CC_PC_FF_MACSRC;
29576 + case (NET_HEADER_FIELD_ETH_TYPE):
29577 + return CC_PC_FF_ETYPE;
29578 + default:
29579 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29580 + return CC_PC_ILLEGAL;
29581 + }
29582 +
29583 + case (HEADER_TYPE_VLAN):
29584 + switch (field.vlan)
29585 + {
29586 + case (NET_HEADER_FIELD_VLAN_TCI):
29587 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29588 + || (index == e_FM_PCD_HDR_INDEX_1))
29589 + return CC_PC_FF_TCI1;
29590 + if (index == e_FM_PCD_HDR_INDEX_LAST)
29591 + return CC_PC_FF_TCI2;
29592 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29593 + return CC_PC_ILLEGAL;
29594 + default:
29595 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29596 + return CC_PC_ILLEGAL;
29597 + }
29598 +
29599 + case (HEADER_TYPE_MPLS):
29600 + switch (field.mpls)
29601 + {
29602 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
29603 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29604 + || (index == e_FM_PCD_HDR_INDEX_1))
29605 + return CC_PC_FF_MPLS1;
29606 + if (index == e_FM_PCD_HDR_INDEX_LAST)
29607 + return CC_PC_FF_MPLS_LAST;
29608 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
29609 + return CC_PC_ILLEGAL;
29610 + default:
29611 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29612 + return CC_PC_ILLEGAL;
29613 + }
29614 +
29615 + case (HEADER_TYPE_IPv4):
29616 + switch (field.ipv4)
29617 + {
29618 + case (NET_HEADER_FIELD_IPv4_DST_IP):
29619 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29620 + || (index == e_FM_PCD_HDR_INDEX_1))
29621 + return CC_PC_FF_IPV4DST1;
29622 + if (index == e_FM_PCD_HDR_INDEX_2)
29623 + return CC_PC_FF_IPV4DST2;
29624 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29625 + return CC_PC_ILLEGAL;
29626 + case (NET_HEADER_FIELD_IPv4_TOS):
29627 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29628 + || (index == e_FM_PCD_HDR_INDEX_1))
29629 + return CC_PC_FF_IPV4IPTOS_TC1;
29630 + if (index == e_FM_PCD_HDR_INDEX_2)
29631 + return CC_PC_FF_IPV4IPTOS_TC2;
29632 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29633 + return CC_PC_ILLEGAL;
29634 + case (NET_HEADER_FIELD_IPv4_PROTO):
29635 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29636 + || (index == e_FM_PCD_HDR_INDEX_1))
29637 + return CC_PC_FF_IPV4PTYPE1;
29638 + if (index == e_FM_PCD_HDR_INDEX_2)
29639 + return CC_PC_FF_IPV4PTYPE2;
29640 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29641 + return CC_PC_ILLEGAL;
29642 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
29643 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29644 + || (index == e_FM_PCD_HDR_INDEX_1))
29645 + return CC_PC_FF_IPV4SRC1;
29646 + if (index == e_FM_PCD_HDR_INDEX_2)
29647 + return CC_PC_FF_IPV4SRC2;
29648 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29649 + return CC_PC_ILLEGAL;
29650 + case (NET_HEADER_FIELD_IPv4_SRC_IP
29651 + | NET_HEADER_FIELD_IPv4_DST_IP):
29652 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29653 + || (index == e_FM_PCD_HDR_INDEX_1))
29654 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
29655 + if (index == e_FM_PCD_HDR_INDEX_2)
29656 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
29657 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29658 + return CC_PC_ILLEGAL;
29659 + case (NET_HEADER_FIELD_IPv4_TTL):
29660 + return CC_PC_FF_IPV4TTL;
29661 + default:
29662 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29663 + return CC_PC_ILLEGAL;
29664 + }
29665 +
29666 + case (HEADER_TYPE_IPv6):
29667 + switch (field.ipv6)
29668 + {
29669 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
29670 + | NET_HEADER_FIELD_IPv6_TC):
29671 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29672 + || (index == e_FM_PCD_HDR_INDEX_1))
29673 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
29674 + if (index == e_FM_PCD_HDR_INDEX_2)
29675 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
29676 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
29677 + return CC_PC_ILLEGAL;
29678 +
29679 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
29680 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29681 + || (index == e_FM_PCD_HDR_INDEX_1))
29682 + return CC_PC_FF_IPV6PTYPE1;
29683 + if (index == e_FM_PCD_HDR_INDEX_2)
29684 + return CC_PC_FF_IPV6PTYPE2;
29685 + if (index == e_FM_PCD_HDR_INDEX_LAST)
29686 + return CC_PC_FF_IPPID;
29687 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
29688 + return CC_PC_ILLEGAL;
29689 +
29690 + case (NET_HEADER_FIELD_IPv6_DST_IP):
29691 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29692 + || (index == e_FM_PCD_HDR_INDEX_1))
29693 + return CC_PC_FF_IPV6DST1;
29694 + if (index == e_FM_PCD_HDR_INDEX_2)
29695 + return CC_PC_FF_IPV6DST2;
29696 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
29697 + return CC_PC_ILLEGAL;
29698 +
29699 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
29700 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29701 + || (index == e_FM_PCD_HDR_INDEX_1))
29702 + return CC_PC_FF_IPV6SRC1;
29703 + if (index == e_FM_PCD_HDR_INDEX_2)
29704 + return CC_PC_FF_IPV6SRC2;
29705 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
29706 + return CC_PC_ILLEGAL;
29707 +
29708 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
29709 + return CC_PC_FF_IPV6HOP_LIMIT;
29710 +
29711 + default:
29712 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29713 + return CC_PC_ILLEGAL;
29714 + }
29715 +
29716 + case (HEADER_TYPE_IP):
29717 + switch (field.ip)
29718 + {
29719 + case (NET_HEADER_FIELD_IP_DSCP):
29720 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29721 + || (index == e_FM_PCD_HDR_INDEX_1))
29722 + return CC_PC_FF_IPDSCP;
29723 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
29724 + return CC_PC_ILLEGAL;
29725 +
29726 + case (NET_HEADER_FIELD_IP_PROTO):
29727 + if (index == e_FM_PCD_HDR_INDEX_LAST)
29728 + return CC_PC_FF_IPPID;
29729 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
29730 + return CC_PC_ILLEGAL;
29731 +
29732 + default:
29733 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29734 + return CC_PC_ILLEGAL;
29735 + }
29736 +
29737 + case (HEADER_TYPE_GRE):
29738 + switch (field.gre)
29739 + {
29740 + case (NET_HEADER_FIELD_GRE_TYPE):
29741 + return CC_PC_FF_GREPTYPE;
29742 +
29743 + default:
29744 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29745 + return CC_PC_ILLEGAL;
29746 + }
29747 +
29748 + case (HEADER_TYPE_MINENCAP):
29749 + switch (field.minencap)
29750 + {
29751 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
29752 + return CC_PC_FF_MINENCAP_PTYPE;
29753 +
29754 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
29755 + return CC_PC_FF_MINENCAP_IPDST;
29756 +
29757 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
29758 + return CC_PC_FF_MINENCAP_IPSRC;
29759 +
29760 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
29761 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
29762 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
29763 +
29764 + default:
29765 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29766 + return CC_PC_ILLEGAL;
29767 + }
29768 +
29769 + case (HEADER_TYPE_TCP):
29770 + switch (field.tcp)
29771 + {
29772 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
29773 + return CC_PC_FF_L4PSRC;
29774 +
29775 + case (NET_HEADER_FIELD_TCP_PORT_DST):
29776 + return CC_PC_FF_L4PDST;
29777 +
29778 + case (NET_HEADER_FIELD_TCP_PORT_DST
29779 + | NET_HEADER_FIELD_TCP_PORT_SRC):
29780 + return CC_PC_FF_L4PSRC_L4PDST;
29781 +
29782 + default:
29783 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29784 + return CC_PC_ILLEGAL;
29785 + }
29786 +
29787 + case (HEADER_TYPE_PPPoE):
29788 + switch (field.pppoe)
29789 + {
29790 + case (NET_HEADER_FIELD_PPPoE_PID):
29791 + return CC_PC_FF_PPPPID;
29792 +
29793 + default:
29794 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29795 + return CC_PC_ILLEGAL;
29796 + }
29797 +
29798 + case (HEADER_TYPE_UDP):
29799 + switch (field.udp)
29800 + {
29801 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
29802 + return CC_PC_FF_L4PSRC;
29803 +
29804 + case (NET_HEADER_FIELD_UDP_PORT_DST):
29805 + return CC_PC_FF_L4PDST;
29806 +
29807 + case (NET_HEADER_FIELD_UDP_PORT_DST
29808 + | NET_HEADER_FIELD_UDP_PORT_SRC):
29809 + return CC_PC_FF_L4PSRC_L4PDST;
29810 +
29811 + default:
29812 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29813 + return CC_PC_ILLEGAL;
29814 + }
29815 +
29816 + default:
29817 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29818 + return CC_PC_ILLEGAL;
29819 + }
29820 +}
29821 +
29822 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
29823 + uint32_t offset, bool glblMask,
29824 + uint8_t *parseArrayOffset)
29825 +{
29826 + bool offsetRelevant = FALSE;
29827 +
29828 + if (offset)
29829 + offsetRelevant = TRUE;
29830 +
29831 + switch (hdr)
29832 + {
29833 + case (HEADER_TYPE_NONE):
29834 + ASSERT_COND(FALSE);
29835 + return CC_PC_ILLEGAL;
29836 +
29837 + case (HEADER_TYPE_ETH):
29838 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
29839 + break;
29840 +
29841 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
29842 + if (offset || glblMask)
29843 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
29844 + else
29845 + return CC_PC_PR_SHIM1;
29846 + break;
29847 +
29848 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
29849 + if (offset || glblMask)
29850 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
29851 + else
29852 + return CC_PC_PR_SHIM2;
29853 + break;
29854 +
29855 + case (HEADER_TYPE_LLC_SNAP):
29856 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
29857 + break;
29858 +
29859 + case (HEADER_TYPE_PPPoE):
29860 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
29861 + break;
29862 +
29863 + case (HEADER_TYPE_MPLS):
29864 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
29865 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
29866 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
29867 + else
29868 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
29869 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
29870 + else
29871 + {
29872 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
29873 + return CC_PC_ILLEGAL;
29874 + }
29875 + break;
29876 +
29877 + case (HEADER_TYPE_IPv4):
29878 + case (HEADER_TYPE_IPv6):
29879 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
29880 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
29881 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
29882 + else
29883 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
29884 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
29885 + else
29886 + {
29887 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
29888 + return CC_PC_ILLEGAL;
29889 + }
29890 + break;
29891 +
29892 + case (HEADER_TYPE_MINENCAP):
29893 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
29894 + break;
29895 +
29896 + case (HEADER_TYPE_GRE):
29897 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
29898 + break;
29899 +
29900 + case (HEADER_TYPE_TCP):
29901 + case (HEADER_TYPE_UDP):
29902 + case (HEADER_TYPE_IPSEC_AH):
29903 + case (HEADER_TYPE_IPSEC_ESP):
29904 + case (HEADER_TYPE_DCCP):
29905 + case (HEADER_TYPE_SCTP):
29906 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
29907 + break;
29908 +
29909 + default:
29910 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
29911 + return CC_PC_ILLEGAL;
29912 + }
29913 +
29914 + if (offsetRelevant)
29915 + return CC_PR_OFFSET;
29916 + else
29917 + return CC_PR_WITHOUT_OFFSET;
29918 +}
29919 +
29920 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
29921 + uint32_t offset, uint8_t *parseArrayOffset,
29922 + e_FmPcdHdrIndex hdrIndex)
29923 +{
29924 + bool offsetRelevant = FALSE;
29925 +
29926 + if (offset)
29927 + offsetRelevant = TRUE;
29928 +
29929 + switch (hdr)
29930 + {
29931 + case (HEADER_TYPE_NONE):
29932 + ASSERT_COND(FALSE);
29933 + break;
29934 + case (HEADER_TYPE_ETH):
29935 + switch (field.eth)
29936 + {
29937 + case (NET_HEADER_FIELD_ETH_TYPE):
29938 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
29939 + break;
29940 +
29941 + default:
29942 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29943 + return CC_PC_ILLEGAL;
29944 + }
29945 + break;
29946 +
29947 + case (HEADER_TYPE_VLAN):
29948 + switch (field.vlan)
29949 + {
29950 + case (NET_HEADER_FIELD_VLAN_TCI):
29951 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
29952 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
29953 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
29954 + else
29955 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
29956 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
29957 + break;
29958 +
29959 + default:
29960 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29961 + return CC_PC_ILLEGAL;
29962 + }
29963 + break;
29964 +
29965 + default:
29966 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
29967 + return CC_PC_ILLEGAL;
29968 + }
29969 +
29970 + if (offsetRelevant)
29971 + return CC_PR_OFFSET;
29972 + else
29973 + return CC_PR_WITHOUT_OFFSET;
29974 +}
29975 +
29976 +static void FillAdOfTypeResult(t_Handle h_Ad,
29977 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
29978 + t_FmPcd *p_FmPcd,
29979 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
29980 +{
29981 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
29982 + t_Handle h_TmpAd;
29983 + uint32_t tmp = 0, tmpNia = 0;
29984 + uint16_t profileId;
29985 + t_Handle p_AdNewPtr = NULL;
29986 + t_Error err = E_OK;
29987 +
29988 + /* There are 3 cases handled in this routine of building a "result" type AD.
29989 + * Case 1: No Manip. The action descriptor is built within the match table.
29990 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
29991 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
29992 + * initialized and returned here.
29993 + * p_AdResult (within the match table) will be initialized after
29994 + * this routine returns and point to the existing AD.
29995 + * Case 3: Manip exists. The action descriptor is built within the match table.
29996 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
29997 + *
29998 + * If statistics were enabled and the statistics mode of this node requires
29999 + * a statistics Ad, it will be placed after the result Ad and before the
30000 + * manip Ad, if manip Ad exists here.
30001 + */
30002 +
30003 + /* As default, the "new" ptr is the current one. i.e. the content of the result
30004 + * AD will be written into the match table itself (case (1))*/
30005 + p_AdNewPtr = p_AdResult;
30006 +
30007 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
30008 + if (p_FmPcdCcStatsParams)
30009 + {
30010 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
30011 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
30012 +
30013 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
30014 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
30015 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
30016 + h_Ad = h_TmpAd;
30017 +
30018 + p_AdNewPtr = h_Ad;
30019 + p_AdResult = h_Ad;
30020 +
30021 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
30022 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
30023 + }
30024 +
30025 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
30026 + if (p_CcNextEngineParams->h_Manip)
30027 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
30028 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
30029 +
30030 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
30031 + if (p_AdNewPtr)
30032 + {
30033 + /* case (1) and (2) */
30034 + switch (p_CcNextEngineParams->nextEngine)
30035 + {
30036 + case (e_FM_PCD_DONE):
30037 + if (p_CcNextEngineParams->params.enqueueParams.action
30038 + == e_FM_PCD_ENQ_FRAME)
30039 + {
30040 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
30041 + {
30042 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
30043 + tmp |=
30044 + p_CcNextEngineParams->params.enqueueParams.newFqid;
30045 +#if (DPAA_VERSION >= 11)
30046 + tmp |=
30047 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
30048 + & FM_PCD_AD_RESULT_VSP_MASK)
30049 + << FM_PCD_AD_RESULT_VSP_SHIFT;
30050 +#endif /* (DPAA_VERSION >= 11) */
30051 + }
30052 + else
30053 + {
30054 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
30055 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
30056 + }
30057 + }
30058 +
30059 + if (p_CcNextEngineParams->params.enqueueParams.action
30060 + == e_FM_PCD_DROP_FRAME)
30061 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
30062 + else
30063 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
30064 + break;
30065 +
30066 + case (e_FM_PCD_KG):
30067 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
30068 + {
30069 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
30070 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
30071 +#if (DPAA_VERSION >= 11)
30072 + tmp |=
30073 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
30074 + & FM_PCD_AD_RESULT_VSP_MASK)
30075 + << FM_PCD_AD_RESULT_VSP_SHIFT;
30076 +#endif /* (DPAA_VERSION >= 11) */
30077 + }
30078 + else
30079 + {
30080 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
30081 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
30082 + }
30083 + tmpNia = NIA_KG_DIRECT;
30084 + tmpNia |= NIA_ENG_KG;
30085 + tmpNia |= NIA_KG_CC_EN;
30086 + tmpNia |= FmPcdKgGetSchemeId(
30087 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
30088 + break;
30089 +
30090 + case (e_FM_PCD_PLCR):
30091 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
30092 + {
30093 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
30094 +
30095 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
30096 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
30097 + {
30098 + tmpNia |= NIA_PLCR_ABSOLUTE;
30099 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
30100 + (t_Handle)p_FmPcd,
30101 + e_FM_PCD_PLCR_SHARED,
30102 + NULL,
30103 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
30104 + &profileId);
30105 +
30106 + if (err != E_OK) {
30107 + REPORT_ERROR(MAJOR, err, NO_MSG);
30108 + return;
30109 + }
30110 +
30111 + }
30112 + else
30113 + profileId =
30114 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
30115 +
30116 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
30117 +#if (DPAA_VERSION >= 11)
30118 + tmp |=
30119 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
30120 + & FM_PCD_AD_RESULT_VSP_MASK)
30121 + << FM_PCD_AD_RESULT_VSP_SHIFT;
30122 +#endif /* (DPAA_VERSION >= 11) */
30123 + WRITE_UINT32(
30124 + p_AdResult->plcrProfile,
30125 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
30126 + }
30127 + else
30128 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
30129 +
30130 + tmpNia |=
30131 + NIA_ENG_PLCR
30132 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
30133 + break;
30134 +
30135 + default:
30136 + return;
30137 + }WRITE_UINT32(p_AdResult->fqid, tmp);
30138 +
30139 + if (p_CcNextEngineParams->h_Manip)
30140 + {
30141 + tmp = GET_UINT32(p_AdResult->plcrProfile);
30142 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
30143 + - (p_FmPcd->physicalMuramBase)) >> 4;
30144 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
30145 +
30146 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
30147 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
30148 + }
30149 +
30150 +#if (DPAA_VERSION >= 11)
30151 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
30152 +#endif /* (DPAA_VERSION >= 11) */
30153 + WRITE_UINT32(p_AdResult->nia, tmpNia);
30154 + }
30155 +}
30156 +
30157 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
30158 + t_Handle h_FmPort, t_Handle h_FmTree,
30159 + bool validate)
30160 +{
30161 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
30162 +
30163 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
30164 + p_CcTree->keyAndNextEngineParams,
30165 + p_CcTree->numOfEntries,
30166 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
30167 + h_FmTree, FALSE);
30168 +}
30169 +
30170 +
30171 +static void ReleaseNewNodeCommonPart(
30172 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30173 +{
30174 + if (p_AdditionalInfo->p_AdTableNew)
30175 + FM_MURAM_FreeMem(
30176 + FmPcdGetMuramHandle(
30177 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
30178 + p_AdditionalInfo->p_AdTableNew);
30179 +
30180 + if (p_AdditionalInfo->p_KeysMatchTableNew)
30181 + FM_MURAM_FreeMem(
30182 + FmPcdGetMuramHandle(
30183 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
30184 + p_AdditionalInfo->p_KeysMatchTableNew);
30185 +}
30186 +
30187 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
30188 + uint8_t *p_Mask)
30189 +{
30190 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
30191 +
30192 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
30193 + && !p_CcNode->lclMask)
30194 + {
30195 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
30196 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30197 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30198 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30199 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30200 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30201 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30202 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30203 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
30204 + {
30205 + p_CcNode->glblMaskSize = 0;
30206 + p_CcNode->lclMask = TRUE;
30207 + }
30208 + else
30209 + {
30210 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
30211 + p_CcNode->glblMaskUpdated = TRUE;
30212 + p_CcNode->glblMaskSize = 4;
30213 + }
30214 + }
30215 + else
30216 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
30217 + {
30218 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
30219 + {
30220 + p_CcNode->lclMask = TRUE;
30221 + p_CcNode->glblMaskSize = 0;
30222 + }
30223 + }
30224 + else
30225 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
30226 + {
30227 + uint32_t tmpMask = 0xffffffff;
30228 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
30229 + {
30230 + p_CcNode->lclMask = TRUE;
30231 + p_CcNode->glblMaskSize = 0;
30232 + }
30233 + }
30234 + else
30235 + if (p_Mask)
30236 + {
30237 + p_CcNode->lclMask = TRUE;
30238 + p_CcNode->glblMaskSize = 0;
30239 + }
30240 +
30241 + /* In static mode (maxNumOfKeys > 0), local mask is supported
30242 + only is mask support was enabled at initialization */
30243 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
30244 + {
30245 + p_CcNode->lclMask = FALSE;
30246 + p_CcNode->glblMaskSize = prvGlblMaskSize;
30247 + return ERROR_CODE(E_NOT_SUPPORTED);
30248 + }
30249 +
30250 + return E_OK;
30251 +}
30252 +
30253 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
30254 +{
30255 + t_FmPcd *p_FmPcd;
30256 + t_Handle h_Ad;
30257 +
30258 + if (isTree)
30259 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
30260 + else
30261 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
30262 +
30263 + if ((isTree && p_FmPcd->p_CcShadow)
30264 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
30265 + {
30266 + /* The allocated shadow is divided as follows:
30267 + 0 . . . 16 . . .
30268 + ---------------------------------------------------
30269 + | Shadow | Shadow Keys | Shadow Next |
30270 + | Ad | Match Table | Engine Table |
30271 + | (16 bytes) | (maximal size) | (maximal size) |
30272 + ---------------------------------------------------
30273 + */
30274 + if (!p_FmPcd->p_CcShadow)
30275 + {
30276 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
30277 + return NULL;
30278 + }
30279 +
30280 + h_Ad = p_FmPcd->p_CcShadow;
30281 + }
30282 + else
30283 + {
30284 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
30285 + FM_PCD_CC_AD_ENTRY_SIZE,
30286 + FM_PCD_CC_AD_TABLE_ALIGN);
30287 + if (!h_Ad)
30288 + {
30289 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
30290 + return NULL;
30291 + }
30292 + }
30293 +
30294 + return h_Ad;
30295 +}
30296 +
30297 +static t_Error BuildNewNodeCommonPart(
30298 + t_FmPcdCcNode *p_CcNode, int *size,
30299 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30300 +{
30301 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30302 +
30303 + if (p_CcNode->lclMask)
30304 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
30305 + else
30306 + *size = p_CcNode->ccKeySizeAccExtraction;
30307 +
30308 + if (p_CcNode->maxNumOfKeys == 0)
30309 + {
30310 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
30311 + FmPcdGetMuramHandle(p_FmPcd),
30312 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
30313 + * FM_PCD_CC_AD_ENTRY_SIZE),
30314 + FM_PCD_CC_AD_TABLE_ALIGN);
30315 + if (!p_AdditionalInfo->p_AdTableNew)
30316 + RETURN_ERROR(
30317 + MAJOR, E_NO_MEMORY,
30318 + ("MURAM allocation for CC node action descriptors table"));
30319 +
30320 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
30321 + FmPcdGetMuramHandle(p_FmPcd),
30322 + (uint32_t)(*size * sizeof(uint8_t)
30323 + * (p_AdditionalInfo->numOfKeys + 1)),
30324 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
30325 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
30326 + {
30327 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
30328 + p_AdditionalInfo->p_AdTableNew);
30329 + p_AdditionalInfo->p_AdTableNew = NULL;
30330 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30331 + ("MURAM allocation for CC node key match table"));
30332 + }
30333 +
30334 + MemSet8(
30335 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
30336 + 0,
30337 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
30338 + * FM_PCD_CC_AD_ENTRY_SIZE));
30339 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
30340 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
30341 + }
30342 + else
30343 + {
30344 + /* The allocated shadow is divided as follows:
30345 + 0 . . . 16 . . .
30346 + ---------------------------------------------------
30347 + | Shadow | Shadow Keys | Shadow Next |
30348 + | Ad | Match Table | Engine Table |
30349 + | (16 bytes) | (maximal size) | (maximal size) |
30350 + ---------------------------------------------------
30351 + */
30352 +
30353 + if (!p_FmPcd->p_CcShadow)
30354 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
30355 +
30356 + p_AdditionalInfo->p_KeysMatchTableNew =
30357 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
30358 + p_AdditionalInfo->p_AdTableNew =
30359 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
30360 +
30361 + MemSet8(
30362 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
30363 + 0,
30364 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30365 + * FM_PCD_CC_AD_ENTRY_SIZE));
30366 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
30367 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
30368 + }
30369 +
30370 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
30371 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
30372 +
30373 + return E_OK;
30374 +}
30375 +
30376 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
30377 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30378 + t_FmPcdCcKeyParams *p_KeyParams,
30379 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
30380 +{
30381 + t_Error err = E_OK;
30382 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
30383 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
30384 + int size;
30385 + int i = 0, j = 0;
30386 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
30387 + uint32_t requiredAction = 0;
30388 + bool prvLclMask;
30389 + t_CcNodeInformation *p_CcNodeInformation;
30390 + t_FmPcdCcStatsParams statsParams = { 0 };
30391 + t_List *p_Pos;
30392 + t_FmPcdStatsObj *p_StatsObj;
30393 +
30394 + /* Check that new NIA is legal */
30395 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
30396 + p_CcNode->statisticsMode);
30397 + if (err)
30398 + RETURN_ERROR(MAJOR, err, NO_MSG);
30399 +
30400 + prvLclMask = p_CcNode->lclMask;
30401 +
30402 + /* Check that new key is not require update of localMask */
30403 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
30404 + p_KeyParams->p_Mask);
30405 + if (err)
30406 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30407 +
30408 + /* Update internal data structure with new next engine for the given index */
30409 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
30410 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
30411 +
30412 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
30413 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
30414 +
30415 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30416 + == e_FM_PCD_CC)
30417 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
30418 + {
30419 + err =
30420 + AllocAndFillAdForContLookupManip(
30421 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
30422 + if (err)
30423 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30424 + }
30425 +
30426 + if (p_KeyParams->p_Mask)
30427 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
30428 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
30429 + else
30430 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
30431 + p_CcNode->userSizeOfExtraction);
30432 +
30433 + /* Update numOfKeys */
30434 + if (add)
30435 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
30436 + else
30437 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
30438 +
30439 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
30440 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
30441 + if (err)
30442 + RETURN_ERROR(MAJOR, err, NO_MSG);
30443 +
30444 + /* Check that manip is legal and what requiredAction is necessary for this manip */
30445 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30446 + {
30447 + err = FmPcdManipCheckParamsForCcNextEngine(
30448 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30449 + if (err)
30450 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30451 + }
30452 +
30453 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
30454 + requiredAction;
30455 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
30456 + UPDATE_CC_WITH_TREE;
30457 +
30458 + /* Update new Ad and new Key Table according to new requirement */
30459 + i = 0;
30460 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
30461 + {
30462 + p_AdTableNewTmp =
30463 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
30464 +
30465 + if (j == keyIndex)
30466 + {
30467 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
30468 + {
30469 + /* Allocate a statistics object that holds statistics AD and counters.
30470 + - For added key - New statistics AD and counters pointer need to be allocated
30471 + new statistics object. If statistics were enabled, we need to replace the
30472 + existing descriptor with a new descriptor with nullified counters.
30473 + */
30474 + p_StatsObj = GetStatsObj(p_CcNode);
30475 + ASSERT_COND(p_StatsObj);
30476 +
30477 + /* Store allocated statistics object */
30478 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
30479 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
30480 + p_StatsObj;
30481 +
30482 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
30483 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
30484 +#if (DPAA_VERSION >= 11)
30485 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
30486 +
30487 +#endif /* (DPAA_VERSION >= 11) */
30488 +
30489 + /* Building action descriptor for the received new key */
30490 + NextStepAd(p_AdTableNewTmp, &statsParams,
30491 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
30492 + }
30493 + else
30494 + {
30495 + /* Building action descriptor for the received new key */
30496 + NextStepAd(p_AdTableNewTmp, NULL,
30497 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
30498 + }
30499 +
30500 + /* Copy the received new key into keys match table */
30501 + p_KeysMatchTableNewTmp =
30502 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
30503 +
30504 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
30505 + p_CcNode->userSizeOfExtraction);
30506 +
30507 + /* Update mask for the received new key */
30508 + if (p_CcNode->lclMask)
30509 + {
30510 + if (p_KeyParams->p_Mask)
30511 + {
30512 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30513 + p_CcNode->ccKeySizeAccExtraction),
30514 + p_KeyParams->p_Mask,
30515 + p_CcNode->userSizeOfExtraction);
30516 + }
30517 + else
30518 + if (p_CcNode->ccKeySizeAccExtraction > 4)
30519 + {
30520 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
30521 + p_CcNode->ccKeySizeAccExtraction),
30522 + 0xff, p_CcNode->userSizeOfExtraction);
30523 + }
30524 + else
30525 + {
30526 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30527 + p_CcNode->ccKeySizeAccExtraction),
30528 + p_CcNode->p_GlblMask,
30529 + p_CcNode->userSizeOfExtraction);
30530 + }
30531 + }
30532 +
30533 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
30534 + if (!add)
30535 + i++;
30536 + }
30537 + else
30538 + {
30539 + /* Copy existing action descriptors to the newly allocated Ad table */
30540 + p_AdTableOldTmp =
30541 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
30542 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
30543 + FM_PCD_CC_AD_ENTRY_SIZE);
30544 +
30545 + /* Copy existing keys and their masks to the newly allocated keys match table */
30546 + p_KeysMatchTableNewTmp =
30547 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
30548 + p_KeysMatchTableOldTmp =
30549 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
30550 +
30551 + if (p_CcNode->lclMask)
30552 + {
30553 + if (prvLclMask)
30554 + {
30555 + MemCpy8(
30556 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
30557 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
30558 + p_CcNode->ccKeySizeAccExtraction);
30559 + }
30560 + else
30561 + {
30562 + p_KeysMatchTableOldTmp =
30563 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
30564 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
30565 +
30566 + if (p_CcNode->ccKeySizeAccExtraction > 4)
30567 + {
30568 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
30569 + p_CcNode->ccKeySizeAccExtraction),
30570 + 0xff, p_CcNode->userSizeOfExtraction);
30571 + }
30572 + else
30573 + {
30574 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30575 + p_CcNode->ccKeySizeAccExtraction),
30576 + p_CcNode->p_GlblMask,
30577 + p_CcNode->userSizeOfExtraction);
30578 + }
30579 + }
30580 + }
30581 +
30582 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
30583 + p_CcNode->ccKeySizeAccExtraction);
30584 +
30585 + i++;
30586 + }
30587 + }
30588 +
30589 + /* Miss action descriptor */
30590 + p_AdTableNewTmp =
30591 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
30592 + p_AdTableOldTmp =
30593 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
30594 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30595 +
30596 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
30597 + {
30598 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
30599 + {
30600 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
30601 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
30602 + /* Update the manipulation which has to be updated from parameters of the port */
30603 + /* It's has to be updated with restrictions defined in the function */
30604 + err =
30605 + SetRequiredAction(
30606 + p_CcNode->h_FmPcd,
30607 + p_CcNode->shadowAction
30608 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
30609 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
30610 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
30611 + 1, p_CcNodeInformation->h_CcNode);
30612 + if (err)
30613 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30614 +
30615 + err =
30616 + CcUpdateParam(
30617 + p_CcNode->h_FmPcd,
30618 + NULL,
30619 + NULL,
30620 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
30621 + 1,
30622 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
30623 + TRUE, p_CcNodeInformation->index,
30624 + p_CcNodeInformation->h_CcNode, TRUE);
30625 + if (err)
30626 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30627 + }
30628 + }
30629 +
30630 + if (p_CcNode->lclMask)
30631 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30632 +
30633 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
30634 + p_AdditionalInfo->h_NodeForAdd =
30635 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
30636 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30637 + p_AdditionalInfo->h_ManipForAdd =
30638 + p_KeyParams->ccNextEngineParams.h_Manip;
30639 +
30640 +#if (DPAA_VERSION >= 11)
30641 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
30642 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
30643 + p_AdditionalInfo->h_FrmReplicForAdd =
30644 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
30645 +#endif /* (DPAA_VERSION >= 11) */
30646 +
30647 + if (!add)
30648 + {
30649 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30650 + == e_FM_PCD_CC)
30651 + p_AdditionalInfo->h_NodeForRmv =
30652 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
30653 +
30654 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
30655 + p_AdditionalInfo->h_ManipForRmv =
30656 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
30657 +
30658 + /* If statistics were previously enabled, store the old statistics object to be released */
30659 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30660 + {
30661 + p_AdditionalInfo->p_StatsObjForRmv =
30662 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
30663 + }
30664 +
30665 +#if (DPAA_VERSION >= 11)
30666 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30667 + == e_FM_PCD_FR)
30668 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
30669 + p_AdditionalInfo->h_FrmReplicForRmv =
30670 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
30671 +#endif /* (DPAA_VERSION >= 11) */
30672 + }
30673 +
30674 + return E_OK;
30675 +}
30676 +
30677 +static t_Error BuildNewNodeRemoveKey(
30678 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30679 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30680 +{
30681 + int i = 0, j = 0;
30682 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
30683 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
30684 + int size;
30685 + t_Error err = E_OK;
30686 +
30687 + /*save new numOfKeys*/
30688 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
30689 +
30690 + /*function which allocates in the memory new KeyTbl, AdTbl*/
30691 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
30692 + if (err)
30693 + RETURN_ERROR(MAJOR, err, NO_MSG);
30694 +
30695 + /*update new Ad and new Key Table according to new requirement*/
30696 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
30697 + {
30698 + if (j == keyIndex)
30699 + j++;
30700 +
30701 + if (j == p_CcNode->numOfKeys)
30702 + break;
30703 + p_AdTableNewTmp =
30704 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
30705 + p_AdTableOldTmp =
30706 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
30707 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30708 +
30709 + p_KeysMatchTableOldTmp =
30710 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
30711 + p_KeysMatchTableNewTmp =
30712 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
30713 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
30714 + size * sizeof(uint8_t));
30715 + }
30716 +
30717 + p_AdTableNewTmp =
30718 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
30719 + p_AdTableOldTmp =
30720 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
30721 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30722 +
30723 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30724 + == e_FM_PCD_CC)
30725 + p_AdditionalInfo->h_NodeForRmv =
30726 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
30727 +
30728 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
30729 + p_AdditionalInfo->h_ManipForRmv =
30730 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
30731 +
30732 + /* If statistics were previously enabled, store the old statistics object to be released */
30733 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30734 + {
30735 + p_AdditionalInfo->p_StatsObjForRmv =
30736 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
30737 + }
30738 +
30739 +#if (DPAA_VERSION >= 11)
30740 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30741 + == e_FM_PCD_FR)
30742 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
30743 + p_AdditionalInfo->h_FrmReplicForRmv =
30744 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
30745 +#endif /* (DPAA_VERSION >= 11) */
30746 +
30747 + return E_OK;
30748 +}
30749 +
30750 +static t_Error BuildNewNodeModifyKey(
30751 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
30752 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30753 +{
30754 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30755 + t_Error err = E_OK;
30756 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
30757 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
30758 + int size;
30759 + int i = 0, j = 0;
30760 + bool prvLclMask;
30761 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
30762 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
30763 +
30764 + prvLclMask = p_CcNode->lclMask;
30765 +
30766 + /* Check that new key is not require update of localMask */
30767 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
30768 + if (err)
30769 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30770 +
30771 + /* Update internal data structure with new next engine for the given index */
30772 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
30773 + p_CcNode->userSizeOfExtraction);
30774 +
30775 + if (p_Mask)
30776 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
30777 + p_CcNode->userSizeOfExtraction);
30778 + else
30779 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
30780 + p_CcNode->userSizeOfExtraction);
30781 +
30782 + /*function which build in the memory new KeyTbl, AdTbl*/
30783 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
30784 + if (err)
30785 + RETURN_ERROR(MAJOR, err, NO_MSG);
30786 +
30787 + /*fill the New AdTable and New KeyTable*/
30788 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
30789 + {
30790 + p_AdTableNewTmp =
30791 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
30792 + p_AdTableOldTmp =
30793 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
30794 +
30795 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30796 +
30797 + if (j == keyIndex)
30798 + {
30799 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
30800 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30801 + {
30802 + /* As statistics were enabled, we need to update the existing
30803 + statistics descriptor with a new nullified counters. */
30804 + p_StatsObj = GetStatsObj(p_CcNode);
30805 + ASSERT_COND(p_StatsObj);
30806 +
30807 + SetStatsCounters(
30808 + p_AdTableNewTmp,
30809 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
30810 + - p_FmPcd->physicalMuramBase)));
30811 +
30812 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
30813 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
30814 +
30815 + /* As we need to replace only the counters, we build a new statistics
30816 + object that holds the old AD and the new counters - this will be the
30817 + currently used statistics object.
30818 + The newly allocated AD is not required and may be released back to
30819 + the available objects with the previous counters pointer. */
30820 + p_StatsObj->h_StatsAd =
30821 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
30822 +
30823 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
30824 + tmpStatsObj.h_StatsAd;
30825 +
30826 + /* Store allocated statistics object */
30827 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
30828 + p_StatsObj;
30829 +
30830 + /* As statistics were previously enabled, store the old statistics object to be released */
30831 + p_AdditionalInfo->p_StatsObjForRmv =
30832 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
30833 + }
30834 +
30835 + p_KeysMatchTableNewTmp =
30836 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
30837 +
30838 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
30839 + p_CcNode->userSizeOfExtraction);
30840 +
30841 + if (p_CcNode->lclMask)
30842 + {
30843 + if (p_Mask)
30844 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30845 + p_CcNode->ccKeySizeAccExtraction),
30846 + p_Mask, p_CcNode->userSizeOfExtraction);
30847 + else
30848 + if (p_CcNode->ccKeySizeAccExtraction > 4)
30849 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
30850 + p_CcNode->ccKeySizeAccExtraction),
30851 + 0xff, p_CcNode->userSizeOfExtraction);
30852 + else
30853 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30854 + p_CcNode->ccKeySizeAccExtraction),
30855 + p_CcNode->p_GlblMask,
30856 + p_CcNode->userSizeOfExtraction);
30857 + }
30858 + }
30859 + else
30860 + {
30861 + p_KeysMatchTableNewTmp =
30862 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
30863 + p_KeysMatchTableOldTmp =
30864 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
30865 +
30866 + if (p_CcNode->lclMask)
30867 + {
30868 + if (prvLclMask)
30869 + MemCpy8(
30870 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
30871 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
30872 + p_CcNode->userSizeOfExtraction);
30873 + else
30874 + {
30875 + p_KeysMatchTableOldTmp =
30876 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
30877 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
30878 +
30879 + if (p_CcNode->ccKeySizeAccExtraction > 4)
30880 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
30881 + p_CcNode->ccKeySizeAccExtraction),
30882 + 0xff, p_CcNode->userSizeOfExtraction);
30883 + else
30884 + MemCpy8(
30885 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
30886 + p_CcNode->p_GlblMask,
30887 + p_CcNode->userSizeOfExtraction);
30888 + }
30889 + }
30890 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
30891 + p_CcNode->ccKeySizeAccExtraction);
30892 + }
30893 + }
30894 +
30895 + p_AdTableNewTmp =
30896 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
30897 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
30898 +
30899 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30900 +
30901 + return E_OK;
30902 +}
30903 +
30904 +static t_Error BuildNewNodeModifyNextEngine(
30905 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
30906 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
30907 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30908 +{
30909 + t_Error err = E_OK;
30910 + uint32_t requiredAction = 0;
30911 + t_List *p_Pos;
30912 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
30913 + t_Handle p_Ad;
30914 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
30915 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
30916 + t_FmPcdStatsObj *p_StatsObj;
30917 + t_FmPcdCcStatsParams statsParams = { 0 };
30918 +
30919 + ASSERT_COND(p_CcNextEngineParams);
30920 +
30921 + /* check that new NIA is legal */
30922 + if (!p_AdditionalInfo->tree)
30923 + err = ValidateNextEngineParams(
30924 + h_FmPcd, p_CcNextEngineParams,
30925 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
30926 + else
30927 + /* Statistics are not supported for CC root */
30928 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
30929 + e_FM_PCD_CC_STATS_MODE_NONE);
30930 + if (err)
30931 + RETURN_ERROR(MAJOR, err, NO_MSG);
30932 +
30933 + /* Update internal data structure for next engine per index (index - key) */
30934 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
30935 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
30936 +
30937 + /* Check that manip is legal and what requiredAction is necessary for this manip */
30938 + if (p_CcNextEngineParams->h_Manip)
30939 + {
30940 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
30941 + &requiredAction);
30942 + if (err)
30943 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30944 + }
30945 +
30946 + if (!p_AdditionalInfo->tree)
30947 + {
30948 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
30949 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
30950 + p_Ad = p_FmPcdCcNode1->h_AdTable;
30951 +
30952 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30953 + == e_FM_PCD_CC)
30954 + p_AdditionalInfo->h_NodeForRmv =
30955 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
30956 +
30957 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
30958 + p_AdditionalInfo->h_ManipForRmv =
30959 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
30960 +
30961 +#if (DPAA_VERSION >= 11)
30962 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30963 + == e_FM_PCD_FR)
30964 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
30965 + p_AdditionalInfo->h_FrmReplicForRmv =
30966 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
30967 +#endif /* (DPAA_VERSION >= 11) */
30968 + }
30969 + else
30970 + {
30971 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
30972 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
30973 +
30974 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30975 + == e_FM_PCD_CC)
30976 + p_AdditionalInfo->h_NodeForRmv =
30977 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
30978 +
30979 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
30980 + p_AdditionalInfo->h_ManipForRmv =
30981 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
30982 +
30983 +#if (DPAA_VERSION >= 11)
30984 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30985 + == e_FM_PCD_FR)
30986 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
30987 + p_AdditionalInfo->h_FrmReplicForRmv =
30988 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
30989 +#endif /* (DPAA_VERSION >= 11) */
30990 + }
30991 +
30992 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
30993 + && p_CcNextEngineParams->h_Manip)
30994 + {
30995 + err = AllocAndFillAdForContLookupManip(
30996 + p_CcNextEngineParams->params.ccParams.h_CcNode);
30997 + if (err)
30998 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30999 + }
31000 +
31001 + ASSERT_COND(p_Ad);
31002 +
31003 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31004 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
31005 +
31006 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
31007 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
31008 + only the actual Nia-Ad should be modified. */
31009 + if ((!p_AdditionalInfo->tree)
31010 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
31011 + && (p_CcNextEngineParams->statisticsEn))
31012 + ccNodeInfo.h_CcNode =
31013 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
31014 +
31015 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
31016 +
31017 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31018 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
31019 + if (!p_Ad)
31020 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31021 + ("MURAM allocation for CC node action descriptor"));
31022 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
31023 +
31024 + /* If statistics were not enabled before, but requested now - Allocate a statistics
31025 + object that holds statistics AD and counters. */
31026 + if ((!p_AdditionalInfo->tree)
31027 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
31028 + && (p_CcNextEngineParams->statisticsEn))
31029 + {
31030 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
31031 + ASSERT_COND(p_StatsObj);
31032 +
31033 + /* Store allocated statistics object */
31034 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
31035 + p_StatsObj;
31036 +
31037 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31038 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31039 +
31040 +#if (DPAA_VERSION >= 11)
31041 + statsParams.h_StatsFLRs =
31042 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
31043 +
31044 +#endif /* (DPAA_VERSION >= 11) */
31045 +
31046 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
31047 + }
31048 + else
31049 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
31050 +
31051 + ccNodeInfo.h_CcNode = p_Ad;
31052 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
31053 +
31054 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
31055 + requiredAction;
31056 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
31057 + UPDATE_CC_WITH_TREE;
31058 +
31059 + if (!p_AdditionalInfo->tree)
31060 + {
31061 + ASSERT_COND(p_FmPcdCcNode1);
31062 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
31063 + {
31064 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
31065 + {
31066 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
31067 +
31068 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
31069 + /* Update the manipulation which has to be updated from parameters of the port
31070 + it's has to be updated with restrictions defined in the function */
31071 +
31072 + err =
31073 + SetRequiredAction(
31074 + p_FmPcdCcNode1->h_FmPcd,
31075 + p_FmPcdCcNode1->shadowAction
31076 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
31077 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
31078 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
31079 + if (err)
31080 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31081 +
31082 + err = CcUpdateParam(
31083 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
31084 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
31085 + p_Ad, TRUE, p_CcNodeInformation->index,
31086 + p_CcNodeInformation->h_CcNode, TRUE);
31087 + if (err)
31088 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31089 + }
31090 + }
31091 + }
31092 + else
31093 + {
31094 + ASSERT_COND(p_FmPcdCcTree);
31095 +
31096 + err =
31097 + SetRequiredAction(
31098 + h_FmPcd,
31099 + p_FmPcdCcTree->requiredAction
31100 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
31101 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
31102 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
31103 + if (err)
31104 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31105 +
31106 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
31107 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
31108 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
31109 + if (err)
31110 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31111 + }
31112 +
31113 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
31114 + p_AdditionalInfo->h_NodeForAdd =
31115 + p_CcNextEngineParams->params.ccParams.h_CcNode;
31116 + if (p_CcNextEngineParams->h_Manip)
31117 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
31118 +
31119 + /* If statistics were previously enabled, but now are disabled,
31120 + store the old statistics object to be released */
31121 + if ((!p_AdditionalInfo->tree)
31122 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
31123 + && (!p_CcNextEngineParams->statisticsEn))
31124 + {
31125 + p_AdditionalInfo->p_StatsObjForRmv =
31126 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
31127 +
31128 +
31129 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
31130 + }
31131 +#if (DPAA_VERSION >= 11)
31132 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
31133 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
31134 + p_AdditionalInfo->h_FrmReplicForAdd =
31135 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
31136 +#endif /* (DPAA_VERSION >= 11) */
31137 +
31138 + return E_OK;
31139 +}
31140 +
31141 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
31142 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
31143 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
31144 +{
31145 + t_CcNodeInformation *p_CcNodeInformation;
31146 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
31147 + t_List *p_Pos;
31148 + int i = 0;
31149 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
31150 + t_CcNodeInformation ccNodeInfo;
31151 +
31152 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
31153 + {
31154 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
31155 + p_NodePtrOnCurrentMdfNode =
31156 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
31157 +
31158 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
31159 +
31160 + /* Search in the previous node which exact index points on this current modified node for getting AD */
31161 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
31162 + {
31163 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
31164 + == e_FM_PCD_CC)
31165 + {
31166 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
31167 + == (t_Handle)p_CrntMdfNode)
31168 + {
31169 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
31170 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
31171 + else
31172 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
31173 + p_AdTablePtOnCrntCurrentMdfNode =
31174 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
31175 + else
31176 + p_AdTablePtOnCrntCurrentMdfNode =
31177 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
31178 +
31179 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31180 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
31181 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
31182 +
31183 + if (!(*p_NextEngineParams))
31184 + *p_NextEngineParams =
31185 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
31186 + }
31187 + }
31188 + }
31189 +
31190 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
31191 + }
31192 +}
31193 +
31194 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
31195 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
31196 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
31197 +{
31198 + t_CcNodeInformation *p_CcNodeInformation;
31199 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
31200 + t_List *p_Pos;
31201 + int i = 0;
31202 + t_Handle p_AdTableTmp;
31203 + t_CcNodeInformation ccNodeInfo;
31204 +
31205 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
31206 + {
31207 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
31208 + p_TreePtrOnCurrentMdfNode =
31209 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
31210 +
31211 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
31212 +
31213 + /*search in the trees which exact index points on this current modified node for getting AD */
31214 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
31215 + {
31216 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
31217 + == e_FM_PCD_CC)
31218 + {
31219 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
31220 + == (t_Handle)p_CrntMdfNode)
31221 + {
31222 + p_AdTableTmp =
31223 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
31224 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31225 + ccNodeInfo.h_CcNode = p_AdTableTmp;
31226 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
31227 +
31228 + if (!(*p_NextEngineParams))
31229 + *p_NextEngineParams =
31230 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
31231 + }
31232 + }
31233 + }
31234 +
31235 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
31236 + }
31237 +}
31238 +
31239 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
31240 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
31241 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
31242 +{
31243 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
31244 + int i = 0, j = 0;
31245 + bool wasUpdate = FALSE;
31246 + t_FmPcdCcNode *p_CcNode = NULL;
31247 + t_FmPcdCcTree *p_FmPcdCcTree;
31248 + uint16_t numOfKeys;
31249 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
31250 +
31251 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
31252 +
31253 + if (!tree)
31254 + {
31255 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
31256 + numOfKeys = p_CcNode->numOfKeys;
31257 +
31258 + /* node has to be pointed by another node or tree */
31259 +
31260 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
31261 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
31262 + if (!p_KeyAndNextEngineParams)
31263 + {
31264 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
31265 + return NULL;
31266 + }
31267 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
31268 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
31269 +
31270 + if (ttlCheck)
31271 + {
31272 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
31273 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
31274 + {
31275 + XX_Free(p_KeyAndNextEngineParams);
31276 + 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"));
31277 + return NULL;
31278 + }
31279 + }
31280 +
31281 + if (hashCheck)
31282 + {
31283 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
31284 + {
31285 + XX_Free(p_KeyAndNextEngineParams);
31286 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
31287 + return NULL;
31288 + }
31289 + }
31290 + }
31291 + else
31292 + {
31293 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
31294 + numOfKeys = p_FmPcdCcTree->numOfEntries;
31295 +
31296 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
31297 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
31298 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
31299 + if (!p_KeyAndNextEngineParams)
31300 + {
31301 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
31302 + return NULL;
31303 + }
31304 + memcpy(p_KeyAndNextEngineParams,
31305 + p_FmPcdCcTree->keyAndNextEngineParams,
31306 + FM_PCD_MAX_NUM_OF_CC_GROUPS
31307 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
31308 + }
31309 +
31310 + p_FmPcdModifyCcKeyAdditionalParams =
31311 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
31312 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
31313 + if (!p_FmPcdModifyCcKeyAdditionalParams)
31314 + {
31315 + XX_Free(p_KeyAndNextEngineParams);
31316 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
31317 + return NULL;
31318 + }
31319 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
31320 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
31321 +
31322 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
31323 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
31324 +
31325 + while (i < numOfKeys)
31326 + {
31327 + if ((j == keyIndex) && !wasUpdate)
31328 + {
31329 + if (modifyState == e_MODIFY_STATE_ADD)
31330 + j++;
31331 + else
31332 + if (modifyState == e_MODIFY_STATE_REMOVE)
31333 + i++;
31334 + wasUpdate = TRUE;
31335 + }
31336 + else
31337 + {
31338 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
31339 + p_KeyAndNextEngineParams + i,
31340 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
31341 + i++;
31342 + j++;
31343 + }
31344 + }
31345 +
31346 + if (keyIndex == numOfKeys)
31347 + {
31348 + if (modifyState == e_MODIFY_STATE_ADD)
31349 + j++;
31350 + }
31351 +
31352 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
31353 + p_KeyAndNextEngineParams + numOfKeys,
31354 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
31355 +
31356 + XX_Free(p_KeyAndNextEngineParams);
31357 +
31358 + return p_FmPcdModifyCcKeyAdditionalParams;
31359 +}
31360 +
31361 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
31362 + t_FmPcdCcNode *p_CcNode,
31363 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
31364 + t_List *h_OldLst, t_List *h_NewLst)
31365 +{
31366 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
31367 + t_CcNodeInformation ccNodeInfo = { 0 };
31368 + t_Handle h_NewAd;
31369 + t_Handle h_OrigAd = NULL;
31370 +
31371 + /* Building a list of all action descriptors that point to the previous node */
31372 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
31373 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
31374 + &p_NextEngineParams);
31375 +
31376 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
31377 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
31378 + &p_NextEngineParams);
31379 +
31380 + /* This node must be found as next engine of one of its previous nodes or trees*/
31381 + if (p_NextEngineParams)
31382 + {
31383 + /* Building a new action descriptor that points to the modified node */
31384 + h_NewAd = GetNewAd(p_CcNode, FALSE);
31385 + if (!h_NewAd)
31386 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
31387 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
31388 +
31389 + h_OrigAd = p_CcNode->h_Ad;
31390 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
31391 + p_NextEngineParams);
31392 +
31393 + ccNodeInfo.h_CcNode = h_NewAd;
31394 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
31395 +
31396 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
31397 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
31398 + }
31399 + return E_OK;
31400 +}
31401 +
31402 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
31403 +{
31404 + ASSERT_COND(p_FmPcdCcTree);
31405 +
31406 + /* this routine must be protected by the calling routine! */
31407 +
31408 + if (add)
31409 + p_FmPcdCcTree->owners++;
31410 + else
31411 + {
31412 + ASSERT_COND(p_FmPcdCcTree->owners);
31413 + p_FmPcdCcTree->owners--;
31414 + }
31415 +}
31416 +
31417 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
31418 +{
31419 + t_Error err = E_OK;
31420 + int i = 0;
31421 +
31422 + for (i = 0; i < p_CcNode->numOfKeys; i++)
31423 + {
31424 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
31425 + {
31426 + err =
31427 + FmPcdManipCheckParamsWithCcNodeParams(
31428 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
31429 + (t_Handle)p_CcNode);
31430 + if (err)
31431 + return err;
31432 + }
31433 + }
31434 +
31435 + return err;
31436 +}
31437 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
31438 + t_FmPcdCcNodeParams *p_CcNodeParam,
31439 + uint32_t *p_NumOfRanges,
31440 + uint32_t *p_CountersArraySize)
31441 +{
31442 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
31443 + uint32_t i;
31444 +
31445 + UNUSED(p_CcNodeParam);
31446 +
31447 + switch (statisticsMode)
31448 + {
31449 + case e_FM_PCD_CC_STATS_MODE_NONE:
31450 + for (i = 0; i < p_CcNode->numOfKeys; i++)
31451 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
31452 + RETURN_ERROR(
31453 + MAJOR,
31454 + E_INVALID_VALUE,
31455 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
31456 + return E_OK;
31457 +
31458 + case e_FM_PCD_CC_STATS_MODE_FRAME:
31459 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
31460 + *p_NumOfRanges = 1;
31461 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
31462 + return E_OK;
31463 +
31464 +#if (DPAA_VERSION >= 11)
31465 + case e_FM_PCD_CC_STATS_MODE_RMON:
31466 + {
31467 + uint16_t *p_FrameLengthRanges =
31468 + p_CcNodeParam->keysParams.frameLengthRanges;
31469 + uint32_t i;
31470 +
31471 + if (p_FrameLengthRanges[0] <= 0)
31472 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
31473 +
31474 + if (p_FrameLengthRanges[0] == 0xFFFF)
31475 + {
31476 + *p_NumOfRanges = 1;
31477 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
31478 + return E_OK;
31479 + }
31480 +
31481 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
31482 + {
31483 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
31484 + RETURN_ERROR(
31485 + MAJOR,
31486 + E_INVALID_VALUE,
31487 + ("Frame length range must be larger at least by 1 from preceding range"));
31488 +
31489 + /* Stop when last range is reached */
31490 + if (p_FrameLengthRanges[i] == 0xFFFF)
31491 + break;
31492 + }
31493 +
31494 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
31495 + || (p_FrameLengthRanges[i] != 0xFFFF))
31496 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31497 + ("Last Frame length range must be 0xFFFF"));
31498 +
31499 + *p_NumOfRanges = i + 1;
31500 +
31501 + /* Allocate an extra counter for byte count, as counters
31502 + array always begins with byte count */
31503 + *p_CountersArraySize = (*p_NumOfRanges + 1)
31504 + * FM_PCD_CC_STATS_COUNTER_SIZE;
31505 +
31506 + }
31507 + return E_OK;
31508 +#endif /* (DPAA_VERSION >= 11) */
31509 +
31510 + default:
31511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
31512 + }
31513 +}
31514 +
31515 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
31516 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
31517 +{
31518 + int tmp = 0;
31519 + t_FmPcdCcKeyParams *p_KeyParams;
31520 + t_Error err;
31521 + uint32_t requiredAction = 0;
31522 +
31523 + /* Validate statistics parameters */
31524 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
31525 + &(p_CcNode->numOfStatsFLRs),
31526 + &(p_CcNode->countersArraySize));
31527 + if (err)
31528 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
31529 +
31530 + /* Validate next engine parameters on Miss */
31531 + err = ValidateNextEngineParams(
31532 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31533 + p_CcNode->statisticsMode);
31534 + if (err)
31535 + RETURN_ERROR(MAJOR, err,
31536 + ("For this node MissNextEngineParams are not valid"));
31537 +
31538 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
31539 + {
31540 + err = FmPcdManipCheckParamsForCcNextEngine(
31541 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31542 + &requiredAction);
31543 + if (err)
31544 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31545 + }
31546 +
31547 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
31548 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31549 + sizeof(t_FmPcdCcNextEngineParams));
31550 +
31551 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
31552 + requiredAction;
31553 +
31554 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
31555 + == e_FM_PCD_CC)
31556 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
31557 + {
31558 + err =
31559 + AllocAndFillAdForContLookupManip(
31560 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
31561 + if (err)
31562 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31563 + }
31564 +
31565 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31566 + {
31567 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31568 +
31569 + if (!p_KeyParams->p_Key)
31570 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
31571 +
31572 + err = ValidateNextEngineParams(h_FmPcd,
31573 + &p_KeyParams->ccNextEngineParams,
31574 + p_CcNode->statisticsMode);
31575 + if (err)
31576 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31577 +
31578 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
31579 + p_KeyParams->p_Mask);
31580 + if (err)
31581 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31582 +
31583 + if (p_KeyParams->ccNextEngineParams.h_Manip)
31584 + {
31585 + err = FmPcdManipCheckParamsForCcNextEngine(
31586 + &p_KeyParams->ccNextEngineParams, &requiredAction);
31587 + if (err)
31588 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31589 + }
31590 +
31591 + /* Store 'key' parameters - key, mask (if passed by the user) */
31592 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
31593 + p_CcNodeParam->keysParams.keySize);
31594 +
31595 + if (p_KeyParams->p_Mask)
31596 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
31597 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
31598 + else
31599 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
31600 + p_CcNodeParam->keysParams.keySize);
31601 +
31602 + /* Store next engine parameters */
31603 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
31604 + &p_KeyParams->ccNextEngineParams,
31605 + sizeof(t_FmPcdCcNextEngineParams));
31606 +
31607 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
31608 +
31609 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31610 + == e_FM_PCD_CC)
31611 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31612 + {
31613 + err =
31614 + AllocAndFillAdForContLookupManip(
31615 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
31616 + if (err)
31617 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31618 + }
31619 + }
31620 +
31621 + if (p_CcNode->maxNumOfKeys)
31622 + {
31623 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
31624 + RETURN_ERROR(
31625 + MAJOR,
31626 + E_INVALID_VALUE,
31627 + ("Number of keys exceed the provided maximal number of keys"));
31628 + }
31629 +
31630 + *isKeyTblAlloc = TRUE;
31631 +
31632 + return E_OK;
31633 +}
31634 +
31635 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
31636 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
31637 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
31638 +{
31639 + int tmp = 0;
31640 + t_FmPcdCcKeyParams *p_KeyParams;
31641 + t_Error err;
31642 + uint8_t key = 0x01;
31643 + uint32_t requiredAction = 0;
31644 +
31645 + if (p_CcNode->numOfKeys != 1)
31646 + RETURN_ERROR(
31647 + MAJOR,
31648 + E_INVALID_VALUE,
31649 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
31650 +
31651 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
31652 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
31653 + RETURN_ERROR(
31654 + MAJOR,
31655 + E_INVALID_VALUE,
31656 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
31657 +
31658 + /* Validate statistics parameters */
31659 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
31660 + &(p_CcNode->numOfStatsFLRs),
31661 + &(p_CcNode->countersArraySize));
31662 + if (err)
31663 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
31664 +
31665 + err = ValidateNextEngineParams(
31666 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31667 + p_CcNodeParam->keysParams.statisticsMode);
31668 + if (err)
31669 + RETURN_ERROR(MAJOR, err,
31670 + ("For this node MissNextEngineParams are not valid"));
31671 +
31672 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
31673 + {
31674 + err = FmPcdManipCheckParamsForCcNextEngine(
31675 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31676 + &requiredAction);
31677 + if (err)
31678 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31679 + }
31680 +
31681 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
31682 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31683 + sizeof(t_FmPcdCcNextEngineParams));
31684 +
31685 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
31686 + requiredAction;
31687 +
31688 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
31689 + == e_FM_PCD_CC)
31690 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
31691 + {
31692 + err =
31693 + AllocAndFillAdForContLookupManip(
31694 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
31695 + if (err)
31696 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31697 + }
31698 +
31699 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31700 + {
31701 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31702 +
31703 + if (p_KeyParams->p_Mask)
31704 + RETURN_ERROR(
31705 + MAJOR,
31706 + E_INVALID_VALUE,
31707 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
31708 +
31709 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
31710 + RETURN_ERROR(
31711 + MAJOR,
31712 + E_INVALID_VALUE,
31713 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
31714 +
31715 + err = ValidateNextEngineParams(h_FmPcd,
31716 + &p_KeyParams->ccNextEngineParams,
31717 + p_CcNode->statisticsMode);
31718 + if (err)
31719 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31720 +
31721 + if (p_KeyParams->ccNextEngineParams.h_Manip)
31722 + {
31723 + err = FmPcdManipCheckParamsForCcNextEngine(
31724 + &p_KeyParams->ccNextEngineParams, &requiredAction);
31725 + if (err)
31726 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31727 + }
31728 +
31729 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
31730 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
31731 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
31732 +
31733 + /* Store NextEngine parameters */
31734 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
31735 + &p_KeyParams->ccNextEngineParams,
31736 + sizeof(t_FmPcdCcNextEngineParams));
31737 +
31738 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31739 + == e_FM_PCD_CC)
31740 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31741 + {
31742 + err =
31743 + AllocAndFillAdForContLookupManip(
31744 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
31745 + if (err)
31746 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31747 + }
31748 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
31749 + }
31750 +
31751 + *isKeyTblAlloc = FALSE;
31752 +
31753 + return E_OK;
31754 +}
31755 +
31756 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
31757 + t_FmPcdCcNodeParams *p_CcNodeParam,
31758 + t_FmPcdCcNode *p_CcNode,
31759 + bool *isKeyTblAlloc)
31760 +{
31761 + int tmp = 0, countOnes = 0;
31762 + t_FmPcdCcKeyParams *p_KeyParams;
31763 + t_Error err;
31764 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
31765 + uint16_t countMask = (uint16_t)(glblMask >> 4);
31766 + uint32_t requiredAction = 0;
31767 +
31768 + if (glblMask & 0x000f)
31769 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31770 + ("icIndxMask has to be with last nibble 0"));
31771 +
31772 + while (countMask)
31773 + {
31774 + countOnes++;
31775 + countMask = (uint16_t)(countMask >> 1);
31776 + }
31777 +
31778 + if (!POWER_OF_2(p_CcNode->numOfKeys))
31779 + RETURN_ERROR(
31780 + MAJOR,
31781 + E_INVALID_VALUE,
31782 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
31783 +
31784 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
31785 + RETURN_ERROR(
31786 + MAJOR,
31787 + E_INVALID_VALUE,
31788 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
31789 +
31790 + if (p_CcNodeParam->keysParams.maxNumOfKeys
31791 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
31792 + RETURN_ERROR(
31793 + MAJOR,
31794 + E_INVALID_VALUE,
31795 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
31796 +
31797 + /* Validate statistics parameters */
31798 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
31799 + &(p_CcNode->numOfStatsFLRs),
31800 + &(p_CcNode->countersArraySize));
31801 + if (err)
31802 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
31803 +
31804 + err = ValidateNextEngineParams(
31805 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31806 + p_CcNode->statisticsMode);
31807 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
31808 + RETURN_ERROR(
31809 + MAJOR,
31810 + err,
31811 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
31812 +
31813 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31814 + {
31815 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31816 +
31817 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
31818 + RETURN_ERROR(
31819 + MAJOR,
31820 + E_INVALID_VALUE,
31821 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
31822 +
31823 + if ((glblMask & (tmp * 16)) == (tmp * 16))
31824 + {
31825 + err = ValidateNextEngineParams(h_FmPcd,
31826 + &p_KeyParams->ccNextEngineParams,
31827 + p_CcNode->statisticsMode);
31828 + if (err)
31829 + RETURN_ERROR(
31830 + MAJOR,
31831 + err,
31832 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
31833 +
31834 + if (p_KeyParams->ccNextEngineParams.h_Manip)
31835 + {
31836 + err = FmPcdManipCheckParamsForCcNextEngine(
31837 + &p_KeyParams->ccNextEngineParams, &requiredAction);
31838 + if (err)
31839 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31840 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
31841 + requiredAction;
31842 + }
31843 +
31844 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
31845 + &p_KeyParams->ccNextEngineParams,
31846 + sizeof(t_FmPcdCcNextEngineParams));
31847 +
31848 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31849 + == e_FM_PCD_CC)
31850 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31851 + {
31852 + err =
31853 + AllocAndFillAdForContLookupManip(
31854 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
31855 + if (err)
31856 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31857 + }
31858 + }
31859 + else
31860 + {
31861 + err = ValidateNextEngineParams(h_FmPcd,
31862 + &p_KeyParams->ccNextEngineParams,
31863 + p_CcNode->statisticsMode);
31864 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
31865 + RETURN_ERROR(
31866 + MAJOR,
31867 + err,
31868 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
31869 + }
31870 + }
31871 +
31872 + *isKeyTblAlloc = FALSE;
31873 + cpu_to_be16s(&glblMask);
31874 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
31875 +
31876 + return E_OK;
31877 +}
31878 +
31879 +static t_Error ModifyNextEngineParamNode(
31880 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
31881 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31882 +{
31883 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31884 + t_FmPcd *p_FmPcd;
31885 + t_List h_OldPointersLst, h_NewPointersLst;
31886 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31887 + t_Error err = E_OK;
31888 +
31889 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
31890 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
31891 +
31892 + if (keyIndex >= p_CcNode->numOfKeys)
31893 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31894 + ("keyIndex > previously cleared last index + 1"));
31895 +
31896 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31897 +
31898 + INIT_LIST(&h_OldPointersLst);
31899 + INIT_LIST(&h_NewPointersLst);
31900 +
31901 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31902 + e_MODIFY_STATE_CHANGE, FALSE,
31903 + FALSE, FALSE);
31904 + if (!p_ModifyKeyParams)
31905 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31906 +
31907 + if (p_CcNode->maxNumOfKeys
31908 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31909 + {
31910 + XX_Free(p_ModifyKeyParams);
31911 + return ERROR_CODE(E_BUSY);
31912 + }
31913 +
31914 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
31915 + p_FmPcdCcNextEngineParams,
31916 + &h_OldPointersLst, &h_NewPointersLst,
31917 + p_ModifyKeyParams);
31918 + if (err)
31919 + {
31920 + XX_Free(p_ModifyKeyParams);
31921 + if (p_CcNode->maxNumOfKeys)
31922 + RELEASE_LOCK(p_FmPcd->shadowLock);
31923 + RETURN_ERROR(MAJOR, err, NO_MSG);
31924 + }
31925 +
31926 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31927 + p_ModifyKeyParams, FALSE);
31928 +
31929 + if (p_CcNode->maxNumOfKeys)
31930 + RELEASE_LOCK(p_FmPcd->shadowLock);
31931 +
31932 + ReleaseLst(&h_OldPointersLst);
31933 + ReleaseLst(&h_NewPointersLst);
31934 +
31935 + return err;
31936 +}
31937 +
31938 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
31939 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
31940 +{
31941 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31942 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
31943 + uint16_t i;
31944 +
31945 + ASSERT_COND(p_Key);
31946 + ASSERT_COND(p_KeyIndex);
31947 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
31948 +
31949 + if (keySize != p_CcNode->userSizeOfExtraction)
31950 + RETURN_ERROR(
31951 + MINOR, E_INVALID_VALUE,
31952 + ("Key size doesn't match the extraction size of the node"));
31953 +
31954 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
31955 + if (!p_Mask)
31956 + memset(tmpMask, 0xFF, keySize);
31957 +
31958 + for (i = 0; i < p_CcNode->numOfKeys; i++)
31959 + {
31960 + /* Comparing received key */
31961 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
31962 + == 0)
31963 + {
31964 + if (p_Mask)
31965 + {
31966 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
31967 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
31968 + keySize) == 0)
31969 + {
31970 + *p_KeyIndex = i;
31971 + return E_OK;
31972 + }
31973 + }
31974 + else
31975 + {
31976 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
31977 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
31978 + keySize) == 0)
31979 + {
31980 + *p_KeyIndex = i;
31981 + return E_OK;
31982 + }
31983 + }
31984 + }
31985 + }
31986 +
31987 + return ERROR_CODE(E_NOT_FOUND);
31988 +}
31989 +
31990 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
31991 + bool isKeyTblAlloc,
31992 + uint32_t *p_MatchTableSize,
31993 + uint32_t *p_AdTableSize)
31994 +{
31995 + uint32_t shadowSize;
31996 + t_Error err;
31997 +
31998 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
31999 + (if local mask support is requested) */
32000 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
32001 + * p_CcNode->maxNumOfKeys;
32002 +
32003 + if (p_CcNode->maskSupport)
32004 + *p_MatchTableSize *= 2;
32005 +
32006 + /* Calculate next action descriptors table, including one more entry for miss */
32007 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
32008 + * FM_PCD_CC_AD_ENTRY_SIZE);
32009 +
32010 + /* Calculate maximal shadow size of this node.
32011 + All shadow structures will be used for runtime modifications host command. If
32012 + keys table was allocated for this node, the keys table and next engines table may
32013 + be modified in run time (entries added or removed), so shadow tables are requires.
32014 + Otherwise, the only supported runtime modification is a specific next engine update
32015 + and this requires shadow memory of a single AD */
32016 +
32017 + /* Shadow size should be enough to hold the following 3 structures:
32018 + * 1 - an action descriptor */
32019 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
32020 +
32021 + /* 2 - keys match table, if was allocated for the current node */
32022 + if (isKeyTblAlloc)
32023 + shadowSize += *p_MatchTableSize;
32024 +
32025 + /* 3 - next action descriptors table */
32026 + shadowSize += *p_AdTableSize;
32027 +
32028 + /* Update shadow to the calculated size */
32029 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
32030 + FM_PCD_CC_AD_TABLE_ALIGN);
32031 + if (err != E_OK)
32032 + {
32033 + DeleteNode(p_CcNode);
32034 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
32035 + }
32036 +
32037 + return E_OK;
32038 +}
32039 +
32040 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
32041 +{
32042 + t_FmPcdStatsObj *p_StatsObj;
32043 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
32044 + uint32_t i;
32045 +
32046 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
32047 + if (!h_FmMuram)
32048 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
32049 +
32050 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
32051 + will be allocated to support runtime modifications */
32052 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
32053 + {
32054 + /* Allocate list object structure */
32055 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
32056 + if (!p_StatsObj)
32057 + {
32058 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
32059 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
32060 + }
32061 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
32062 +
32063 + /* Allocate statistics AD from MURAM */
32064 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
32065 + FM_PCD_CC_AD_ENTRY_SIZE,
32066 + FM_PCD_CC_AD_TABLE_ALIGN);
32067 + if (!h_StatsAd)
32068 + {
32069 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
32070 + XX_Free(p_StatsObj);
32071 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32072 + ("MURAM allocation for statistics ADs"));
32073 + }
32074 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
32075 +
32076 + /* Allocate statistics counters from MURAM */
32077 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
32078 + h_FmMuram, p_CcNode->countersArraySize,
32079 + FM_PCD_CC_AD_TABLE_ALIGN);
32080 + if (!h_StatsCounters)
32081 + {
32082 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
32083 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
32084 + XX_Free(p_StatsObj);
32085 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32086 + ("MURAM allocation for statistics counters"));
32087 + }
32088 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
32089 +
32090 + p_StatsObj->h_StatsAd = h_StatsAd;
32091 + p_StatsObj->h_StatsCounters = h_StatsCounters;
32092 +
32093 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
32094 + }
32095 +
32096 + return E_OK;
32097 +}
32098 +
32099 +static t_Error MatchTableGetKeyStatistics(
32100 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
32101 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
32102 +{
32103 + uint32_t *p_StatsCounters, i;
32104 +
32105 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
32106 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32107 + ("Statistics were not enabled for this match table"));
32108 +
32109 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
32110 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32111 + ("Statistics were not enabled for this key"));
32112 +
32113 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
32114 +
32115 + p_StatsCounters =
32116 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
32117 + ASSERT_COND(p_StatsCounters);
32118 +
32119 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
32120 +
32121 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
32122 + {
32123 + p_StatsCounters =
32124 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
32125 +
32126 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
32127 +
32128 +#if (DPAA_VERSION >= 11)
32129 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
32130 + GET_UINT32(*p_StatsCounters);
32131 +#endif /* (DPAA_VERSION >= 11) */
32132 + }
32133 +
32134 + return E_OK;
32135 +}
32136 +
32137 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
32138 + t_FmPcdCcNodeParams *p_CcNodeParam)
32139 +{
32140 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32141 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32142 + t_Error err = E_OK;
32143 + uint32_t tmp, keySize;
32144 + bool glblMask = FALSE;
32145 + t_FmPcdCcKeyParams *p_KeyParams;
32146 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
32147 +#if (DPAA_VERSION >= 11)
32148 + t_Handle h_StatsFLRs;
32149 +#endif /* (DPAA_VERSION >= 11) */
32150 + bool fullField = FALSE;
32151 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
32152 + bool isKeyTblAlloc, fromIc = FALSE;
32153 + uint32_t matchTableSize, adTableSize;
32154 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32155 + t_FmPcdStatsObj *p_StatsObj;
32156 + t_FmPcdCcStatsParams statsParams = { 0 };
32157 + t_Handle h_Manip;
32158 +
32159 + ASSERT_COND(h_FmPcd);
32160 + ASSERT_COND(p_CcNode);
32161 + ASSERT_COND(p_CcNodeParam);
32162 +
32163 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
32164 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
32165 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
32166 +
32167 + p_CcNode->h_FmPcd = h_FmPcd;
32168 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
32169 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
32170 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
32171 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
32172 +
32173 + /* For backward compatibility - even if statistics mode is nullified,
32174 + we'll fix it to frame mode so we can support per-key request for
32175 + statistics using 'statisticsEn' in next engine parameters */
32176 + if (!p_CcNode->maxNumOfKeys
32177 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
32178 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
32179 +
32180 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
32181 + if (!h_FmMuram)
32182 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
32183 +
32184 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
32185 + INIT_LIST(&p_CcNode->ccTreeIdLst);
32186 + INIT_LIST(&p_CcNode->ccTreesLst);
32187 + INIT_LIST(&p_CcNode->availableStatsLst);
32188 +
32189 + p_CcNode->h_Spinlock = XX_InitSpinlock();
32190 + if (!p_CcNode->h_Spinlock)
32191 + {
32192 + DeleteNode(p_CcNode);
32193 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
32194 + }
32195 +
32196 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
32197 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
32198 + == HEADER_TYPE_IPv4)
32199 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
32200 + == HEADER_TYPE_IPv6))
32201 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
32202 + == e_FM_PCD_EXTRACT_FULL_FIELD)
32203 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
32204 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
32205 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
32206 + == NET_HEADER_FIELD_IPv4_TTL)))
32207 + {
32208 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
32209 + &isKeyTblAlloc);
32210 + glblMask = FALSE;
32211 + }
32212 + else
32213 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
32214 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
32215 + == e_FM_PCD_EXTRACT_FROM_KEY)
32216 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
32217 + == e_FM_PCD_EXTRACT_FROM_HASH)
32218 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
32219 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
32220 + {
32221 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
32222 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
32223 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
32224 + {
32225 + DeleteNode(p_CcNode);
32226 + RETURN_ERROR(
32227 + MAJOR,
32228 + E_INVALID_VALUE,
32229 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
32230 + }
32231 +
32232 + icCode = IcDefineCode(p_CcNodeParam);
32233 + fromIc = TRUE;
32234 + if (icCode == CC_PRIVATE_INFO_NONE)
32235 + {
32236 + DeleteNode(p_CcNode);
32237 + RETURN_ERROR(
32238 + MAJOR,
32239 + E_INVALID_STATE,
32240 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
32241 + }
32242 +
32243 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
32244 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
32245 + {
32246 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
32247 + &isKeyTblAlloc);
32248 + glblMask = TRUE;
32249 + }
32250 + else
32251 + {
32252 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
32253 + &isKeyTblAlloc);
32254 + if (p_CcNode->glblMaskSize)
32255 + glblMask = TRUE;
32256 + }
32257 + }
32258 + else
32259 + {
32260 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
32261 + if (p_CcNode->glblMaskSize)
32262 + glblMask = TRUE;
32263 + }
32264 +
32265 + if (err)
32266 + {
32267 + DeleteNode(p_CcNode);
32268 + RETURN_ERROR(MAJOR, err, NO_MSG);
32269 + }
32270 +
32271 + switch (p_CcNodeParam->extractCcParams.type)
32272 + {
32273 + case (e_FM_PCD_EXTRACT_BY_HDR):
32274 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
32275 + {
32276 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
32277 + p_CcNode->parseCode =
32278 + GetFullFieldParseCode(
32279 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32280 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
32281 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
32282 + GetSizeHeaderField(
32283 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32284 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
32285 + &p_CcNode->sizeOfExtraction);
32286 + fullField = TRUE;
32287 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
32288 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
32289 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
32290 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
32291 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
32292 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
32293 + && (p_CcNode->parseCode
32294 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
32295 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
32296 + && (p_CcNode->parseCode
32297 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
32298 + && glblMask)
32299 + {
32300 + glblMask = FALSE;
32301 + p_CcNode->glblMaskSize = 4;
32302 + p_CcNode->lclMask = TRUE;
32303 + }
32304 + break;
32305 +
32306 + case (e_FM_PCD_EXTRACT_FROM_HDR):
32307 + p_CcNode->sizeOfExtraction =
32308 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
32309 + p_CcNode->offset =
32310 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
32311 + p_CcNode->userOffset =
32312 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
32313 + p_CcNode->parseCode =
32314 + GetPrParseCode(
32315 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32316 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
32317 + p_CcNode->offset, glblMask,
32318 + &p_CcNode->prsArrayOffset);
32319 + break;
32320 +
32321 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
32322 + p_CcNode->offset =
32323 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
32324 + p_CcNode->userOffset =
32325 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
32326 + p_CcNode->sizeOfExtraction =
32327 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
32328 + p_CcNode->parseCode =
32329 + GetFieldParseCode(
32330 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32331 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
32332 + p_CcNode->offset,
32333 + &p_CcNode->prsArrayOffset,
32334 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
32335 + break;
32336 +
32337 + default:
32338 + DeleteNode(p_CcNode);
32339 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
32340 + }
32341 + break;
32342 +
32343 + case (e_FM_PCD_EXTRACT_NON_HDR):
32344 + /* get the field code for the generic extract */
32345 + p_CcNode->sizeOfExtraction =
32346 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
32347 + p_CcNode->offset =
32348 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
32349 + p_CcNode->userOffset =
32350 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
32351 + p_CcNode->parseCode = GetGenParseCode(
32352 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
32353 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
32354 + fromIc, icCode);
32355 +
32356 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
32357 + {
32358 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
32359 + {
32360 + DeleteNode(p_CcNode);
32361 + RETURN_ERROR(
32362 + MAJOR,
32363 + E_INVALID_SELECTION,
32364 + ("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)"));
32365 + }
32366 + }
32367 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
32368 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
32369 + {
32370 + p_CcNode->offset += p_CcNode->prsArrayOffset;
32371 + p_CcNode->prsArrayOffset = 0;
32372 + }
32373 + break;
32374 +
32375 + default:
32376 + DeleteNode(p_CcNode);
32377 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
32378 + }
32379 +
32380 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
32381 + {
32382 + DeleteNode(p_CcNode);
32383 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
32384 + }
32385 +
32386 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
32387 + || !p_CcNode->sizeOfExtraction)
32388 + {
32389 + DeleteNode(p_CcNode);
32390 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32391 + ("sizeOfExatrction can not be greater than 56 and not 0"));
32392 + }
32393 +
32394 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
32395 + {
32396 + DeleteNode(p_CcNode);
32397 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32398 + ("keySize has to be equal to sizeOfExtraction"));
32399 + }
32400 +
32401 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
32402 +
32403 + if (!glblMask)
32404 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
32405 +
32406 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
32407 + if (err != E_OK)
32408 + {
32409 + DeleteNode(p_CcNode);
32410 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32411 + ("keySize has to be equal to sizeOfExtraction"));
32412 + }
32413 +
32414 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
32415 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
32416 + &p_CcNode->ccKeySizeAccExtraction);
32417 +
32418 + /* If local mask is used, it is stored next to each key in the keys match table */
32419 + if (p_CcNode->lclMask)
32420 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
32421 + else
32422 + keySize = p_CcNode->ccKeySizeAccExtraction;
32423 +
32424 + /* Update CC shadow with maximal size required by this node */
32425 + if (p_CcNode->maxNumOfKeys)
32426 + {
32427 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
32428 + &adTableSize);
32429 + if (err != E_OK)
32430 + {
32431 + DeleteNode(p_CcNode);
32432 + RETURN_ERROR(MAJOR, err, NO_MSG);
32433 + }
32434 +
32435 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
32436 +
32437 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
32438 + {
32439 + err = AllocStatsObjs(p_CcNode);
32440 + if (err != E_OK)
32441 + {
32442 + DeleteNode(p_CcNode);
32443 + RETURN_ERROR(MAJOR, err, NO_MSG);
32444 + }
32445 + }
32446 +
32447 + /* If manipulation will be initialized before this node, it will use the table
32448 + descriptor in the AD table of previous node and this node will need an extra
32449 + AD as his table descriptor. */
32450 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
32451 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
32452 + if (!p_CcNode->h_TmpAd)
32453 + {
32454 + DeleteNode(p_CcNode);
32455 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32456 + ("MURAM allocation for CC action descriptor"));
32457 + }
32458 + }
32459 + else
32460 + {
32461 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
32462 + * (p_CcNode->numOfKeys + 1));
32463 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
32464 + * (p_CcNode->numOfKeys + 1));
32465 + }
32466 +
32467 +#if (DPAA_VERSION >= 11)
32468 + switch (p_CcNode->statisticsMode)
32469 + {
32470 +
32471 + case e_FM_PCD_CC_STATS_MODE_RMON:
32472 + /* If RMON statistics or RMON conditional statistics modes are requested,
32473 + allocate frame length ranges array */
32474 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
32475 + h_FmMuram,
32476 + (uint32_t)(p_CcNode->numOfStatsFLRs)
32477 + * FM_PCD_CC_STATS_FLR_SIZE,
32478 + FM_PCD_CC_AD_TABLE_ALIGN);
32479 +
32480 + if (!p_CcNode->h_StatsFLRs)
32481 + {
32482 + DeleteNode(p_CcNode);
32483 + RETURN_ERROR(
32484 + MAJOR, E_NO_MEMORY,
32485 + ("MURAM allocation for CC frame length ranges array"));
32486 + }
32487 +
32488 + /* Initialize using value received from the user */
32489 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
32490 + {
32491 + uint16_t flr =
32492 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
32493 +
32494 + h_StatsFLRs =
32495 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
32496 +
32497 + MemCpy8(h_StatsFLRs,
32498 + &flr,
32499 + FM_PCD_CC_STATS_FLR_SIZE);
32500 + }
32501 + break;
32502 +
32503 + default:
32504 + break;
32505 + }
32506 +#endif /* (DPAA_VERSION >= 11) */
32507 +
32508 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
32509 + identification, IPv6 hop count identification, etc. */
32510 + if (isKeyTblAlloc)
32511 + {
32512 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
32513 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
32514 + if (!p_CcNode->h_KeysMatchTable)
32515 + {
32516 + DeleteNode(p_CcNode);
32517 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32518 + ("MURAM allocation for CC node key match table"));
32519 + }
32520 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
32521 + }
32522 +
32523 + /* Allocate action descriptors table */
32524 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
32525 + FM_PCD_CC_AD_TABLE_ALIGN);
32526 + if (!p_CcNode->h_AdTable)
32527 + {
32528 + DeleteNode(p_CcNode);
32529 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32530 + ("MURAM allocation for CC node action descriptors table"));
32531 + }
32532 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
32533 +
32534 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
32535 + p_AdTableTmp = p_CcNode->h_AdTable;
32536 +
32537 + /* For each key, create the key and the next step AD */
32538 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
32539 + {
32540 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
32541 +
32542 + if (p_KeysMatchTblTmp)
32543 + {
32544 + /* Copy the key */
32545 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
32546 + p_CcNode->sizeOfExtraction);
32547 +
32548 + /* Copy the key mask or initialize it to 0xFF..F */
32549 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
32550 + {
32551 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
32552 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
32553 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
32554 + }
32555 + else
32556 + if (p_CcNode->lclMask)
32557 + {
32558 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
32559 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
32560 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
32561 + }
32562 +
32563 + p_KeysMatchTblTmp =
32564 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
32565 + }
32566 +
32567 + /* Create the next action descriptor in the match table */
32568 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
32569 + {
32570 + p_StatsObj = GetStatsObj(p_CcNode);
32571 + ASSERT_COND(p_StatsObj);
32572 +
32573 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
32574 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
32575 +#if (DPAA_VERSION >= 11)
32576 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
32577 +
32578 +#endif /* (DPAA_VERSION >= 11) */
32579 + NextStepAd(p_AdTableTmp, &statsParams,
32580 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
32581 +
32582 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
32583 + }
32584 + else
32585 + {
32586 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
32587 + p_FmPcd);
32588 +
32589 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
32590 + }
32591 +
32592 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32593 + }
32594 +
32595 + /* Update next engine for the 'miss' entry */
32596 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
32597 + {
32598 + p_StatsObj = GetStatsObj(p_CcNode);
32599 + ASSERT_COND(p_StatsObj);
32600 +
32601 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
32602 + allocated by the hash table. So, if this node is a bucket of a hash table,
32603 + we'll replace the locally allocated counters with the shared counters. */
32604 + if (p_CcNode->isHashBucket)
32605 + {
32606 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
32607 +
32608 + /* Store original counters pointer and replace it with mutual preallocated pointer */
32609 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
32610 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
32611 + }
32612 +
32613 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
32614 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
32615 +#if (DPAA_VERSION >= 11)
32616 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
32617 +
32618 +#endif /* (DPAA_VERSION >= 11) */
32619 +
32620 + NextStepAd(p_AdTableTmp, &statsParams,
32621 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32622 + p_FmPcd);
32623 +
32624 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
32625 + }
32626 + else
32627 + {
32628 + NextStepAd(p_AdTableTmp, NULL,
32629 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32630 + p_FmPcd);
32631 +
32632 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
32633 + }
32634 +
32635 + /* This parameter will be used to initialize the "key length" field in the action descriptor
32636 + that points to this node and it should be 0 for full field extraction */
32637 + if (fullField == TRUE)
32638 + p_CcNode->sizeOfExtraction = 0;
32639 +
32640 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
32641 + {
32642 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
32643 + == e_FM_PCD_CC)
32644 + {
32645 + p_FmPcdCcNextNode =
32646 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
32647 + p_CcInformation = FindNodeInfoInReleventLst(
32648 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
32649 + p_FmPcdCcNextNode->h_Spinlock);
32650 + if (!p_CcInformation)
32651 + {
32652 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32653 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
32654 + ccNodeInfo.index = 1;
32655 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
32656 + &ccNodeInfo,
32657 + p_FmPcdCcNextNode->h_Spinlock);
32658 + }
32659 + else
32660 + p_CcInformation->index++;
32661 +
32662 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
32663 + {
32664 + h_Manip =
32665 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
32666 + p_CcInformation = FindNodeInfoInReleventLst(
32667 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
32668 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
32669 + if (!p_CcInformation)
32670 + {
32671 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32672 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
32673 + ccNodeInfo.index = 1;
32674 + EnqueueNodeInfoToRelevantLst(
32675 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
32676 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
32677 + }
32678 + else
32679 + p_CcInformation->index++;
32680 + }
32681 + }
32682 + }
32683 +
32684 + p_AdTableTmp = p_CcNode->h_AdTable;
32685 +
32686 + if (!FmPcdLockTryLockAll(h_FmPcd))
32687 + {
32688 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
32689 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32690 + return ERROR_CODE(E_BUSY);
32691 + }
32692 +
32693 + /* Required action for each next engine */
32694 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
32695 + {
32696 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
32697 + {
32698 + err = SetRequiredAction(
32699 + h_FmPcd,
32700 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
32701 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
32702 + NULL);
32703 + if (err)
32704 + {
32705 + FmPcdLockUnlockAll(h_FmPcd);
32706 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
32707 + RETURN_ERROR(MAJOR, err, NO_MSG);
32708 + }
32709 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32710 + }
32711 + }
32712 +
32713 + FmPcdLockUnlockAll(h_FmPcd);
32714 +
32715 + return E_OK;
32716 +}
32717 +/************************** End of static functions **************************/
32718 +
32719 +/*****************************************************************************/
32720 +/* Inter-module API routines */
32721 +/*****************************************************************************/
32722 +
32723 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
32724 + t_Handle h_Spinlock)
32725 +{
32726 + t_CcNodeInformation *p_CcInformation;
32727 + t_List *p_Pos;
32728 + uint32_t intFlags;
32729 +
32730 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
32731 +
32732 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
32733 + p_Pos = LIST_NEXT(p_Pos))
32734 + {
32735 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
32736 +
32737 + ASSERT_COND(p_CcInformation->h_CcNode);
32738 +
32739 + if (p_CcInformation->h_CcNode == h_Info)
32740 + {
32741 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
32742 + return p_CcInformation;
32743 + }
32744 + }
32745 +
32746 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
32747 +
32748 + return NULL;
32749 +}
32750 +
32751 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
32752 + t_Handle h_Spinlock)
32753 +{
32754 + t_CcNodeInformation *p_CcInformation;
32755 + uint32_t intFlags = 0;
32756 +
32757 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
32758 + sizeof(t_CcNodeInformation));
32759 +
32760 + if (p_CcInformation)
32761 + {
32762 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
32763 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
32764 + INIT_LIST(&p_CcInformation->node);
32765 +
32766 + if (h_Spinlock)
32767 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
32768 +
32769 + LIST_AddToTail(&p_CcInformation->node, p_List);
32770 +
32771 + if (h_Spinlock)
32772 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
32773 + }
32774 + else
32775 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
32776 +}
32777 +
32778 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
32779 + t_Handle h_Spinlock)
32780 +{
32781 + t_CcNodeInformation *p_CcInformation = NULL;
32782 + uint32_t intFlags = 0;
32783 + t_List *p_Pos;
32784 +
32785 + if (h_Spinlock)
32786 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
32787 +
32788 + if (LIST_IsEmpty(p_List))
32789 + {
32790 + XX_RestoreAllIntr(intFlags);
32791 + return;
32792 + }
32793 +
32794 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
32795 + p_Pos = LIST_NEXT(p_Pos))
32796 + {
32797 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
32798 + ASSERT_COND(p_CcInformation);
32799 + ASSERT_COND(p_CcInformation->h_CcNode);
32800 + if (p_CcInformation->h_CcNode == h_Info)
32801 + break;
32802 + }
32803 +
32804 + if (p_CcInformation)
32805 + {
32806 + LIST_DelAndInit(&p_CcInformation->node);
32807 + XX_Free(p_CcInformation);
32808 + }
32809 +
32810 + if (h_Spinlock)
32811 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
32812 +}
32813 +
32814 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
32815 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
32816 + t_FmPcd *p_FmPcd)
32817 +{
32818 + switch (p_FmPcdCcNextEngineParams->nextEngine)
32819 + {
32820 + case (e_FM_PCD_KG):
32821 + case (e_FM_PCD_PLCR):
32822 + case (e_FM_PCD_DONE):
32823 + /* if NIA is not CC, create a "result" type AD */
32824 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
32825 + p_FmPcdCcNextEngineParams);
32826 + break;
32827 +#if (DPAA_VERSION >= 11)
32828 + case (e_FM_PCD_FR):
32829 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
32830 + {
32831 + FillAdOfTypeContLookup(
32832 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
32833 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
32834 + p_FmPcdCcNextEngineParams->h_Manip,
32835 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
32836 + FrmReplicGroupUpdateOwner(
32837 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
32838 + TRUE/* add */);
32839 + }
32840 + break;
32841 +#endif /* (DPAA_VERSION >= 11) */
32842 +
32843 + case (e_FM_PCD_CC):
32844 + /* if NIA is not CC, create a TD to continue the CC lookup */
32845 + FillAdOfTypeContLookup(
32846 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
32847 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
32848 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
32849 +
32850 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
32851 + TRUE);
32852 + break;
32853 +
32854 + default:
32855 + return;
32856 + }
32857 +}
32858 +
32859 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
32860 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
32861 + bool createSchemes)
32862 +{
32863 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
32864 + t_FmPcdCcNextEngineParams nextEngineParams;
32865 + t_NetEnvParams netEnvParams;
32866 + t_Handle h_Ad;
32867 + bool isIpv6Present;
32868 + uint8_t ipv4GroupId, ipv6GroupId;
32869 + t_Error err;
32870 +
32871 + ASSERT_COND(p_FmPcdCcTree);
32872 +
32873 + /* this routine must be protected by the calling routine! */
32874 +
32875 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
32876 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
32877 +
32878 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32879 +
32880 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
32881 +
32882 + if (isIpv6Present
32883 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
32884 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
32885 +
32886 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
32887 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
32888 +
32889 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
32890 + nextEngineParams.h_Manip = h_IpReassemblyManip;
32891 +
32892 + /* Lock tree */
32893 + err = CcRootTryLock(p_FmPcdCcTree);
32894 + if (err)
32895 + return ERROR_CODE(E_BUSY);
32896 +
32897 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
32898 + {
32899 + CcRootReleaseLock(p_FmPcdCcTree);
32900 + return E_OK;
32901 + }
32902 +
32903 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
32904 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
32905 + {
32906 + CcRootReleaseLock(p_FmPcdCcTree);
32907 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32908 + ("This tree was previously updated with different IPR"));
32909 + }
32910 +
32911 + /* Initialize IPR for the first time for this tree */
32912 + if (isIpv6Present)
32913 + {
32914 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
32915 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
32916 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
32917 +
32918 + if (createSchemes)
32919 + {
32920 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
32921 + p_FmPcdCcTree,
32922 + h_IpReassemblyManip, FALSE,
32923 + ipv6GroupId);
32924 + if (err)
32925 + {
32926 + p_FmPcdCcTree->numOfGrps--;
32927 + CcRootReleaseLock(p_FmPcdCcTree);
32928 + RETURN_ERROR(MAJOR, err, NO_MSG);
32929 + }
32930 + }
32931 +
32932 + NextStepAd(
32933 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
32934 + NULL, &nextEngineParams, h_FmPcd);
32935 + }
32936 +
32937 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
32938 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
32939 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
32940 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
32941 +
32942 + if (createSchemes)
32943 + {
32944 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
32945 + h_IpReassemblyManip, TRUE,
32946 + ipv4GroupId);
32947 + if (err)
32948 + {
32949 + p_FmPcdCcTree->numOfGrps--;
32950 + if (isIpv6Present)
32951 + {
32952 + p_FmPcdCcTree->numOfGrps--;
32953 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
32954 + }
32955 + CcRootReleaseLock(p_FmPcdCcTree);
32956 + RETURN_ERROR(MAJOR, err, NO_MSG);
32957 + }
32958 + }
32959 +
32960 + NextStepAd(
32961 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
32962 + NULL, &nextEngineParams, h_FmPcd);
32963 +
32964 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
32965 +
32966 + CcRootReleaseLock(p_FmPcdCcTree);
32967 +
32968 + return E_OK;
32969 +}
32970 +
32971 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
32972 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
32973 + bool createSchemes)
32974 +{
32975 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
32976 + t_FmPcdCcNextEngineParams nextEngineParams;
32977 + t_NetEnvParams netEnvParams;
32978 + t_Handle h_Ad;
32979 + uint8_t groupId;
32980 + t_Error err;
32981 +
32982 + ASSERT_COND(p_FmPcdCcTree);
32983 +
32984 + /* this routine must be protected by the calling routine! */
32985 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
32986 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
32987 +
32988 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32989 +
32990 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
32991 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
32992 +
32993 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
32994 + nextEngineParams.h_Manip = h_ReassemblyManip;
32995 +
32996 + /* Lock tree */
32997 + err = CcRootTryLock(p_FmPcdCcTree);
32998 + if (err)
32999 + return ERROR_CODE(E_BUSY);
33000 +
33001 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
33002 + {
33003 + CcRootReleaseLock(p_FmPcdCcTree);
33004 + return E_OK;
33005 + }
33006 +
33007 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
33008 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
33009 + {
33010 + CcRootReleaseLock(p_FmPcdCcTree);
33011 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33012 + ("This tree was previously updated with different CPR"));
33013 + }
33014 +
33015 + groupId = p_FmPcdCcTree->numOfGrps++;
33016 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
33017 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
33018 +
33019 + if (createSchemes)
33020 + {
33021 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
33022 + p_FmPcdCcTree,
33023 + h_ReassemblyManip, groupId);
33024 + if (err)
33025 + {
33026 + p_FmPcdCcTree->numOfGrps--;
33027 + CcRootReleaseLock(p_FmPcdCcTree);
33028 + RETURN_ERROR(MAJOR, err, NO_MSG);
33029 + }
33030 + }
33031 +
33032 + NextStepAd(
33033 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
33034 + NULL, &nextEngineParams, h_FmPcd);
33035 +
33036 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
33037 +
33038 + CcRootReleaseLock(p_FmPcdCcTree);
33039 +
33040 + return E_OK;
33041 +}
33042 +
33043 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
33044 +{
33045 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
33046 +
33047 + ASSERT_COND(p_FmPcdCcTree);
33048 +
33049 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
33050 +}
33051 +
33052 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
33053 + t_Handle h_SavedManipParams)
33054 +{
33055 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
33056 +
33057 + ASSERT_COND(p_FmPcdCcTree);
33058 +
33059 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
33060 +}
33061 +
33062 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
33063 +{
33064 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33065 +
33066 + ASSERT_COND(p_CcNode);
33067 +
33068 + return p_CcNode->parseCode;
33069 +}
33070 +
33071 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
33072 +{
33073 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33074 +
33075 + ASSERT_COND(p_CcNode);
33076 +
33077 + return p_CcNode->offset;
33078 +}
33079 +
33080 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
33081 +{
33082 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33083 +
33084 + ASSERT_COND(p_CcNode);
33085 +
33086 + return p_CcNode->numOfKeys;
33087 +}
33088 +
33089 +t_Error FmPcdCcModifyNextEngineParamTree(
33090 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
33091 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33092 +{
33093 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33094 + t_FmPcd *p_FmPcd;
33095 + t_List h_OldPointersLst, h_NewPointersLst;
33096 + uint16_t keyIndex;
33097 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33098 + t_Error err = E_OK;
33099 +
33100 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
33101 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33102 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
33103 +
33104 + if (grpId >= p_FmPcdCcTree->numOfGrps)
33105 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
33106 + ("grpId you asked > numOfGroup of relevant tree"));
33107 +
33108 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
33109 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
33110 +
33111 + p_FmPcd = (t_FmPcd *)h_FmPcd;
33112 +
33113 + INIT_LIST(&h_OldPointersLst);
33114 + INIT_LIST(&h_NewPointersLst);
33115 +
33116 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
33117 + + index);
33118 +
33119 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
33120 + e_MODIFY_STATE_CHANGE, FALSE,
33121 + FALSE, TRUE);
33122 + if (!p_ModifyKeyParams)
33123 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33124 +
33125 + p_ModifyKeyParams->tree = TRUE;
33126 +
33127 + if (p_FmPcd->p_CcShadow
33128 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33129 + {
33130 + XX_Free(p_ModifyKeyParams);
33131 + return ERROR_CODE(E_BUSY);
33132 + }
33133 +
33134 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
33135 + p_FmPcdCcNextEngineParams,
33136 + &h_OldPointersLst, &h_NewPointersLst,
33137 + p_ModifyKeyParams);
33138 + if (err)
33139 + {
33140 + XX_Free(p_ModifyKeyParams);
33141 + RETURN_ERROR(MAJOR, err, NO_MSG);
33142 + }
33143 +
33144 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33145 + p_ModifyKeyParams, FALSE);
33146 +
33147 + if (p_FmPcd->p_CcShadow)
33148 + RELEASE_LOCK(p_FmPcd->shadowLock);
33149 +
33150 + ReleaseLst(&h_OldPointersLst);
33151 + ReleaseLst(&h_NewPointersLst);
33152 +
33153 + return err;
33154 +
33155 +}
33156 +
33157 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33158 + uint16_t keyIndex)
33159 +{
33160 +
33161 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33162 + t_FmPcd *p_FmPcd;
33163 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33164 + t_List h_OldPointersLst, h_NewPointersLst;
33165 + bool useShadowStructs = FALSE;
33166 + t_Error err = E_OK;
33167 +
33168 + if (keyIndex >= p_CcNode->numOfKeys)
33169 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33170 + ("impossible to remove key when numOfKeys <= keyIndex"));
33171 +
33172 + if (p_CcNode->h_FmPcd != h_FmPcd)
33173 + RETURN_ERROR(
33174 + MAJOR,
33175 + E_INVALID_VALUE,
33176 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33177 +
33178 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33179 +
33180 + INIT_LIST(&h_OldPointersLst);
33181 + INIT_LIST(&h_NewPointersLst);
33182 +
33183 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33184 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
33185 + FALSE);
33186 + if (!p_ModifyKeyParams)
33187 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33188 +
33189 + if (p_CcNode->maxNumOfKeys)
33190 + {
33191 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33192 + {
33193 + XX_Free(p_ModifyKeyParams);
33194 + return ERROR_CODE(E_BUSY);
33195 + }
33196 +
33197 + useShadowStructs = TRUE;
33198 + }
33199 +
33200 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
33201 + if (err)
33202 + {
33203 + XX_Free(p_ModifyKeyParams);
33204 + if (p_CcNode->maxNumOfKeys)
33205 + RELEASE_LOCK(p_FmPcd->shadowLock);
33206 + RETURN_ERROR(MAJOR, err, NO_MSG);
33207 + }
33208 +
33209 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33210 + &h_OldPointersLst,
33211 + &h_NewPointersLst);
33212 + if (err)
33213 + {
33214 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33215 + XX_Free(p_ModifyKeyParams);
33216 + if (p_CcNode->maxNumOfKeys)
33217 + RELEASE_LOCK(p_FmPcd->shadowLock);
33218 + RETURN_ERROR(MAJOR, err, NO_MSG);
33219 + }
33220 +
33221 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33222 + p_ModifyKeyParams, useShadowStructs);
33223 +
33224 + if (p_CcNode->maxNumOfKeys)
33225 + RELEASE_LOCK(p_FmPcd->shadowLock);
33226 +
33227 + ReleaseLst(&h_OldPointersLst);
33228 + ReleaseLst(&h_NewPointersLst);
33229 +
33230 + return err;
33231 +}
33232 +
33233 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33234 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
33235 + uint8_t *p_Mask)
33236 +{
33237 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33238 + t_FmPcd *p_FmPcd;
33239 + t_List h_OldPointersLst, h_NewPointersLst;
33240 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33241 + uint16_t tmpKeyIndex;
33242 + bool useShadowStructs = FALSE;
33243 + t_Error err = E_OK;
33244 +
33245 + if (keyIndex >= p_CcNode->numOfKeys)
33246 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33247 + ("keyIndex > previously cleared last index + 1"));
33248 +
33249 + if (keySize != p_CcNode->userSizeOfExtraction)
33250 + RETURN_ERROR(
33251 + MAJOR,
33252 + E_INVALID_VALUE,
33253 + ("size for ModifyKey has to be the same as defined in SetNode"));
33254 +
33255 + if (p_CcNode->h_FmPcd != h_FmPcd)
33256 + RETURN_ERROR(
33257 + MAJOR,
33258 + E_INVALID_VALUE,
33259 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33260 +
33261 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
33262 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
33263 + RETURN_ERROR(
33264 + MINOR,
33265 + E_ALREADY_EXISTS,
33266 + ("The received key and mask pair was already found in the match table of the provided node"));
33267 +
33268 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33269 +
33270 + INIT_LIST(&h_OldPointersLst);
33271 + INIT_LIST(&h_NewPointersLst);
33272 +
33273 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33274 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
33275 + FALSE);
33276 + if (!p_ModifyKeyParams)
33277 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33278 +
33279 + if (p_CcNode->maxNumOfKeys)
33280 + {
33281 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33282 + {
33283 + XX_Free(p_ModifyKeyParams);
33284 + return ERROR_CODE(E_BUSY);
33285 + }
33286 +
33287 + useShadowStructs = TRUE;
33288 + }
33289 +
33290 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
33291 + p_ModifyKeyParams);
33292 + if (err)
33293 + {
33294 + XX_Free(p_ModifyKeyParams);
33295 + if (p_CcNode->maxNumOfKeys)
33296 + RELEASE_LOCK(p_FmPcd->shadowLock);
33297 + RETURN_ERROR(MAJOR, err, NO_MSG);
33298 + }
33299 +
33300 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33301 + &h_OldPointersLst,
33302 + &h_NewPointersLst);
33303 + if (err)
33304 + {
33305 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33306 + XX_Free(p_ModifyKeyParams);
33307 + if (p_CcNode->maxNumOfKeys)
33308 + RELEASE_LOCK(p_FmPcd->shadowLock);
33309 + RETURN_ERROR(MAJOR, err, NO_MSG);
33310 + }
33311 +
33312 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33313 + p_ModifyKeyParams, useShadowStructs);
33314 +
33315 + if (p_CcNode->maxNumOfKeys)
33316 + RELEASE_LOCK(p_FmPcd->shadowLock);
33317 +
33318 + ReleaseLst(&h_OldPointersLst);
33319 + ReleaseLst(&h_NewPointersLst);
33320 +
33321 + return err;
33322 +}
33323 +
33324 +t_Error FmPcdCcModifyMissNextEngineParamNode(
33325 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33326 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33327 +{
33328 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33329 + t_FmPcd *p_FmPcd;
33330 + t_List h_OldPointersLst, h_NewPointersLst;
33331 + uint16_t keyIndex;
33332 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33333 + t_Error err = E_OK;
33334 +
33335 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
33336 +
33337 + keyIndex = p_CcNode->numOfKeys;
33338 +
33339 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33340 +
33341 + INIT_LIST(&h_OldPointersLst);
33342 + INIT_LIST(&h_NewPointersLst);
33343 +
33344 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33345 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
33346 + FALSE);
33347 + if (!p_ModifyKeyParams)
33348 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33349 +
33350 + if (p_CcNode->maxNumOfKeys
33351 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33352 + {
33353 + XX_Free(p_ModifyKeyParams);
33354 + return ERROR_CODE(E_BUSY);
33355 + }
33356 +
33357 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
33358 + p_FmPcdCcNextEngineParams,
33359 + &h_OldPointersLst, &h_NewPointersLst,
33360 + p_ModifyKeyParams);
33361 + if (err)
33362 + {
33363 + XX_Free(p_ModifyKeyParams);
33364 + if (p_CcNode->maxNumOfKeys)
33365 + RELEASE_LOCK(p_FmPcd->shadowLock);
33366 + RETURN_ERROR(MAJOR, err, NO_MSG);
33367 + }
33368 +
33369 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33370 + p_ModifyKeyParams, FALSE);
33371 +
33372 + if (p_CcNode->maxNumOfKeys)
33373 + RELEASE_LOCK(p_FmPcd->shadowLock);
33374 +
33375 + ReleaseLst(&h_OldPointersLst);
33376 + ReleaseLst(&h_NewPointersLst);
33377 +
33378 + return err;
33379 +}
33380 +
33381 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33382 + uint16_t keyIndex, uint8_t keySize,
33383 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
33384 +{
33385 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33386 + t_FmPcd *p_FmPcd;
33387 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33388 + t_List h_OldPointersLst, h_NewPointersLst;
33389 + bool useShadowStructs = FALSE;
33390 + uint16_t tmpKeyIndex;
33391 + t_Error err = E_OK;
33392 +
33393 + if (keyIndex > p_CcNode->numOfKeys)
33394 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
33395 + ("keyIndex > previously cleared last index + 1"));
33396 +
33397 + if (keySize != p_CcNode->userSizeOfExtraction)
33398 + RETURN_ERROR(
33399 + MAJOR,
33400 + E_INVALID_VALUE,
33401 + ("keySize has to be defined as it was defined in initialization step"));
33402 +
33403 + if (p_CcNode->h_FmPcd != h_FmPcd)
33404 + RETURN_ERROR(
33405 + MAJOR,
33406 + E_INVALID_VALUE,
33407 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33408 +
33409 + if (p_CcNode->maxNumOfKeys)
33410 + {
33411 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
33412 + RETURN_ERROR(
33413 + MAJOR,
33414 + E_FULL,
33415 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
33416 + }
33417 + else
33418 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
33419 + RETURN_ERROR(
33420 + MAJOR,
33421 + E_INVALID_VALUE,
33422 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
33423 +
33424 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
33425 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
33426 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
33427 + RETURN_ERROR(
33428 + MAJOR,
33429 + E_ALREADY_EXISTS,
33430 + ("The received key and mask pair was already found in the match table of the provided node"));
33431 +
33432 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33433 +
33434 + INIT_LIST(&h_OldPointersLst);
33435 + INIT_LIST(&h_NewPointersLst);
33436 +
33437 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33438 + e_MODIFY_STATE_ADD, TRUE, TRUE,
33439 + FALSE);
33440 + if (!p_ModifyKeyParams)
33441 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33442 +
33443 + if (p_CcNode->maxNumOfKeys)
33444 + {
33445 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33446 + {
33447 + XX_Free(p_ModifyKeyParams);
33448 + return ERROR_CODE(E_BUSY);
33449 + }
33450 +
33451 + useShadowStructs = TRUE;
33452 + }
33453 +
33454 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
33455 + p_FmPcdCcKeyParams,
33456 + p_ModifyKeyParams, TRUE);
33457 + if (err)
33458 + {
33459 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33460 + XX_Free(p_ModifyKeyParams);
33461 + if (p_CcNode->maxNumOfKeys)
33462 + RELEASE_LOCK(p_FmPcd->shadowLock);
33463 + RETURN_ERROR(MAJOR, err, NO_MSG);
33464 + }
33465 +
33466 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33467 + &h_OldPointersLst,
33468 + &h_NewPointersLst);
33469 + if (err)
33470 + {
33471 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33472 + XX_Free(p_ModifyKeyParams);
33473 + if (p_CcNode->maxNumOfKeys)
33474 + RELEASE_LOCK(p_FmPcd->shadowLock);
33475 + RETURN_ERROR(MAJOR, err, NO_MSG);
33476 + }
33477 +
33478 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33479 + p_ModifyKeyParams, useShadowStructs);
33480 + if (p_CcNode->maxNumOfKeys)
33481 + RELEASE_LOCK(p_FmPcd->shadowLock);
33482 +
33483 + ReleaseLst(&h_OldPointersLst);
33484 + ReleaseLst(&h_NewPointersLst);
33485 +
33486 + return err;
33487 +}
33488 +
33489 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33490 + uint16_t keyIndex, uint8_t keySize,
33491 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
33492 +{
33493 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33494 + t_FmPcd *p_FmPcd;
33495 + t_List h_OldPointersLst, h_NewPointersLst;
33496 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33497 + uint16_t tmpKeyIndex;
33498 + bool useShadowStructs = FALSE;
33499 + t_Error err = E_OK;
33500 +
33501 + if (keyIndex > p_CcNode->numOfKeys)
33502 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33503 + ("keyIndex > previously cleared last index + 1"));
33504 +
33505 + if (keySize != p_CcNode->userSizeOfExtraction)
33506 + RETURN_ERROR(
33507 + MAJOR,
33508 + E_INVALID_VALUE,
33509 + ("keySize has to be defined as it was defined in initialization step"));
33510 +
33511 + if (p_CcNode->h_FmPcd != h_FmPcd)
33512 + RETURN_ERROR(
33513 + MAJOR,
33514 + E_INVALID_VALUE,
33515 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33516 +
33517 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
33518 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
33519 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
33520 + RETURN_ERROR(
33521 + MINOR,
33522 + E_ALREADY_EXISTS,
33523 + ("The received key and mask pair was already found in the match table of the provided node"));
33524 +
33525 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33526 +
33527 + INIT_LIST(&h_OldPointersLst);
33528 + INIT_LIST(&h_NewPointersLst);
33529 +
33530 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33531 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
33532 + FALSE);
33533 + if (!p_ModifyKeyParams)
33534 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33535 +
33536 + if (p_CcNode->maxNumOfKeys)
33537 + {
33538 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33539 + {
33540 + XX_Free(p_ModifyKeyParams);
33541 + return ERROR_CODE(E_BUSY);
33542 + }
33543 +
33544 + useShadowStructs = TRUE;
33545 + }
33546 +
33547 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
33548 + p_FmPcdCcKeyParams,
33549 + p_ModifyKeyParams, FALSE);
33550 + if (err)
33551 + {
33552 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33553 + XX_Free(p_ModifyKeyParams);
33554 + if (p_CcNode->maxNumOfKeys)
33555 + RELEASE_LOCK(p_FmPcd->shadowLock);
33556 + RETURN_ERROR(MAJOR, err, NO_MSG);
33557 + }
33558 +
33559 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33560 + &h_OldPointersLst,
33561 + &h_NewPointersLst);
33562 + if (err)
33563 + {
33564 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33565 + XX_Free(p_ModifyKeyParams);
33566 + if (p_CcNode->maxNumOfKeys)
33567 + RELEASE_LOCK(p_FmPcd->shadowLock);
33568 + RETURN_ERROR(MAJOR, err, NO_MSG);
33569 + }
33570 +
33571 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33572 + p_ModifyKeyParams, useShadowStructs);
33573 +
33574 + if (p_CcNode->maxNumOfKeys)
33575 + RELEASE_LOCK(p_FmPcd->shadowLock);
33576 +
33577 + ReleaseLst(&h_OldPointersLst);
33578 + ReleaseLst(&h_NewPointersLst);
33579 +
33580 + return err;
33581 +}
33582 +
33583 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
33584 + t_Handle h_Pointer)
33585 +{
33586 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
33587 + t_CcNodeInformation *p_CcNodeInfo;
33588 +
33589 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
33590 + (uint32_t)ILLEGAL_BASE);
33591 +
33592 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
33593 +
33594 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
33595 + - p_FmPcd->physicalMuramBase);
33596 +}
33597 +
33598 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
33599 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
33600 +{
33601 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33602 +
33603 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33604 +
33605 + if (grpId >= p_FmPcdCcTree->numOfGrps)
33606 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
33607 + ("grpId you asked > numOfGroup of relevant tree"));
33608 +
33609 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
33610 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
33611 +
33612 + return E_OK;
33613 +}
33614 +
33615 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
33616 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
33617 + t_Handle h_FmPort)
33618 +{
33619 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
33620 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33621 + t_Error err = E_OK;
33622 +
33623 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
33624 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33625 +
33626 + /* this routine must be protected by the calling routine by locking all PCD modules! */
33627 +
33628 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
33629 +
33630 + if (err == E_OK)
33631 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
33632 +
33633 + *p_Offset = (uint32_t)(XX_VirtToPhys(
33634 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
33635 + - p_FmPcd->physicalMuramBase);
33636 +
33637 + return err;
33638 +}
33639 +
33640 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
33641 +{
33642 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33643 +
33644 + /* this routine must be protected by the calling routine by locking all PCD modules! */
33645 +
33646 + UNUSED(h_FmPcd);
33647 +
33648 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33649 +
33650 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
33651 +
33652 + return E_OK;
33653 +}
33654 +
33655 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33656 + t_List *p_List)
33657 +{
33658 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33659 + t_List *p_Pos, *p_Tmp;
33660 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
33661 + uint32_t intFlags;
33662 + t_Error err = E_OK;
33663 +
33664 + intFlags = FmPcdLock(h_FmPcd);
33665 +
33666 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
33667 + {
33668 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
33669 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
33670 +
33671 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
33672 +
33673 + if (err)
33674 + {
33675 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
33676 + {
33677 + if (p_Tmp == p_Pos)
33678 + break;
33679 +
33680 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
33681 + }
33682 + break;
33683 + }
33684 +
33685 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
33686 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
33687 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
33688 + }
33689 +
33690 + FmPcdUnlock(h_FmPcd, intFlags);
33691 + CORE_MemoryBarrier();
33692 +
33693 + return err;
33694 +}
33695 +
33696 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
33697 +{
33698 + t_List *p_Pos;
33699 + t_CcNodeInformation *p_CcNodeInfo;
33700 + t_Handle h_FmPcdCcTree;
33701 + uint32_t intFlags;
33702 +
33703 + intFlags = FmPcdLock(h_FmPcd);
33704 +
33705 + LIST_FOR_EACH(p_Pos, p_List)
33706 + {
33707 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
33708 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
33709 + CcRootReleaseLock(h_FmPcdCcTree);
33710 + }
33711 +
33712 + ReleaseLst(p_List);
33713 +
33714 + FmPcdUnlock(h_FmPcd, intFlags);
33715 + CORE_MemoryBarrier();
33716 +}
33717 +
33718 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
33719 +{
33720 + uint32_t intFlags;
33721 + uint32_t newSize = 0, newAlign = 0;
33722 + bool allocFail = FALSE;
33723 +
33724 + ASSERT_COND(p_FmPcd);
33725 +
33726 + if (!size)
33727 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
33728 +
33729 + if (!POWER_OF_2(align))
33730 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
33731 +
33732 + newSize = p_FmPcd->ccShadowSize;
33733 + newAlign = p_FmPcd->ccShadowAlign;
33734 +
33735 + /* Check if current shadow is large enough to hold the requested size */
33736 + if (size > p_FmPcd->ccShadowSize)
33737 + newSize = size;
33738 +
33739 + /* Check if current shadow matches the requested alignment */
33740 + if (align > p_FmPcd->ccShadowAlign)
33741 + newAlign = align;
33742 +
33743 + /* If a bigger shadow size or bigger shadow alignment are required,
33744 + a new shadow will be allocated */
33745 + if ((newSize != p_FmPcd->ccShadowSize)
33746 + || (newAlign != p_FmPcd->ccShadowAlign))
33747 + {
33748 + intFlags = FmPcdLock(p_FmPcd);
33749 +
33750 + if (p_FmPcd->p_CcShadow)
33751 + {
33752 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
33753 + p_FmPcd->ccShadowSize = 0;
33754 + p_FmPcd->ccShadowAlign = 0;
33755 + }
33756 +
33757 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
33758 + newSize, newAlign);
33759 + if (!p_FmPcd->p_CcShadow)
33760 + {
33761 + allocFail = TRUE;
33762 +
33763 + /* If new shadow size allocation failed,
33764 + re-allocate with previous parameters */
33765 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
33766 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
33767 + p_FmPcd->ccShadowAlign);
33768 + }
33769 +
33770 + FmPcdUnlock(p_FmPcd, intFlags);
33771 +
33772 + if (allocFail)
33773 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
33774 + ("MURAM allocation for CC Shadow memory"));
33775 +
33776 + p_FmPcd->ccShadowSize = newSize;
33777 + p_FmPcd->ccShadowAlign = newAlign;
33778 + }
33779 +
33780 + return E_OK;
33781 +}
33782 +
33783 +#if (DPAA_VERSION >= 11)
33784 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
33785 + t_Handle h_ReplicGroup,
33786 + t_List *p_AdTables,
33787 + uint32_t *p_NumOfAdTables)
33788 +{
33789 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
33790 + int i = 0;
33791 + void * p_AdTable;
33792 + t_CcNodeInformation ccNodeInfo;
33793 +
33794 + ASSERT_COND(h_Node);
33795 + *p_NumOfAdTables = 0;
33796 +
33797 + /* search in the current node which exact index points on this current replicator group for getting AD */
33798 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
33799 + {
33800 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
33801 + == e_FM_PCD_FR)
33802 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
33803 + == (t_Handle)h_ReplicGroup)))
33804 + {
33805 + /* save the current ad table in the list */
33806 + /* this entry uses the input replicator group */
33807 + p_AdTable =
33808 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
33809 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
33810 + ccNodeInfo.h_CcNode = p_AdTable;
33811 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
33812 + (*p_NumOfAdTables)++;
33813 + }
33814 + }
33815 +
33816 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
33817 +}
33818 +#endif /* (DPAA_VERSION >= 11) */
33819 +/*********************** End of inter-module routines ************************/
33820 +
33821 +/****************************************/
33822 +/* API Init unit functions */
33823 +/****************************************/
33824 +
33825 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
33826 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
33827 +{
33828 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
33829 + t_Error err = E_OK;
33830 + int i = 0, j = 0, k = 0;
33831 + t_FmPcdCcTree *p_FmPcdCcTree;
33832 + uint8_t numOfEntries;
33833 + t_Handle p_CcTreeTmp;
33834 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
33835 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
33836 + t_NetEnvParams netEnvParams;
33837 + uint8_t lastOne = 0;
33838 + uint32_t requiredAction = 0;
33839 + t_FmPcdCcNode *p_FmPcdCcNextNode;
33840 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
33841 +
33842 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33843 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
33844 +
33845 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
33846 + {
33847 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
33848 + return NULL;
33849 + }
33850 +
33851 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
33852 + if (!p_FmPcdCcTree)
33853 + {
33854 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
33855 + return NULL;
33856 + }
33857 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
33858 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
33859 +
33860 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
33861 + FM_PCD_MAX_NUM_OF_CC_GROUPS
33862 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
33863 + memset(p_Params,
33864 + 0,
33865 + FM_PCD_MAX_NUM_OF_CC_GROUPS
33866 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
33867 +
33868 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
33869 +
33870 +#ifdef FM_CAPWAP_SUPPORT
33871 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
33872 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
33873 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
33874 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
33875 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
33876 + {
33877 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
33878 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
33879 + {
33880 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
33881 + XX_Free(p_Params);
33882 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33883 + return NULL;
33884 + }
33885 + }
33886 +#endif /* FM_CAPWAP_SUPPORT */
33887 +
33888 + numOfEntries = 0;
33889 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
33890 +
33891 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
33892 + {
33893 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
33894 +
33895 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
33896 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
33897 + {
33898 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33899 + XX_Free(p_Params);
33900 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33901 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
33902 + return NULL;
33903 + }
33904 +
33905 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
33906 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
33907 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
33908 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
33909 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
33910 + {
33911 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33912 + XX_Free(p_Params);
33913 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
33914 + return NULL;
33915 + }
33916 +
33917 + if (lastOne)
33918 + {
33919 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
33920 + {
33921 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33922 + XX_Free(p_Params);
33923 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
33924 + return NULL;
33925 + }
33926 + }
33927 +
33928 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
33929 +
33930 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
33931 + netEnvParams.numOfDistinctionUnits =
33932 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
33933 +
33934 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
33935 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
33936 +
33937 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
33938 + if (err)
33939 + {
33940 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33941 + XX_Free(p_Params);
33942 + REPORT_ERROR(MAJOR, err, NO_MSG);
33943 + return NULL;
33944 + }
33945 +
33946 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
33947 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
33948 + j++)
33949 + {
33950 + err = ValidateNextEngineParams(
33951 + h_FmPcd,
33952 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
33953 + e_FM_PCD_CC_STATS_MODE_NONE);
33954 + if (err)
33955 + {
33956 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33957 + XX_Free(p_Params);
33958 + REPORT_ERROR(MAJOR, err, (NO_MSG));
33959 + return NULL;
33960 + }
33961 +
33962 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
33963 + {
33964 + err = FmPcdManipCheckParamsForCcNextEngine(
33965 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
33966 + &requiredAction);
33967 + if (err)
33968 + {
33969 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33970 + XX_Free(p_Params);
33971 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33972 + return NULL;
33973 + }
33974 + }
33975 + p_KeyAndNextEngineParams = p_Params + k;
33976 +
33977 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
33978 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
33979 + sizeof(t_FmPcdCcNextEngineParams));
33980 +
33981 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
33982 + == e_FM_PCD_CC)
33983 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
33984 + {
33985 + err =
33986 + AllocAndFillAdForContLookupManip(
33987 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
33988 + if (err)
33989 + {
33990 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
33991 + XX_Free(p_Params);
33992 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
33993 + return NULL;
33994 + }
33995 + }
33996 +
33997 + requiredAction |= UPDATE_CC_WITH_TREE;
33998 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
33999 +
34000 + k++;
34001 + }
34002 + }
34003 +
34004 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
34005 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
34006 +
34007 + p_FmPcdCcTree->ccTreeBaseAddr =
34008 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
34009 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
34010 + FM_PCD_CC_TREE_ADDR_ALIGN));
34011 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
34012 + {
34013 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34014 + XX_Free(p_Params);
34015 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
34016 + return NULL;
34017 + }
34018 + MemSet8(
34019 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
34020 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
34021 +
34022 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
34023 +
34024 + for (i = 0; i < numOfEntries; i++)
34025 + {
34026 + p_KeyAndNextEngineParams = p_Params + i;
34027 +
34028 + NextStepAd(p_CcTreeTmp, NULL,
34029 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
34030 +
34031 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
34032 +
34033 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
34034 + p_KeyAndNextEngineParams,
34035 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
34036 +
34037 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34038 + == e_FM_PCD_CC)
34039 + {
34040 + p_FmPcdCcNextNode =
34041 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
34042 + p_CcInformation = FindNodeInfoInReleventLst(
34043 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
34044 + p_FmPcdCcNextNode->h_Spinlock);
34045 +
34046 + if (!p_CcInformation)
34047 + {
34048 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
34049 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
34050 + ccNodeInfo.index = 1;
34051 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
34052 + &ccNodeInfo,
34053 + p_FmPcdCcNextNode->h_Spinlock);
34054 + }
34055 + else
34056 + p_CcInformation->index++;
34057 + }
34058 + }
34059 +
34060 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
34061 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
34062 +
34063 + if (!FmPcdLockTryLockAll(p_FmPcd))
34064 + {
34065 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
34066 + XX_Free(p_Params);
34067 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34068 + return NULL;
34069 + }
34070 +
34071 + for (i = 0; i < numOfEntries; i++)
34072 + {
34073 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
34074 + {
34075 + err = SetRequiredAction(
34076 + h_FmPcd,
34077 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
34078 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
34079 + p_FmPcdCcTree);
34080 + if (err)
34081 + {
34082 + FmPcdLockUnlockAll(p_FmPcd);
34083 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
34084 + XX_Free(p_Params);
34085 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
34086 + return NULL;
34087 + }
34088 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
34089 + }
34090 + }
34091 +
34092 + FmPcdLockUnlockAll(p_FmPcd);
34093 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
34094 + if (!p_FmPcdCcTree->p_Lock)
34095 + {
34096 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
34097 + XX_Free(p_Params);
34098 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
34099 + return NULL;
34100 + }
34101 +
34102 + XX_Free(p_Params);
34103 +
34104 + return p_FmPcdCcTree;
34105 +}
34106 +
34107 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
34108 +{
34109 + t_FmPcd *p_FmPcd;
34110 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
34111 + int i = 0;
34112 +
34113 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
34114 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
34115 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34116 +
34117 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
34118 +
34119 + if (p_CcTree->owners)
34120 + RETURN_ERROR(
34121 + MAJOR,
34122 + E_INVALID_SELECTION,
34123 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
34124 +
34125 + /* Delete ip-reassembly schemes if exist */
34126 + if (p_CcTree->h_IpReassemblyManip)
34127 + {
34128 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
34129 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
34130 + }
34131 +
34132 + /* Delete capwap-reassembly schemes if exist */
34133 + if (p_CcTree->h_CapwapReassemblyManip)
34134 + {
34135 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
34136 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
34137 + }
34138 +
34139 + for (i = 0; i < p_CcTree->numOfEntries; i++)
34140 + {
34141 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34142 + == e_FM_PCD_CC)
34143 + UpdateNodeOwner(
34144 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
34145 + FALSE);
34146 +
34147 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
34148 + FmPcdManipUpdateOwner(
34149 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
34150 + FALSE);
34151 +
34152 +#ifdef FM_CAPWAP_SUPPORT
34153 + if ((p_CcTree->numOfGrps == 1) &&
34154 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
34155 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
34156 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
34157 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
34158 + {
34159 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
34160 + return E_INVALID_STATE;
34161 + }
34162 +#endif /* FM_CAPWAP_SUPPORT */
34163 +
34164 +#if (DPAA_VERSION >= 11)
34165 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34166 + == e_FM_PCD_FR)
34167 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
34168 + FrmReplicGroupUpdateOwner(
34169 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
34170 + FALSE);
34171 +#endif /* (DPAA_VERSION >= 11) */
34172 + }
34173 +
34174 + if (p_CcTree->p_Lock)
34175 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
34176 +
34177 + DeleteTree(p_CcTree, p_FmPcd);
34178 +
34179 + return E_OK;
34180 +}
34181 +
34182 +t_Error FM_PCD_CcRootModifyNextEngine(
34183 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
34184 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34185 +{
34186 + t_FmPcd *p_FmPcd;
34187 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
34188 + t_Error err = E_OK;
34189 +
34190 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34191 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
34192 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
34193 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34194 +
34195 + if (!FmPcdLockTryLockAll(p_FmPcd))
34196 + {
34197 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34198 + return ERROR_CODE(E_BUSY);
34199 + }
34200 +
34201 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
34202 + p_FmPcdCcNextEngineParams);
34203 + FmPcdLockUnlockAll(p_FmPcd);
34204 +
34205 + if (err)
34206 + {
34207 + RETURN_ERROR(MAJOR, err, NO_MSG);
34208 + }
34209 +
34210 + return E_OK;
34211 +}
34212 +
34213 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
34214 + t_FmPcdCcNodeParams *p_CcNodeParam)
34215 +{
34216 + t_FmPcdCcNode *p_CcNode;
34217 + t_Error err;
34218 +
34219 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
34220 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
34221 +
34222 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
34223 + if (!p_CcNode)
34224 + {
34225 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
34226 + return NULL;
34227 + }
34228 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
34229 +
34230 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
34231 +
34232 + switch(GET_ERROR_TYPE(err)
34233 +) {
34234 + case E_OK:
34235 + break;
34236 +
34237 + case E_BUSY:
34238 + DBG(TRACE, ("E_BUSY error"));
34239 + return NULL;
34240 +
34241 + default:
34242 + REPORT_ERROR(MAJOR, err, NO_MSG);
34243 + return NULL;
34244 + }
34245 +
34246 + return p_CcNode;
34247 +}
34248 +
34249 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
34250 +{
34251 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34252 + int i = 0;
34253 +
34254 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34255 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
34256 +
34257 + if (p_CcNode->owners)
34258 + RETURN_ERROR(
34259 + MAJOR,
34260 + E_INVALID_STATE,
34261 + ("This node cannot be removed because it is occupied; first unbind this node"));
34262 +
34263 + for (i = 0; i < p_CcNode->numOfKeys; i++)
34264 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34265 + == e_FM_PCD_CC)
34266 + UpdateNodeOwner(
34267 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
34268 + FALSE);
34269 +
34270 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34271 + == e_FM_PCD_CC)
34272 + UpdateNodeOwner(
34273 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
34274 + FALSE);
34275 +
34276 + /* Handle also Miss entry */
34277 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
34278 + {
34279 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
34280 + FmPcdManipUpdateOwner(
34281 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
34282 + FALSE);
34283 +
34284 +#if (DPAA_VERSION >= 11)
34285 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34286 + == e_FM_PCD_FR)
34287 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
34288 + {
34289 + FrmReplicGroupUpdateOwner(
34290 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
34291 + FALSE);
34292 + }
34293 +#endif /* (DPAA_VERSION >= 11) */
34294 + }
34295 +
34296 + DeleteNode(p_CcNode);
34297 +
34298 + return E_OK;
34299 +}
34300 +
34301 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
34302 + uint8_t keySize,
34303 + t_FmPcdCcKeyParams *p_KeyParams)
34304 +{
34305 + t_FmPcd *p_FmPcd;
34306 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34307 + t_Error err = E_OK;
34308 +
34309 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
34310 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34311 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34312 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34313 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34314 +
34315 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
34316 + keyIndex = p_CcNode->numOfKeys;
34317 +
34318 + if (!FmPcdLockTryLockAll(p_FmPcd))
34319 + {
34320 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34321 + return ERROR_CODE(E_BUSY);
34322 + }
34323 +
34324 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
34325 +
34326 + FmPcdLockUnlockAll(p_FmPcd);
34327 +
34328 + switch(GET_ERROR_TYPE(err)
34329 +) {
34330 + case E_OK:
34331 + return E_OK;
34332 +
34333 + case E_BUSY:
34334 + DBG(TRACE, ("E_BUSY error"));
34335 + return ERROR_CODE(E_BUSY);
34336 +
34337 + default:
34338 + RETURN_ERROR(MAJOR, err, NO_MSG);
34339 + }
34340 +}
34341 +
34342 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
34343 +{
34344 + t_FmPcd *p_FmPcd;
34345 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34346 + t_Error err = E_OK;
34347 +
34348 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34349 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34350 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34351 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34352 +
34353 + if (!FmPcdLockTryLockAll(p_FmPcd))
34354 + {
34355 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34356 + return ERROR_CODE(E_BUSY);
34357 + }
34358 +
34359 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
34360 +
34361 + FmPcdLockUnlockAll(p_FmPcd);
34362 +
34363 + switch(GET_ERROR_TYPE(err)
34364 +) {
34365 + case E_OK:
34366 + return E_OK;
34367 +
34368 + case E_BUSY:
34369 + DBG(TRACE, ("E_BUSY error"));
34370 + return ERROR_CODE(E_BUSY);
34371 +
34372 + default:
34373 + RETURN_ERROR(MAJOR, err, NO_MSG);
34374 + }
34375 +
34376 + return E_OK;
34377 +}
34378 +
34379 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
34380 + uint8_t keySize, uint8_t *p_Key,
34381 + uint8_t *p_Mask)
34382 +{
34383 + t_FmPcd *p_FmPcd;
34384 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34385 + t_Error err = E_OK;
34386 +
34387 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34388 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34389 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34390 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34391 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34392 +
34393 +
34394 + if (!FmPcdLockTryLockAll(p_FmPcd))
34395 + {
34396 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34397 + return ERROR_CODE(E_BUSY);
34398 + }
34399 +
34400 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
34401 +
34402 + FmPcdLockUnlockAll(p_FmPcd);
34403 +
34404 + switch(GET_ERROR_TYPE(err)
34405 +) {
34406 + case E_OK:
34407 + return E_OK;
34408 +
34409 + case E_BUSY:
34410 + DBG(TRACE, ("E_BUSY error"));
34411 + return ERROR_CODE(E_BUSY);
34412 +
34413 + default:
34414 + RETURN_ERROR(MAJOR, err, NO_MSG);
34415 + }
34416 +}
34417 +
34418 +t_Error FM_PCD_MatchTableModifyNextEngine(
34419 + t_Handle h_CcNode, uint16_t keyIndex,
34420 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34421 +{
34422 + t_FmPcd *p_FmPcd;
34423 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34424 + t_Error err = E_OK;
34425 +
34426 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34427 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34428 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34429 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34430 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34431 +
34432 + if (!FmPcdLockTryLockAll(p_FmPcd))
34433 + {
34434 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34435 + return ERROR_CODE(E_BUSY);
34436 + }
34437 +
34438 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
34439 + p_FmPcdCcNextEngineParams);
34440 +
34441 + FmPcdLockUnlockAll(p_FmPcd);
34442 +
34443 + switch(GET_ERROR_TYPE(err)
34444 +) {
34445 + case E_OK:
34446 + return E_OK;
34447 +
34448 + case E_BUSY:
34449 + DBG(TRACE, ("E_BUSY error"));
34450 + return ERROR_CODE(E_BUSY);
34451 +
34452 + default:
34453 + RETURN_ERROR(MAJOR, err, NO_MSG);
34454 + }
34455 +}
34456 +
34457 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
34458 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34459 +{
34460 + t_FmPcd *p_FmPcd;
34461 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34462 + t_Error err = E_OK;
34463 +
34464 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34465 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34466 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34467 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34468 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34469 +
34470 + if (!FmPcdLockTryLockAll(p_FmPcd))
34471 + {
34472 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34473 + return ERROR_CODE(E_BUSY);
34474 + }
34475 +
34476 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
34477 + p_FmPcdCcNextEngineParams);
34478 +
34479 + FmPcdLockUnlockAll(p_FmPcd);
34480 +
34481 + switch(GET_ERROR_TYPE(err)
34482 +) {
34483 + case E_OK:
34484 + return E_OK;
34485 +
34486 + case E_BUSY:
34487 + DBG(TRACE, ("E_BUSY error"));
34488 + return ERROR_CODE(E_BUSY);
34489 +
34490 + default:
34491 + RETURN_ERROR(MAJOR, err, NO_MSG);
34492 + }
34493 +}
34494 +
34495 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
34496 + uint16_t keyIndex,
34497 + uint8_t keySize,
34498 + t_FmPcdCcKeyParams *p_KeyParams)
34499 +{
34500 + t_FmPcd *p_FmPcd;
34501 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34502 + t_Error err = E_OK;
34503 +
34504 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
34505 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34506 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34507 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34508 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34509 +
34510 + if (!FmPcdLockTryLockAll(p_FmPcd))
34511 + {
34512 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34513 + return ERROR_CODE(E_BUSY);
34514 + }
34515 +
34516 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
34517 + p_KeyParams);
34518 +
34519 + FmPcdLockUnlockAll(p_FmPcd);
34520 +
34521 + switch(GET_ERROR_TYPE(err)
34522 +) {
34523 + case E_OK:
34524 + return E_OK;
34525 +
34526 + case E_BUSY:
34527 + DBG(TRACE, ("E_BUSY error"));
34528 + return ERROR_CODE(E_BUSY);
34529 +
34530 + default:
34531 + RETURN_ERROR(MAJOR, err, NO_MSG);
34532 + }
34533 +}
34534 +
34535 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
34536 + uint8_t *p_Key, uint8_t *p_Mask)
34537 +{
34538 + t_FmPcd *p_FmPcd;
34539 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34540 + uint16_t keyIndex;
34541 + t_Error err;
34542 +
34543 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34544 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34545 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34546 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34547 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34548 +
34549 + if (!FmPcdLockTryLockAll(p_FmPcd))
34550 + {
34551 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34552 + return ERROR_CODE(E_BUSY);
34553 + }
34554 +
34555 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34556 + if (GET_ERROR_TYPE(err) != E_OK)
34557 + {
34558 + FmPcdLockUnlockAll(p_FmPcd);
34559 + RETURN_ERROR(
34560 + MAJOR,
34561 + err,
34562 + ("The received key and mask pair was not found in the match table of the provided node"));
34563 + }
34564 +
34565 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
34566 +
34567 + FmPcdLockUnlockAll(p_FmPcd);
34568 +
34569 + switch(GET_ERROR_TYPE(err)
34570 +) {
34571 + case E_OK:
34572 + return E_OK;
34573 +
34574 + case E_BUSY:
34575 + DBG(TRACE, ("E_BUSY error"));
34576 + return ERROR_CODE(E_BUSY);
34577 +
34578 + default:
34579 + RETURN_ERROR(MAJOR, err, NO_MSG);
34580 + }
34581 +}
34582 +
34583 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
34584 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
34585 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34586 +{
34587 + t_FmPcd *p_FmPcd;
34588 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34589 + uint16_t keyIndex;
34590 + t_Error err;
34591 +
34592 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34593 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34594 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34595 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34596 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34597 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34598 +
34599 + if (!FmPcdLockTryLockAll(p_FmPcd))
34600 + {
34601 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34602 + return ERROR_CODE(E_BUSY);
34603 + }
34604 +
34605 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34606 + if (GET_ERROR_TYPE(err) != E_OK)
34607 + {
34608 + FmPcdLockUnlockAll(p_FmPcd);
34609 + RETURN_ERROR(
34610 + MAJOR,
34611 + err,
34612 + ("The received key and mask pair was not found in the match table of the provided node"));
34613 + }
34614 +
34615 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
34616 + p_FmPcdCcNextEngineParams);
34617 +
34618 + FmPcdLockUnlockAll(p_FmPcd);
34619 +
34620 + switch(GET_ERROR_TYPE(err)
34621 +) {
34622 + case E_OK:
34623 + return E_OK;
34624 +
34625 + case E_BUSY:
34626 + DBG(TRACE, ("E_BUSY error"));
34627 + return ERROR_CODE(E_BUSY);
34628 +
34629 + default:
34630 + RETURN_ERROR(MAJOR, err, NO_MSG);
34631 + }
34632 +}
34633 +
34634 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
34635 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
34636 + t_FmPcdCcKeyParams *p_KeyParams)
34637 +{
34638 + t_FmPcd *p_FmPcd;
34639 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34640 + uint16_t keyIndex;
34641 + t_Error err;
34642 +
34643 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34644 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
34645 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34646 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34647 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34648 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34649 +
34650 + if (!FmPcdLockTryLockAll(p_FmPcd))
34651 + {
34652 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34653 + return ERROR_CODE(E_BUSY);
34654 + }
34655 +
34656 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34657 + if (GET_ERROR_TYPE(err) != E_OK)
34658 + {
34659 + FmPcdLockUnlockAll(p_FmPcd);
34660 + RETURN_ERROR(
34661 + MAJOR,
34662 + err,
34663 + ("The received key and mask pair was not found in the match table of the provided node"));
34664 + }
34665 +
34666 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
34667 + p_KeyParams);
34668 +
34669 + FmPcdLockUnlockAll(p_FmPcd);
34670 +
34671 + switch(GET_ERROR_TYPE(err)
34672 +) {
34673 + case E_OK:
34674 + return E_OK;
34675 +
34676 + case E_BUSY:
34677 + DBG(TRACE, ("E_BUSY error"));
34678 + return ERROR_CODE(E_BUSY);
34679 +
34680 + default:
34681 + RETURN_ERROR(MAJOR, err, NO_MSG);
34682 + }
34683 +}
34684 +
34685 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
34686 + uint8_t *p_Key, uint8_t *p_Mask,
34687 + uint8_t *p_NewKey, uint8_t *p_NewMask)
34688 +{
34689 + t_FmPcd *p_FmPcd;
34690 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34691 + t_List h_List;
34692 + uint16_t keyIndex;
34693 + t_Error err;
34694 +
34695 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34696 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
34697 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34698 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34699 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34700 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34701 +
34702 + INIT_LIST(&h_List);
34703 +
34704 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
34705 + if (err)
34706 + {
34707 + DBG(TRACE, ("Node's trees lock failed"));
34708 + return ERROR_CODE(E_BUSY);
34709 + }
34710 +
34711 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34712 + if (GET_ERROR_TYPE(err) != E_OK)
34713 + {
34714 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
34715 + RETURN_ERROR(MAJOR, err,
34716 + ("The received key and mask pair was not found in the "
34717 + "match table of the provided node"));
34718 + }
34719 +
34720 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
34721 + p_NewMask);
34722 +
34723 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
34724 +
34725 + switch(GET_ERROR_TYPE(err)
34726 +) {
34727 + case E_OK:
34728 + return E_OK;
34729 +
34730 + case E_BUSY:
34731 + DBG(TRACE, ("E_BUSY error"));
34732 + return ERROR_CODE(E_BUSY);
34733 +
34734 + default:
34735 + RETURN_ERROR(MAJOR, err, NO_MSG);
34736 + }
34737 +}
34738 +
34739 +t_Error FM_PCD_MatchTableGetNextEngine(
34740 + t_Handle h_CcNode, uint16_t keyIndex,
34741 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34742 +{
34743 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34744 +
34745 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34746 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34747 +
34748 + if (keyIndex >= p_CcNode->numOfKeys)
34749 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
34750 + ("keyIndex exceeds current number of keys"));
34751 +
34752 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
34753 + RETURN_ERROR(
34754 + MAJOR,
34755 + E_INVALID_VALUE,
34756 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
34757 +
34758 + memcpy(p_FmPcdCcNextEngineParams,
34759 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
34760 + sizeof(t_FmPcdCcNextEngineParams));
34761 +
34762 + return E_OK;
34763 +}
34764 +
34765 +
34766 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
34767 +{
34768 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34769 + uint32_t *p_StatsCounters, frameCount;
34770 + uint32_t intFlags;
34771 +
34772 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
34773 +
34774 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
34775 + {
34776 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
34777 + return 0;
34778 + }
34779 +
34780 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
34781 + && (p_CcNode->statisticsMode
34782 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
34783 + {
34784 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
34785 + return 0;
34786 + }
34787 +
34788 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
34789 +
34790 + if (keyIndex >= p_CcNode->numOfKeys)
34791 + {
34792 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34793 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
34794 + return 0;
34795 + }
34796 +
34797 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
34798 + {
34799 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34800 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
34801 + return 0;
34802 + }
34803 +
34804 + p_StatsCounters =
34805 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
34806 + ASSERT_COND(p_StatsCounters);
34807 +
34808 + /* The first counter is byte counter, so we need to advance to the next counter */
34809 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
34810 + FM_PCD_CC_STATS_COUNTER_SIZE)));
34811 +
34812 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34813 +
34814 + return frameCount;
34815 +}
34816 +
34817 +t_Error FM_PCD_MatchTableGetKeyStatistics(
34818 + t_Handle h_CcNode, uint16_t keyIndex,
34819 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
34820 +{
34821 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34822 + uint32_t intFlags;
34823 + t_Error err;
34824 +
34825 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
34826 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
34827 +
34828 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
34829 +
34830 + if (keyIndex >= p_CcNode->numOfKeys)
34831 + RETURN_ERROR(
34832 + MAJOR,
34833 + E_INVALID_STATE,
34834 + ("The provided keyIndex exceeds the number of keys in this match table"));
34835 +
34836 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
34837 +
34838 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34839 +
34840 + if (err != E_OK)
34841 + RETURN_ERROR(MAJOR, err, NO_MSG);
34842 +
34843 + return E_OK;
34844 +}
34845 +
34846 +t_Error FM_PCD_MatchTableGetMissStatistics(
34847 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
34848 +{
34849 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34850 + uint32_t intFlags;
34851 + t_Error err;
34852 +
34853 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
34854 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
34855 +
34856 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
34857 +
34858 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
34859 + p_MissStatistics);
34860 +
34861 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34862 +
34863 + if (err != E_OK)
34864 + RETURN_ERROR(MAJOR, err, NO_MSG);
34865 +
34866 + return E_OK;
34867 +}
34868 +
34869 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
34870 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
34871 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
34872 +{
34873 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34874 + uint16_t keyIndex;
34875 + uint32_t intFlags;
34876 + t_Error err;
34877 +
34878 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34879 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
34880 +
34881 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
34882 +
34883 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34884 + if (GET_ERROR_TYPE(err) != E_OK)
34885 + {
34886 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34887 + RETURN_ERROR(MAJOR, err,
34888 + ("The received key and mask pair was not found in the "
34889 + "match table of the provided node"));
34890 + }
34891 +
34892 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
34893 +
34894 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
34895 +
34896 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
34897 +
34898 + if (err != E_OK)
34899 + RETURN_ERROR(MAJOR, err, NO_MSG);
34900 +
34901 + return E_OK;
34902 +}
34903 +
34904 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
34905 + uint8_t keySize, uint8_t *p_Key,
34906 + uint8_t hashShift,
34907 + t_Handle *p_CcNodeBucketHandle,
34908 + uint8_t *p_BucketIndex,
34909 + uint16_t *p_LastIndex)
34910 +{
34911 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34912 + uint16_t glblMask;
34913 + uint64_t crc64 = 0;
34914 +
34915 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
34916 + SANITY_CHECK_RETURN_ERROR(
34917 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
34918 + E_INVALID_STATE);
34919 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34920 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
34921 +
34922 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
34923 + be16_to_cpus(&glblMask);
34924 +
34925 + crc64 = crc64_init();
34926 + crc64 = crc64_compute(p_Key, keySize, crc64);
34927 + crc64 >>= hashShift;
34928 +
34929 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
34930 + & glblMask) >> 4);
34931 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
34932 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
34933 +
34934 + *p_CcNodeBucketHandle =
34935 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
34936 + if (!*p_CcNodeBucketHandle)
34937 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
34938 +
34939 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
34940 +
34941 + return E_OK;
34942 +}
34943 +
34944 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
34945 +{
34946 + t_FmPcdCcNode *p_CcNodeHashTbl;
34947 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
34948 + t_FmPcdCcNode *p_CcNode;
34949 + t_Handle h_MissStatsCounters = NULL;
34950 + t_FmPcdCcKeyParams *p_HashKeyParams;
34951 + int i;
34952 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
34953 + bool statsEnForMiss = FALSE;
34954 + t_Error err;
34955 +
34956 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
34957 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
34958 +
34959 + if (p_Param->maxNumOfKeys == 0)
34960 + {
34961 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
34962 + return NULL;
34963 + }
34964 +
34965 + if (p_Param->hashResMask == 0)
34966 + {
34967 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
34968 + return NULL;
34969 + }
34970 +
34971 + /*Fix: QorIQ SDK / QSDK-2131*/
34972 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
34973 + {
34974 + 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."));
34975 + return NULL;
34976 + }
34977 +
34978 +#if (DPAA_VERSION >= 11)
34979 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
34980 + {
34981 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
34982 + ("RMON statistics mode is not supported for hash table"));
34983 + return NULL;
34984 + }
34985 +#endif /* (DPAA_VERSION >= 11) */
34986 +
34987 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
34988 + sizeof(t_FmPcdCcNodeParams));
34989 + if (!p_ExactMatchCcNodeParam)
34990 + {
34991 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
34992 + return NULL;
34993 + }
34994 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
34995 +
34996 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
34997 + sizeof(t_FmPcdCcNodeParams));
34998 + if (!p_IndxHashCcNodeParam)
34999 + {
35000 + XX_Free(p_ExactMatchCcNodeParam);
35001 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
35002 + return NULL;
35003 + }
35004 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
35005 +
35006 + /* Calculate number of sets and number of ways of the hash table */
35007 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
35008 + while (countMask)
35009 + {
35010 + onesCount++;
35011 + countMask = (uint16_t)(countMask >> 1);
35012 + }
35013 +
35014 + numOfSets = (uint16_t)(1 << onesCount);
35015 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
35016 +
35017 + if (p_Param->maxNumOfKeys % numOfSets)
35018 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
35019 +
35020 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
35021 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
35022 + {
35023 + /* Allocating a statistics counters table that will be used by all
35024 + 'miss' entries of the hash table */
35025 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
35026 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
35027 + FM_PCD_CC_AD_TABLE_ALIGN);
35028 + if (!h_MissStatsCounters)
35029 + {
35030 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
35031 + XX_Free(p_IndxHashCcNodeParam);
35032 + XX_Free(p_ExactMatchCcNodeParam);
35033 + return NULL;
35034 + }
35035 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
35036 +
35037 + /* Always enable statistics for 'miss', so that a statistics AD will be
35038 + initialized from the start. We'll store the requested 'statistics enable'
35039 + value and it will be used when statistics are read by the user. */
35040 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
35041 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
35042 + }
35043 +
35044 + /* Building exact-match node params, will be used to create the hash buckets */
35045 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
35046 +
35047 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
35048 + e_FM_PCD_EXTRACT_FROM_KEY;
35049 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
35050 + e_FM_PCD_ACTION_EXACT_MATCH;
35051 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
35052 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
35053 + p_Param->matchKeySize;
35054 +
35055 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
35056 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
35057 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
35058 + p_Param->statisticsMode;
35059 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
35060 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
35061 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
35062 + p_Param->ccNextEngineParamsForMiss;
35063 +
35064 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
35065 +
35066 + for (i = 0; i < numOfSets; i++)
35067 + {
35068 + /* Each exact-match node will be marked as a 'bucket' and provided with
35069 + a pointer to statistics counters, to be used for 'miss' entry
35070 + statistics */
35071 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
35072 + if (!p_CcNode)
35073 + break;
35074 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
35075 +
35076 + p_CcNode->isHashBucket = TRUE;
35077 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
35078 +
35079 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
35080 + if (err)
35081 + break;
35082 +
35083 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
35084 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
35085 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
35086 + p_CcNode;
35087 + }
35088 +
35089 + if (i < numOfSets)
35090 + {
35091 + for (i = i - 1; i >= 0; i--)
35092 + FM_PCD_MatchTableDelete(
35093 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
35094 +
35095 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
35096 +
35097 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
35098 + XX_Free(p_IndxHashCcNodeParam);
35099 + XX_Free(p_ExactMatchCcNodeParam);
35100 + return NULL;
35101 + }
35102 +
35103 + /* Creating indexed-hash CC node */
35104 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
35105 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
35106 + e_FM_PCD_EXTRACT_FROM_HASH;
35107 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
35108 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
35109 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
35110 + p_Param->hashResMask;
35111 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
35112 + p_Param->hashShift;
35113 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
35114 +
35115 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
35116 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
35117 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
35118 + e_FM_PCD_CC_STATS_MODE_NONE;
35119 + /* Number of keys of this node is number of sets of the hash */
35120 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
35121 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
35122 +
35123 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
35124 +
35125 + if (p_CcNodeHashTbl)
35126 + {
35127 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
35128 +
35129 + /* Storing the allocated counters for buckets 'miss' in the hash table
35130 + and if statistics for miss were enabled. */
35131 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
35132 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
35133 + }
35134 +
35135 + XX_Free(p_IndxHashCcNodeParam);
35136 + XX_Free(p_ExactMatchCcNodeParam);
35137 +
35138 + return p_CcNodeHashTbl;
35139 +}
35140 +
35141 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
35142 +{
35143 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35144 + t_Handle h_FmPcd;
35145 + t_Handle *p_HashBuckets, h_MissStatsCounters;
35146 + uint16_t i, numOfBuckets;
35147 + t_Error err;
35148 +
35149 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35150 +
35151 + /* Store all hash buckets before the hash is freed */
35152 + numOfBuckets = p_HashTbl->numOfKeys;
35153 +
35154 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
35155 + if (!p_HashBuckets)
35156 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
35157 +
35158 + for (i = 0; i < numOfBuckets; i++)
35159 + p_HashBuckets[i] =
35160 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
35161 +
35162 + h_FmPcd = p_HashTbl->h_FmPcd;
35163 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
35164 +
35165 + /* Free the hash */
35166 + err = FM_PCD_MatchTableDelete(p_HashTbl);
35167 +
35168 + /* Free each hash bucket */
35169 + for (i = 0; i < numOfBuckets; i++)
35170 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
35171 +
35172 + XX_Free(p_HashBuckets);
35173 +
35174 + /* Free statistics counters for 'miss', if these were allocated */
35175 + if (h_MissStatsCounters)
35176 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
35177 +
35178 + if (err)
35179 + RETURN_ERROR(MAJOR, err, NO_MSG);
35180 +
35181 + return E_OK;
35182 +}
35183 +
35184 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
35185 + t_FmPcdCcKeyParams *p_KeyParams)
35186 +{
35187 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35188 + t_Handle h_HashBucket;
35189 + uint8_t bucketIndex;
35190 + uint16_t lastIndex;
35191 + t_Error err;
35192 +
35193 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35194 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
35195 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
35196 +
35197 + if (p_KeyParams->p_Mask)
35198 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35199 + ("Keys masks not supported for hash table"));
35200 +
35201 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
35202 + p_KeyParams->p_Key,
35203 + p_HashTbl->kgHashShift,
35204 + &h_HashBucket, &bucketIndex,
35205 + &lastIndex);
35206 + if (err)
35207 + RETURN_ERROR(MAJOR, err, NO_MSG);
35208 +
35209 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
35210 + p_KeyParams);
35211 +}
35212 +
35213 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
35214 + uint8_t *p_Key)
35215 +{
35216 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35217 + t_Handle h_HashBucket;
35218 + uint8_t bucketIndex;
35219 + uint16_t lastIndex;
35220 + t_Error err;
35221 +
35222 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35223 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35224 +
35225 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
35226 + p_HashTbl->kgHashShift,
35227 + &h_HashBucket, &bucketIndex,
35228 + &lastIndex);
35229 + if (err)
35230 + RETURN_ERROR(MAJOR, err, NO_MSG);
35231 +
35232 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
35233 +}
35234 +
35235 +t_Error FM_PCD_HashTableModifyNextEngine(
35236 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
35237 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35238 +{
35239 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35240 + t_Handle h_HashBucket;
35241 + uint8_t bucketIndex;
35242 + uint16_t lastIndex;
35243 + t_Error err;
35244 +
35245 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35246 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35247 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
35248 +
35249 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
35250 + p_HashTbl->kgHashShift,
35251 + &h_HashBucket, &bucketIndex,
35252 + &lastIndex);
35253 + if (err)
35254 + RETURN_ERROR(MAJOR, err, NO_MSG);
35255 +
35256 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
35257 + NULL,
35258 + p_FmPcdCcNextEngineParams);
35259 +}
35260 +
35261 +t_Error FM_PCD_HashTableModifyMissNextEngine(
35262 + t_Handle h_HashTbl,
35263 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35264 +{
35265 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35266 + t_Handle h_HashBucket;
35267 + uint8_t i;
35268 + bool nullifyMissStats = FALSE;
35269 + t_Error err;
35270 +
35271 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
35272 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
35273 +
35274 + if ((!p_HashTbl->h_MissStatsCounters)
35275 + && (p_FmPcdCcNextEngineParams->statisticsEn))
35276 + RETURN_ERROR(
35277 + MAJOR,
35278 + E_CONFLICT,
35279 + ("Statistics are requested for a key, but statistics mode was set"
35280 + "to 'NONE' upon initialization"));
35281 +
35282 + if (p_HashTbl->h_MissStatsCounters)
35283 + {
35284 + if ((!p_HashTbl->statsEnForMiss)
35285 + && (p_FmPcdCcNextEngineParams->statisticsEn))
35286 + nullifyMissStats = TRUE;
35287 +
35288 + if ((p_HashTbl->statsEnForMiss)
35289 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
35290 + {
35291 + p_HashTbl->statsEnForMiss = FALSE;
35292 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
35293 + }
35294 + }
35295 +
35296 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
35297 + {
35298 + h_HashBucket =
35299 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
35300 +
35301 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
35302 + p_FmPcdCcNextEngineParams);
35303 + if (err)
35304 + RETURN_ERROR(MAJOR, err, NO_MSG);
35305 + }
35306 +
35307 + if (nullifyMissStats)
35308 + {
35309 + memset(p_HashTbl->h_MissStatsCounters, 0,
35310 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
35311 + memset(p_HashTbl->h_MissStatsCounters, 0,
35312 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
35313 + p_HashTbl->statsEnForMiss = TRUE;
35314 + }
35315 +
35316 + return E_OK;
35317 +}
35318 +
35319 +
35320 +t_Error FM_PCD_HashTableGetMissNextEngine(
35321 + t_Handle h_HashTbl,
35322 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35323 +{
35324 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35325 + t_FmPcdCcNode *p_HashBucket;
35326 +
35327 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35328 +
35329 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
35330 + p_HashBucket =
35331 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
35332 +
35333 + memcpy(p_FmPcdCcNextEngineParams,
35334 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
35335 + sizeof(t_FmPcdCcNextEngineParams));
35336 +
35337 + return E_OK;
35338 +}
35339 +
35340 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
35341 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
35342 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
35343 +{
35344 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35345 + t_Handle h_HashBucket;
35346 + uint8_t bucketIndex;
35347 + uint16_t lastIndex;
35348 + t_Error err;
35349 +
35350 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35351 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35352 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
35353 +
35354 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
35355 + p_HashTbl->kgHashShift,
35356 + &h_HashBucket, &bucketIndex,
35357 + &lastIndex);
35358 + if (err)
35359 + RETURN_ERROR(MAJOR, err, NO_MSG);
35360 +
35361 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
35362 + NULL, p_KeyStatistics);
35363 +}
35364 +
35365 +t_Error FM_PCD_HashTableGetMissStatistics(
35366 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
35367 +{
35368 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35369 + t_Handle h_HashBucket;
35370 +
35371 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35372 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
35373 +
35374 + if (!p_HashTbl->statsEnForMiss)
35375 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35376 + ("Statistics were not enabled for miss"));
35377 +
35378 + h_HashBucket =
35379 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
35380 +
35381 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
35382 +}
35383 --- /dev/null
35384 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
35385 @@ -0,0 +1,399 @@
35386 +/*
35387 + * Copyright 2008-2012 Freescale Semiconductor Inc.
35388 + *
35389 + * Redistribution and use in source and binary forms, with or without
35390 + * modification, are permitted provided that the following conditions are met:
35391 + * * Redistributions of source code must retain the above copyright
35392 + * notice, this list of conditions and the following disclaimer.
35393 + * * Redistributions in binary form must reproduce the above copyright
35394 + * notice, this list of conditions and the following disclaimer in the
35395 + * documentation and/or other materials provided with the distribution.
35396 + * * Neither the name of Freescale Semiconductor nor the
35397 + * names of its contributors may be used to endorse or promote products
35398 + * derived from this software without specific prior written permission.
35399 + *
35400 + *
35401 + * ALTERNATIVELY, this software may be distributed under the terms of the
35402 + * GNU General Public License ("GPL") as published by the Free Software
35403 + * Foundation, either version 2 of that License or (at your option) any
35404 + * later version.
35405 + *
35406 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
35407 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35408 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35409 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
35410 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35411 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35412 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35413 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35414 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35415 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35416 + */
35417 +
35418 +
35419 +/******************************************************************************
35420 + @File fm_cc.h
35421 +
35422 + @Description FM PCD CC ...
35423 +*//***************************************************************************/
35424 +#ifndef __FM_CC_H
35425 +#define __FM_CC_H
35426 +
35427 +#include "std_ext.h"
35428 +#include "error_ext.h"
35429 +#include "list_ext.h"
35430 +
35431 +#include "fm_pcd.h"
35432 +
35433 +
35434 +/***********************************************************************/
35435 +/* Coarse classification defines */
35436 +/***********************************************************************/
35437 +
35438 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
35439 +
35440 +#define CC_PC_FF_MACDST 0x00
35441 +#define CC_PC_FF_MACSRC 0x01
35442 +#define CC_PC_FF_ETYPE 0x02
35443 +
35444 +#define CC_PC_FF_TCI1 0x03
35445 +#define CC_PC_FF_TCI2 0x04
35446 +
35447 +#define CC_PC_FF_MPLS1 0x06
35448 +#define CC_PC_FF_MPLS_LAST 0x07
35449 +
35450 +#define CC_PC_FF_IPV4DST1 0x08
35451 +#define CC_PC_FF_IPV4DST2 0x16
35452 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
35453 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
35454 +#define CC_PC_FF_IPV4PTYPE1 0x0A
35455 +#define CC_PC_FF_IPV4PTYPE2 0x18
35456 +#define CC_PC_FF_IPV4SRC1 0x0b
35457 +#define CC_PC_FF_IPV4SRC2 0x19
35458 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
35459 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
35460 +#define CC_PC_FF_IPV4TTL 0x29
35461 +
35462 +
35463 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
35464 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
35465 +#define CC_PC_FF_IPV6PTYPE1 0x0e
35466 +#define CC_PC_FF_IPV6PTYPE2 0x1c
35467 +#define CC_PC_FF_IPV6DST1 0x0f
35468 +#define CC_PC_FF_IPV6DST2 0x1d
35469 +#define CC_PC_FF_IPV6SRC1 0x10
35470 +#define CC_PC_FF_IPV6SRC2 0x1e
35471 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
35472 +#define CC_PC_FF_IPPID 0x24
35473 +#define CC_PC_FF_IPDSCP 0x76
35474 +
35475 +#define CC_PC_FF_GREPTYPE 0x11
35476 +
35477 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
35478 +#define CC_PC_FF_MINENCAP_IPDST 0x13
35479 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
35480 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
35481 +
35482 +#define CC_PC_FF_L4PSRC 0x1f
35483 +#define CC_PC_FF_L4PDST 0x20
35484 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
35485 +
35486 +#define CC_PC_FF_PPPPID 0x05
35487 +
35488 +#define CC_PC_PR_SHIM1 0x22
35489 +#define CC_PC_PR_SHIM2 0x23
35490 +
35491 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
35492 +#define CC_PC_GENERIC_WITH_MASK 0x28
35493 +#define CC_PC_GENERIC_IC_GMASK 0x2B
35494 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
35495 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
35496 +
35497 +#define CC_PR_OFFSET 0x25
35498 +#define CC_PR_WITHOUT_OFFSET 0x26
35499 +
35500 +#define CC_PC_PR_ETH_OFFSET 19
35501 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
35502 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
35503 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
35504 +#define CC_PC_PR_VLAN1_OFFSET 21
35505 +#define CC_PC_PR_VLAN2_OFFSET 22
35506 +#define CC_PC_PR_PPPOE_OFFSET 24
35507 +#define CC_PC_PR_MPLS1_OFFSET 25
35508 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
35509 +#define CC_PC_PR_IP1_OFFSET 27
35510 +#define CC_PC_PR_IP_LAST_OFFSET 28
35511 +#define CC_PC_PR_MINENC_OFFSET 28
35512 +#define CC_PC_PR_L4_OFFSET 30
35513 +#define CC_PC_PR_GRE_OFFSET 29
35514 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
35515 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
35516 +
35517 +#define CC_PC_ILLEGAL 0xff
35518 +#define CC_SIZE_ILLEGAL 0
35519 +
35520 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
35521 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
35522 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
35523 +#define FM_PCD_CC_NUM_OF_KEYS 255
35524 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
35525 +
35526 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
35527 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
35528 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
35529 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
35530 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
35531 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
35532 +
35533 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
35534 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
35535 +
35536 +#define FM_PCD_AD_STATS_TYPE 0x40000000
35537 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
35538 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
35539 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
35540 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
35541 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
35542 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
35543 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
35544 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
35545 +
35546 +
35547 +
35548 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
35549 +
35550 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
35551 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
35552 +
35553 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
35554 +#if (DPAA_VERSION >= 11)
35555 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
35556 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
35557 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
35558 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
35559 +#endif /* (DPAA_VERSION >= 11) */
35560 +
35561 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
35562 +#define CC_GLBL_MASK_SIZE 4
35563 +#define CC_AGING_MASK_SIZE 4
35564 +
35565 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
35566 +
35567 +#define CC_PRIVATE_INFO_NONE 0
35568 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
35569 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
35570 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
35571 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
35572 +
35573 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
35574 +/***********************************************************************/
35575 +/* Memory map */
35576 +/***********************************************************************/
35577 +#if defined(__MWERKS__) && !defined(__GNUC__)
35578 +#pragma pack(push,1)
35579 +#endif /* defined(__MWERKS__) && ... */
35580 +
35581 +typedef struct
35582 +{
35583 + volatile uint32_t fqid;
35584 + volatile uint32_t plcrProfile;
35585 + volatile uint32_t nia;
35586 + volatile uint32_t res;
35587 +} t_AdOfTypeResult;
35588 +
35589 +typedef struct
35590 +{
35591 + volatile uint32_t ccAdBase;
35592 + volatile uint32_t matchTblPtr;
35593 + volatile uint32_t pcAndOffsets;
35594 + volatile uint32_t gmask;
35595 +} t_AdOfTypeContLookup;
35596 +
35597 +typedef struct
35598 +{
35599 + volatile uint32_t profileTableAddr;
35600 + volatile uint32_t reserved;
35601 + volatile uint32_t nextActionIndx;
35602 + volatile uint32_t statsTableAddr;
35603 +} t_AdOfTypeStats;
35604 +
35605 +typedef union
35606 +{
35607 + volatile t_AdOfTypeResult adResult;
35608 + volatile t_AdOfTypeContLookup adContLookup;
35609 +} t_Ad;
35610 +
35611 +#if defined(__MWERKS__) && !defined(__GNUC__)
35612 +#pragma pack(pop)
35613 +#endif /* defined(__MWERKS__) && ... */
35614 +
35615 +
35616 +/***********************************************************************/
35617 +/* Driver's internal structures */
35618 +/***********************************************************************/
35619 +
35620 +typedef struct t_FmPcdStatsObj
35621 +{
35622 + t_Handle h_StatsAd;
35623 + t_Handle h_StatsCounters;
35624 + t_List node;
35625 +} t_FmPcdStatsObj;
35626 +
35627 +typedef struct
35628 +{
35629 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
35630 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
35631 +
35632 + t_FmPcdCcNextEngineParams nextEngineParams;
35633 + uint32_t requiredAction;
35634 + uint32_t shadowAction;
35635 +
35636 + t_FmPcdStatsObj *p_StatsObj;
35637 +
35638 +} t_FmPcdCcKeyAndNextEngineParams;
35639 +
35640 +typedef struct
35641 +{
35642 + t_Handle p_Ad;
35643 + e_FmPcdEngine fmPcdEngine;
35644 + bool adAllocated;
35645 + bool isTree;
35646 +
35647 + uint32_t myInfo;
35648 + t_List *h_CcNextNodesLst;
35649 + t_Handle h_AdditionalInfo;
35650 + t_Handle h_Node;
35651 +} t_FmPcdModifyCcAdditionalParams;
35652 +
35653 +typedef struct
35654 +{
35655 + t_Handle p_AdTableNew;
35656 + t_Handle p_KeysMatchTableNew;
35657 + t_Handle p_AdTableOld;
35658 + t_Handle p_KeysMatchTableOld;
35659 + uint16_t numOfKeys;
35660 + t_Handle h_CurrentNode;
35661 + uint16_t savedKeyIndex;
35662 + t_Handle h_NodeForAdd;
35663 + t_Handle h_NodeForRmv;
35664 + t_Handle h_ManipForRmv;
35665 + t_Handle h_ManipForAdd;
35666 + t_FmPcdStatsObj *p_StatsObjForRmv;
35667 +#if (DPAA_VERSION >= 11)
35668 + t_Handle h_FrmReplicForAdd;
35669 + t_Handle h_FrmReplicForRmv;
35670 +#endif /* (DPAA_VERSION >= 11) */
35671 + bool tree;
35672 +
35673 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
35674 +} t_FmPcdModifyCcKeyAdditionalParams;
35675 +
35676 +typedef struct
35677 +{
35678 + t_Handle h_Manip;
35679 + t_Handle h_CcNode;
35680 +} t_CcNextEngineInfo;
35681 +
35682 +typedef struct
35683 +{
35684 + uint16_t numOfKeys;
35685 + uint16_t maxNumOfKeys;
35686 +
35687 + bool maskSupport;
35688 + uint32_t keysMatchTableMaxSize;
35689 +
35690 + e_FmPcdCcStatsMode statisticsMode;
35691 + uint32_t numOfStatsFLRs;
35692 + uint32_t countersArraySize;
35693 +
35694 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
35695 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
35696 + Holds the statistics counters allocated by the hash table and
35697 + are shared by all hash table buckets; */
35698 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
35699 + Holds the statistics counters that were allocated for this node
35700 + and replaced by the shared counters (allocated by the hash table); */
35701 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
35702 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
35703 + returned statistics count to user, statistics AD always present for 'miss'
35704 + for all hash buckets; */
35705 + bool glblMaskUpdated;
35706 + t_Handle p_GlblMask;
35707 + bool lclMask;
35708 + uint8_t parseCode;
35709 + uint8_t offset;
35710 + uint8_t prsArrayOffset;
35711 + bool ctrlFlow;
35712 + uint16_t owners;
35713 +
35714 + uint8_t ccKeySizeAccExtraction;
35715 + uint8_t sizeOfExtraction;
35716 + uint8_t glblMaskSize;
35717 +
35718 + t_Handle h_KeysMatchTable;
35719 + t_Handle h_AdTable;
35720 + t_Handle h_StatsAds;
35721 + t_Handle h_TmpAd;
35722 + t_Handle h_Ad;
35723 + t_Handle h_StatsFLRs;
35724 +
35725 + t_List availableStatsLst;
35726 +
35727 + t_List ccPrevNodesLst;
35728 +
35729 + t_List ccTreeIdLst;
35730 + t_List ccTreesLst;
35731 +
35732 + t_Handle h_FmPcd;
35733 + uint32_t shadowAction;
35734 + uint8_t userSizeOfExtraction;
35735 + uint8_t userOffset;
35736 + uint8_t kgHashShift; /* used in hash-table */
35737 +
35738 + t_Handle h_Spinlock;
35739 +
35740 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
35741 +} t_FmPcdCcNode;
35742 +
35743 +typedef struct
35744 +{
35745 + t_FmPcdCcNode *p_FmPcdCcNode;
35746 + bool occupied;
35747 + uint16_t owners;
35748 + volatile bool lock;
35749 +} t_FmPcdCcNodeArray;
35750 +
35751 +typedef struct
35752 +{
35753 + uint8_t numOfEntriesInGroup;
35754 + uint32_t totalBitsMask;
35755 + uint8_t baseGroupEntry;
35756 +} t_FmPcdCcGroupParam;
35757 +
35758 +typedef struct
35759 +{
35760 + t_Handle h_FmPcd;
35761 + uint8_t netEnvId;
35762 + uintptr_t ccTreeBaseAddr;
35763 + uint8_t numOfGrps;
35764 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
35765 + t_List fmPortsLst;
35766 + t_FmPcdLock *p_Lock;
35767 + uint8_t numOfEntries;
35768 + uint16_t owners;
35769 + t_Handle h_FmPcdCcSavedManipParams;
35770 + bool modifiedState;
35771 + uint32_t requiredAction;
35772 + t_Handle h_IpReassemblyManip;
35773 + t_Handle h_CapwapReassemblyManip;
35774 +
35775 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
35776 +} t_FmPcdCcTree;
35777 +
35778 +
35779 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
35780 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
35781 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
35782 +
35783 +
35784 +#endif /* __FM_CC_H */
35785 --- /dev/null
35786 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
35787 @@ -0,0 +1,3242 @@
35788 +/*
35789 + * Copyright 2008-2012 Freescale Semiconductor Inc.
35790 + *
35791 + * Redistribution and use in source and binary forms, with or without
35792 + * modification, are permitted provided that the following conditions are met:
35793 + * * Redistributions of source code must retain the above copyright
35794 + * notice, this list of conditions and the following disclaimer.
35795 + * * Redistributions in binary form must reproduce the above copyright
35796 + * notice, this list of conditions and the following disclaimer in the
35797 + * documentation and/or other materials provided with the distribution.
35798 + * * Neither the name of Freescale Semiconductor nor the
35799 + * names of its contributors may be used to endorse or promote products
35800 + * derived from this software without specific prior written permission.
35801 + *
35802 + *
35803 + * ALTERNATIVELY, this software may be distributed under the terms of the
35804 + * GNU General Public License ("GPL") as published by the Free Software
35805 + * Foundation, either version 2 of that License or (at your option) any
35806 + * later version.
35807 + *
35808 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
35809 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35810 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35811 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
35812 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35813 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35814 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35815 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35816 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35817 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35818 + */
35819 +
35820 +
35821 +/******************************************************************************
35822 + @File fm_kg.c
35823 +
35824 + @Description FM PCD ...
35825 +*//***************************************************************************/
35826 +#include "std_ext.h"
35827 +#include "error_ext.h"
35828 +#include "string_ext.h"
35829 +#include "debug_ext.h"
35830 +#include "net_ext.h"
35831 +#include "fm_port_ext.h"
35832 +
35833 +#include "fm_common.h"
35834 +#include "fm_pcd.h"
35835 +#include "fm_hc.h"
35836 +#include "fm_pcd_ipc.h"
35837 +#include "fm_kg.h"
35838 +#include "fsl_fman_kg.h"
35839 +
35840 +
35841 +/****************************************/
35842 +/* static functions */
35843 +/****************************************/
35844 +
35845 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
35846 +{
35847 + ASSERT_COND(h_FmPcdKg);
35848 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
35849 +}
35850 +
35851 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
35852 +{
35853 + ASSERT_COND(h_FmPcdKg);
35854 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
35855 +}
35856 +
35857 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
35858 +{
35859 + ASSERT_COND(h_Scheme);
35860 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
35861 +}
35862 +
35863 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
35864 +{
35865 + ASSERT_COND(h_Scheme);
35866 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
35867 +}
35868 +
35869 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
35870 +{
35871 + ASSERT_COND(h_Scheme);
35872 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
35873 +}
35874 +
35875 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
35876 +{
35877 + ASSERT_COND(h_Scheme);
35878 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
35879 +}
35880 +
35881 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
35882 +{
35883 +
35884 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35885 +
35886 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
35887 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
35888 +
35889 + return E_OK;
35890 +}
35891 +
35892 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
35893 +{
35894 + int i;
35895 +
35896 + switch (code)
35897 + {
35898 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
35899 + case (KG_SCH_GEN_DEFAULT):
35900 + case (KG_SCH_GEN_NEXTHDR):
35901 + for (i=0 ; i<numOfSwDefaults ; i++)
35902 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
35903 + return swDefaults[i].dfltSelect;
35904 + break;
35905 + case (KG_SCH_GEN_SHIM1):
35906 + case (KG_SCH_GEN_SHIM2):
35907 + case (KG_SCH_GEN_IP_PID_NO_V):
35908 + case (KG_SCH_GEN_ETH_NO_V):
35909 + case (KG_SCH_GEN_SNAP_NO_V):
35910 + case (KG_SCH_GEN_VLAN1_NO_V):
35911 + case (KG_SCH_GEN_VLAN2_NO_V):
35912 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
35913 + case (KG_SCH_GEN_PPP_NO_V):
35914 + case (KG_SCH_GEN_MPLS1_NO_V):
35915 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
35916 + case (KG_SCH_GEN_L3_NO_V):
35917 + case (KG_SCH_GEN_IP2_NO_V):
35918 + case (KG_SCH_GEN_GRE_NO_V):
35919 + case (KG_SCH_GEN_L4_NO_V):
35920 + for (i=0 ; i<numOfSwDefaults ; i++)
35921 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
35922 + return swDefaults[i].dfltSelect;
35923 + break;
35924 + case (KG_SCH_GEN_START_OF_FRM):
35925 + case (KG_SCH_GEN_ETH):
35926 + case (KG_SCH_GEN_SNAP):
35927 + case (KG_SCH_GEN_VLAN1):
35928 + case (KG_SCH_GEN_VLAN2):
35929 + case (KG_SCH_GEN_ETH_TYPE):
35930 + case (KG_SCH_GEN_PPP):
35931 + case (KG_SCH_GEN_MPLS1):
35932 + case (KG_SCH_GEN_MPLS2):
35933 + case (KG_SCH_GEN_MPLS3):
35934 + case (KG_SCH_GEN_MPLS_LAST):
35935 + case (KG_SCH_GEN_IPV4):
35936 + case (KG_SCH_GEN_IPV6):
35937 + case (KG_SCH_GEN_IPV4_TUNNELED):
35938 + case (KG_SCH_GEN_IPV6_TUNNELED):
35939 + case (KG_SCH_GEN_MIN_ENCAP):
35940 + case (KG_SCH_GEN_GRE):
35941 + case (KG_SCH_GEN_TCP):
35942 + case (KG_SCH_GEN_UDP):
35943 + case (KG_SCH_GEN_IPSEC_AH):
35944 + case (KG_SCH_GEN_SCTP):
35945 + case (KG_SCH_GEN_DCCP):
35946 + case (KG_SCH_GEN_IPSEC_ESP):
35947 + for (i=0 ; i<numOfSwDefaults ; i++)
35948 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
35949 + return swDefaults[i].dfltSelect;
35950 + break;
35951 + default:
35952 + break;
35953 + }
35954 +
35955 + return e_FM_PCD_KG_DFLT_ILLEGAL;
35956 +}
35957 +
35958 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
35959 +{
35960 + *p_Offset = 0;
35961 +
35962 + switch (src)
35963 + {
35964 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
35965 + return KG_SCH_GEN_START_OF_FRM;
35966 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
35967 + return KG_SCH_GEN_DEFAULT;
35968 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
35969 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
35970 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
35971 + *p_Offset = 32;
35972 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
35973 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
35974 + return KG_SCH_GEN_NEXTHDR;
35975 + default:
35976 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
35977 + return 0;
35978 + }
35979 +}
35980 +
35981 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
35982 +{
35983 + if (!ignoreProtocolValidation)
35984 + switch (hdr)
35985 + {
35986 + case (HEADER_TYPE_NONE):
35987 + ASSERT_COND(FALSE);
35988 + case (HEADER_TYPE_ETH):
35989 + return KG_SCH_GEN_ETH;
35990 + case (HEADER_TYPE_LLC_SNAP):
35991 + return KG_SCH_GEN_SNAP;
35992 + case (HEADER_TYPE_PPPoE):
35993 + return KG_SCH_GEN_PPP;
35994 + case (HEADER_TYPE_MPLS):
35995 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
35996 + return KG_SCH_GEN_MPLS1;
35997 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
35998 + return KG_SCH_GEN_MPLS2;
35999 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
36000 + return KG_SCH_GEN_MPLS3;
36001 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36002 + return KG_SCH_GEN_MPLS_LAST;
36003 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
36004 + return 0;
36005 + case (HEADER_TYPE_IPv4):
36006 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36007 + return KG_SCH_GEN_IPV4;
36008 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
36009 + return KG_SCH_GEN_IPV4_TUNNELED;
36010 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
36011 + return 0;
36012 + case (HEADER_TYPE_IPv6):
36013 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36014 + return KG_SCH_GEN_IPV6;
36015 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
36016 + return KG_SCH_GEN_IPV6_TUNNELED;
36017 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
36018 + return 0;
36019 + case (HEADER_TYPE_GRE):
36020 + return KG_SCH_GEN_GRE;
36021 + case (HEADER_TYPE_TCP):
36022 + return KG_SCH_GEN_TCP;
36023 + case (HEADER_TYPE_UDP):
36024 + return KG_SCH_GEN_UDP;
36025 + case (HEADER_TYPE_IPSEC_AH):
36026 + return KG_SCH_GEN_IPSEC_AH;
36027 + case (HEADER_TYPE_IPSEC_ESP):
36028 + return KG_SCH_GEN_IPSEC_ESP;
36029 + case (HEADER_TYPE_SCTP):
36030 + return KG_SCH_GEN_SCTP;
36031 + case (HEADER_TYPE_DCCP):
36032 + return KG_SCH_GEN_DCCP;
36033 + default:
36034 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36035 + return 0;
36036 + }
36037 + else
36038 + switch (hdr)
36039 + {
36040 + case (HEADER_TYPE_NONE):
36041 + ASSERT_COND(FALSE);
36042 + case (HEADER_TYPE_ETH):
36043 + return KG_SCH_GEN_ETH_NO_V;
36044 + case (HEADER_TYPE_LLC_SNAP):
36045 + return KG_SCH_GEN_SNAP_NO_V;
36046 + case (HEADER_TYPE_PPPoE):
36047 + return KG_SCH_GEN_PPP_NO_V;
36048 + case (HEADER_TYPE_MPLS):
36049 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36050 + return KG_SCH_GEN_MPLS1_NO_V;
36051 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36052 + return KG_SCH_GEN_MPLS_LAST_NO_V;
36053 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
36054 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
36055 + else
36056 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
36057 + return 0;
36058 + case (HEADER_TYPE_IPv4):
36059 + case (HEADER_TYPE_IPv6):
36060 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36061 + return KG_SCH_GEN_L3_NO_V;
36062 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
36063 + return KG_SCH_GEN_IP2_NO_V;
36064 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
36065 + case (HEADER_TYPE_MINENCAP):
36066 + return KG_SCH_GEN_IP2_NO_V;
36067 + case (HEADER_TYPE_USER_DEFINED_L3):
36068 + return KG_SCH_GEN_L3_NO_V;
36069 + case (HEADER_TYPE_GRE):
36070 + return KG_SCH_GEN_GRE_NO_V;
36071 + case (HEADER_TYPE_TCP):
36072 + case (HEADER_TYPE_UDP):
36073 + case (HEADER_TYPE_IPSEC_AH):
36074 + case (HEADER_TYPE_IPSEC_ESP):
36075 + case (HEADER_TYPE_SCTP):
36076 + case (HEADER_TYPE_DCCP):
36077 + return KG_SCH_GEN_L4_NO_V;
36078 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
36079 + return KG_SCH_GEN_SHIM1;
36080 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
36081 + return KG_SCH_GEN_SHIM2;
36082 + default:
36083 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36084 + return 0;
36085 + }
36086 +}
36087 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
36088 +{
36089 + if (!ignoreProtocolValidation)
36090 + switch (hdr)
36091 + {
36092 + case (HEADER_TYPE_NONE):
36093 + ASSERT_COND(FALSE);
36094 + break;
36095 + case (HEADER_TYPE_ETH):
36096 + switch (field.eth)
36097 + {
36098 + case (NET_HEADER_FIELD_ETH_TYPE):
36099 + return KG_SCH_GEN_ETH_TYPE;
36100 + default:
36101 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36102 + return 0;
36103 + }
36104 + break;
36105 + case (HEADER_TYPE_VLAN):
36106 + switch (field.vlan)
36107 + {
36108 + case (NET_HEADER_FIELD_VLAN_TCI):
36109 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36110 + return KG_SCH_GEN_VLAN1;
36111 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36112 + return KG_SCH_GEN_VLAN2;
36113 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
36114 + return 0;
36115 + }
36116 + break;
36117 + case (HEADER_TYPE_MPLS):
36118 + case (HEADER_TYPE_IPSEC_AH):
36119 + case (HEADER_TYPE_IPSEC_ESP):
36120 + case (HEADER_TYPE_LLC_SNAP):
36121 + case (HEADER_TYPE_PPPoE):
36122 + case (HEADER_TYPE_IPv4):
36123 + case (HEADER_TYPE_IPv6):
36124 + case (HEADER_TYPE_GRE):
36125 + case (HEADER_TYPE_MINENCAP):
36126 + case (HEADER_TYPE_USER_DEFINED_L3):
36127 + case (HEADER_TYPE_TCP):
36128 + case (HEADER_TYPE_UDP):
36129 + case (HEADER_TYPE_SCTP):
36130 + case (HEADER_TYPE_DCCP):
36131 + case (HEADER_TYPE_USER_DEFINED_L4):
36132 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36133 + return 0;
36134 + default:
36135 + break;
36136 +
36137 + }
36138 + else
36139 + switch (hdr)
36140 + {
36141 + case (HEADER_TYPE_NONE):
36142 + ASSERT_COND(FALSE);
36143 + break;
36144 + case (HEADER_TYPE_ETH):
36145 + switch (field.eth)
36146 + {
36147 + case (NET_HEADER_FIELD_ETH_TYPE):
36148 + return KG_SCH_GEN_ETH_TYPE_NO_V;
36149 + default:
36150 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36151 + return 0;
36152 + }
36153 + break;
36154 + case (HEADER_TYPE_VLAN):
36155 + switch (field.vlan)
36156 + {
36157 + case (NET_HEADER_FIELD_VLAN_TCI) :
36158 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36159 + return KG_SCH_GEN_VLAN1_NO_V;
36160 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36161 + return KG_SCH_GEN_VLAN2_NO_V;
36162 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
36163 + return 0;
36164 + }
36165 + break;
36166 + case (HEADER_TYPE_IPv4):
36167 + switch (field.ipv4)
36168 + {
36169 + case (NET_HEADER_FIELD_IPv4_PROTO):
36170 + return KG_SCH_GEN_IP_PID_NO_V;
36171 + default:
36172 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36173 + return 0;
36174 + }
36175 + break;
36176 + case (HEADER_TYPE_IPv6):
36177 + switch (field.ipv6)
36178 + {
36179 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
36180 + return KG_SCH_GEN_IP_PID_NO_V;
36181 + default:
36182 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36183 + return 0;
36184 + }
36185 + break;
36186 + case (HEADER_TYPE_MPLS):
36187 + case (HEADER_TYPE_LLC_SNAP):
36188 + case (HEADER_TYPE_PPPoE):
36189 + case (HEADER_TYPE_GRE):
36190 + case (HEADER_TYPE_MINENCAP):
36191 + case (HEADER_TYPE_USER_DEFINED_L3):
36192 + case (HEADER_TYPE_TCP):
36193 + case (HEADER_TYPE_UDP):
36194 + case (HEADER_TYPE_IPSEC_AH):
36195 + case (HEADER_TYPE_IPSEC_ESP):
36196 + case (HEADER_TYPE_SCTP):
36197 + case (HEADER_TYPE_DCCP):
36198 + case (HEADER_TYPE_USER_DEFINED_L4):
36199 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36200 + return 0;
36201 + default:
36202 + break;
36203 + }
36204 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
36205 + return 0;
36206 +}
36207 +
36208 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
36209 +{
36210 + UNUSED(p_FmPcd);
36211 +
36212 + switch (hdr)
36213 + {
36214 + case (HEADER_TYPE_NONE):
36215 + ASSERT_COND(FALSE);
36216 + break;
36217 + case (HEADER_TYPE_ETH):
36218 + switch (field.eth)
36219 + {
36220 + case (NET_HEADER_FIELD_ETH_DA):
36221 + return KG_SCH_KN_MACDST;
36222 + case (NET_HEADER_FIELD_ETH_SA):
36223 + return KG_SCH_KN_MACSRC;
36224 + case (NET_HEADER_FIELD_ETH_TYPE):
36225 + return KG_SCH_KN_ETYPE;
36226 + default:
36227 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36228 + return 0;
36229 + }
36230 + case (HEADER_TYPE_LLC_SNAP):
36231 + switch (field.llcSnap)
36232 + {
36233 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
36234 + return KG_SCH_KN_ETYPE;
36235 + default:
36236 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36237 + return 0;
36238 + }
36239 + case (HEADER_TYPE_VLAN):
36240 + switch (field.vlan)
36241 + {
36242 + case (NET_HEADER_FIELD_VLAN_TCI):
36243 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36244 + return KG_SCH_KN_TCI1;
36245 + if (index == e_FM_PCD_HDR_INDEX_LAST)
36246 + return KG_SCH_KN_TCI2;
36247 + else
36248 + {
36249 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36250 + return 0;
36251 + }
36252 + default:
36253 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36254 + return 0;
36255 + }
36256 + case (HEADER_TYPE_MPLS):
36257 + switch (field.mpls)
36258 + {
36259 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
36260 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36261 + return KG_SCH_KN_MPLS1;
36262 + if (index == e_FM_PCD_HDR_INDEX_2)
36263 + return KG_SCH_KN_MPLS2;
36264 + if (index == e_FM_PCD_HDR_INDEX_LAST)
36265 + return KG_SCH_KN_MPLS_LAST;
36266 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
36267 + return 0;
36268 + default:
36269 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36270 + return 0;
36271 + }
36272 + case (HEADER_TYPE_IPv4):
36273 + switch (field.ipv4)
36274 + {
36275 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
36276 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36277 + return KG_SCH_KN_IPSRC1;
36278 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36279 + return KG_SCH_KN_IPSRC2;
36280 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36281 + return 0;
36282 + case (NET_HEADER_FIELD_IPv4_DST_IP):
36283 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36284 + return KG_SCH_KN_IPDST1;
36285 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36286 + return KG_SCH_KN_IPDST2;
36287 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36288 + return 0;
36289 + case (NET_HEADER_FIELD_IPv4_PROTO):
36290 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36291 + return KG_SCH_KN_PTYPE1;
36292 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36293 + return KG_SCH_KN_PTYPE2;
36294 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36295 + return 0;
36296 + case (NET_HEADER_FIELD_IPv4_TOS):
36297 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36298 + return KG_SCH_KN_IPTOS_TC1;
36299 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36300 + return KG_SCH_KN_IPTOS_TC2;
36301 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36302 + return 0;
36303 + default:
36304 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36305 + return 0;
36306 + }
36307 + case (HEADER_TYPE_IPv6):
36308 + switch (field.ipv6)
36309 + {
36310 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
36311 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36312 + return KG_SCH_KN_IPSRC1;
36313 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36314 + return KG_SCH_KN_IPSRC2;
36315 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36316 + return 0;
36317 + case (NET_HEADER_FIELD_IPv6_DST_IP):
36318 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36319 + return KG_SCH_KN_IPDST1;
36320 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36321 + return KG_SCH_KN_IPDST2;
36322 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36323 + return 0;
36324 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
36325 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36326 + return KG_SCH_KN_PTYPE1;
36327 + if (index == e_FM_PCD_HDR_INDEX_2)
36328 + return KG_SCH_KN_PTYPE2;
36329 + if (index == e_FM_PCD_HDR_INDEX_LAST)
36330 +#ifdef FM_KG_NO_IPPID_SUPPORT
36331 + if (p_FmPcd->fmRevInfo.majorRev < 6)
36332 + return KG_SCH_KN_PTYPE2;
36333 +#endif /* FM_KG_NO_IPPID_SUPPORT */
36334 + return KG_SCH_KN_IPPID;
36335 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36336 + return 0;
36337 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
36338 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36339 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
36340 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36341 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
36342 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36343 + return 0;
36344 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
36345 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36346 + return KG_SCH_KN_IPTOS_TC1;
36347 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36348 + return KG_SCH_KN_IPTOS_TC2;
36349 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36350 + return 0;
36351 + case (NET_HEADER_FIELD_IPv6_FL):
36352 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36353 + return KG_SCH_KN_IPV6FL1;
36354 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36355 + return KG_SCH_KN_IPV6FL2;
36356 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36357 + return 0;
36358 + default:
36359 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36360 + return 0;
36361 + }
36362 + case (HEADER_TYPE_GRE):
36363 + switch (field.gre)
36364 + {
36365 + case (NET_HEADER_FIELD_GRE_TYPE):
36366 + return KG_SCH_KN_GREPTYPE;
36367 + default:
36368 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36369 + return 0;
36370 + }
36371 + case (HEADER_TYPE_MINENCAP):
36372 + switch (field.minencap)
36373 + {
36374 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
36375 + return KG_SCH_KN_IPSRC2;
36376 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
36377 + return KG_SCH_KN_IPDST2;
36378 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
36379 + return KG_SCH_KN_PTYPE2;
36380 + default:
36381 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36382 + return 0;
36383 + }
36384 + case (HEADER_TYPE_TCP):
36385 + switch (field.tcp)
36386 + {
36387 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
36388 + return KG_SCH_KN_L4PSRC;
36389 + case (NET_HEADER_FIELD_TCP_PORT_DST):
36390 + return KG_SCH_KN_L4PDST;
36391 + case (NET_HEADER_FIELD_TCP_FLAGS):
36392 + return KG_SCH_KN_TFLG;
36393 + default:
36394 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36395 + return 0;
36396 + }
36397 + case (HEADER_TYPE_UDP):
36398 + switch (field.udp)
36399 + {
36400 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
36401 + return KG_SCH_KN_L4PSRC;
36402 + case (NET_HEADER_FIELD_UDP_PORT_DST):
36403 + return KG_SCH_KN_L4PDST;
36404 + default:
36405 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36406 + return 0;
36407 + }
36408 + case (HEADER_TYPE_IPSEC_AH):
36409 + switch (field.ipsecAh)
36410 + {
36411 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
36412 + return KG_SCH_KN_IPSEC_SPI;
36413 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
36414 + return KG_SCH_KN_IPSEC_NH;
36415 + default:
36416 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36417 + return 0;
36418 + }
36419 + case (HEADER_TYPE_IPSEC_ESP):
36420 + switch (field.ipsecEsp)
36421 + {
36422 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
36423 + return KG_SCH_KN_IPSEC_SPI;
36424 + default:
36425 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36426 + return 0;
36427 + }
36428 + case (HEADER_TYPE_SCTP):
36429 + switch (field.sctp)
36430 + {
36431 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
36432 + return KG_SCH_KN_L4PSRC;
36433 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
36434 + return KG_SCH_KN_L4PDST;
36435 + default:
36436 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36437 + return 0;
36438 + }
36439 + case (HEADER_TYPE_DCCP):
36440 + switch (field.dccp)
36441 + {
36442 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
36443 + return KG_SCH_KN_L4PSRC;
36444 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
36445 + return KG_SCH_KN_L4PDST;
36446 + default:
36447 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36448 + return 0;
36449 + }
36450 + case (HEADER_TYPE_PPPoE):
36451 + switch (field.pppoe)
36452 + {
36453 + case (NET_HEADER_FIELD_PPPoE_PID):
36454 + return KG_SCH_KN_PPPID;
36455 + case (NET_HEADER_FIELD_PPPoE_SID):
36456 + return KG_SCH_KN_PPPSID;
36457 + default:
36458 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36459 + return 0;
36460 + }
36461 + default:
36462 + break;
36463 +
36464 + }
36465 +
36466 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36467 + return 0;
36468 +}
36469 +
36470 +
36471 +static uint8_t GetKnownFieldId(uint32_t bitMask)
36472 +{
36473 + uint8_t cnt = 0;
36474 +
36475 + while (bitMask)
36476 + if (bitMask & 0x80000000)
36477 + break;
36478 + else
36479 + {
36480 + cnt++;
36481 + bitMask <<= 1;
36482 + }
36483 + return cnt;
36484 +
36485 +}
36486 +
36487 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
36488 +{
36489 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
36490 +
36491 + /* bitOffset 1-7 --> mask 0x1-0x7F */
36492 + if (bitOffset<8)
36493 + {
36494 + mask = 0;
36495 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
36496 + mask |= walking1Mask;
36497 + }
36498 + else
36499 + {
36500 + mask = 0xFF;
36501 + numOfOnesToClear = 0;
36502 + if (fqid && bitOffset>24)
36503 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
36504 + numOfOnesToClear = (uint8_t)(bitOffset-24);
36505 + else
36506 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
36507 + if (!fqid && bitOffset>8)
36508 + numOfOnesToClear = (uint8_t)(bitOffset-8);
36509 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
36510 + mask &= ~walking1Mask;
36511 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
36512 + }
36513 + return mask;
36514 +}
36515 +
36516 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
36517 +{
36518 + t_FmPcdKg *p_FmPcdKg;
36519 + t_FmPcdKgScheme *p_Scheme;
36520 + uint32_t intFlags;
36521 + uint8_t relativeSchemeId;
36522 + int i;
36523 +
36524 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
36525 +
36526 + /* for each scheme - update owners counters */
36527 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
36528 + {
36529 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36530 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
36531 +
36532 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
36533 +
36534 + /* increment owners number */
36535 + intFlags = KgSchemeLock(p_Scheme);
36536 + p_Scheme->owners++;
36537 + KgSchemeUnlock(p_Scheme, intFlags);
36538 + }
36539 +}
36540 +
36541 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
36542 +{
36543 + t_FmPcdKg *p_FmPcdKg;
36544 + t_FmPcdKgScheme *p_Scheme;
36545 + uint32_t intFlags;
36546 + uint8_t relativeSchemeId;
36547 + int i;
36548 +
36549 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
36550 +
36551 + /* for each scheme - update owners counters */
36552 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
36553 + {
36554 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36555 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
36556 +
36557 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
36558 +
36559 + /* increment owners number */
36560 + ASSERT_COND(p_Scheme->owners);
36561 + intFlags = KgSchemeLock(p_Scheme);
36562 + p_Scheme->owners--;
36563 + KgSchemeUnlock(p_Scheme, intFlags);
36564 + }
36565 +}
36566 +
36567 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
36568 +{
36569 + /* this routine is locked by the calling routine */
36570 + ASSERT_COND(p_Scheme);
36571 + ASSERT_COND(p_Scheme->valid);
36572 +
36573 + if (set)
36574 + p_Scheme->requiredActionFlag = TRUE;
36575 + else
36576 + {
36577 + p_Scheme->requiredAction = 0;
36578 + p_Scheme->requiredActionFlag = FALSE;
36579 + }
36580 +}
36581 +
36582 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
36583 +{
36584 + struct fman_kg_regs *p_KgRegs;
36585 +
36586 + uint32_t tmpKgarReg = 0, intFlags;
36587 + t_Error err = E_OK;
36588 +
36589 + /* The calling routine had locked the port, so for each port only one core can access
36590 + * (so we don't need a lock here) */
36591 +
36592 + if (p_FmPcd->h_Hc)
36593 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
36594 +
36595 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36596 +
36597 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
36598 + /* lock a common KG reg */
36599 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36600 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
36601 + if (err)
36602 + {
36603 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36604 + RETURN_ERROR(MINOR, err, NO_MSG);
36605 + }
36606 +
36607 + fman_kg_write_sp(p_KgRegs, spReg, add);
36608 +
36609 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
36610 +
36611 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
36612 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36613 + return err;
36614 +}
36615 +
36616 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
36617 +{
36618 + struct fman_kg_regs *p_KgRegs;
36619 + uint32_t tmpKgarReg, intFlags;
36620 + t_Error err;
36621 +
36622 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36623 +
36624 + if (p_FmPcd->h_Hc)
36625 + {
36626 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
36627 + return err;
36628 + }
36629 +
36630 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36631 + fman_kg_write_cpp(p_KgRegs, cppReg);
36632 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
36633 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
36634 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36635 +
36636 + return err;
36637 +}
36638 +
36639 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
36640 +{
36641 + uint32_t tmpKgpeCpp;
36642 +
36643 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
36644 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
36645 +
36646 + return tmpKgpeCpp;
36647 +}
36648 +
36649 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
36650 +{
36651 + uint32_t tmpKgpeCpp = 0;
36652 +
36653 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
36654 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
36655 +}
36656 +
36657 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
36658 +{
36659 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
36660 +}
36661 +
36662 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
36663 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
36664 +{
36665 + return (uint32_t)(FM_KG_KGAR_GO |
36666 + FM_KG_KGAR_READ |
36667 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
36668 + DUMMY_PORT_ID |
36669 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36670 + FM_PCD_KG_KGAR_WSEL_MASK);
36671 +
36672 + /* if we ever want to write 1 by 1, use:
36673 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
36674 + */
36675 +}
36676 +#endif /* (defined(DEBUG_ERRORS) && ... */
36677 +
36678 +static void PcdKgErrorException(t_Handle h_FmPcd)
36679 +{
36680 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36681 + uint32_t event,schemeIndexes = 0, index = 0;
36682 + struct fman_kg_regs *p_KgRegs;
36683 +
36684 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36685 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36686 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
36687 +
36688 + if (event & FM_EX_KG_DOUBLE_ECC)
36689 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
36690 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
36691 + {
36692 + if (schemeIndexes)
36693 + {
36694 + while (schemeIndexes)
36695 + {
36696 + if (schemeIndexes & 0x1)
36697 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
36698 + schemeIndexes >>= 1;
36699 + index+=1;
36700 + }
36701 + }
36702 + else /* this should happen only when interrupt is forced. */
36703 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
36704 + }
36705 +}
36706 +
36707 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
36708 +{
36709 + t_Error err = E_OK;
36710 + t_FmPcdIpcKgSchemesParams kgAlloc;
36711 + uint32_t replyLength;
36712 + t_FmPcdIpcReply reply;
36713 + t_FmPcdIpcMsg msg;
36714 +
36715 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
36716 +
36717 + /* in GUEST_PARTITION, we use the IPC */
36718 + memset(&reply, 0, sizeof(reply));
36719 + memset(&msg, 0, sizeof(msg));
36720 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
36721 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36722 + kgAlloc.guestId = p_FmPcd->guestId;
36723 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
36724 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36725 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
36726 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36727 + (uint8_t*)&msg,
36728 + sizeof(msg.msgId) + sizeof(kgAlloc),
36729 + (uint8_t*)&reply,
36730 + &replyLength,
36731 + NULL,
36732 + NULL)) != E_OK)
36733 + RETURN_ERROR(MAJOR, err, NO_MSG);
36734 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
36735 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36736 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
36737 +
36738 + return (t_Error)reply.error;
36739 +}
36740 +
36741 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
36742 +{
36743 + t_Error err = E_OK;
36744 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36745 +
36746 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
36747 +
36748 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
36749 + FmEnableRamsEcc(p_FmPcd->h_Fm);
36750 +
36751 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
36752 +
36753 + /* register even if no interrupts enabled, to allow future enablement */
36754 + FmRegisterIntr(p_FmPcd->h_Fm,
36755 + e_FM_MOD_KG,
36756 + 0,
36757 + e_FM_INTR_TYPE_ERR,
36758 + PcdKgErrorException,
36759 + p_FmPcd);
36760 +
36761 + fman_kg_enable_scheme_interrupts(p_Regs);
36762 +
36763 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
36764 + {
36765 + err = FmPcdKgAllocSchemes(p_FmPcd,
36766 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36767 + p_FmPcd->guestId,
36768 + p_FmPcd->p_FmPcdKg->schemesIds);
36769 + if (err)
36770 + RETURN_ERROR(MINOR, err, NO_MSG);
36771 + }
36772 +
36773 + return E_OK;
36774 +}
36775 +
36776 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
36777 +{
36778 + ASSERT_COND(!p_Scheme->valid);
36779 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
36780 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
36781 + p_Scheme->valid = TRUE;
36782 +}
36783 +
36784 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
36785 +{
36786 + if (p_Scheme->owners)
36787 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
36788 +
36789 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
36790 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
36791 + p_Scheme->valid = FALSE;
36792 +
36793 + return E_OK;
36794 +}
36795 +
36796 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
36797 + t_FmPcdKgSchemeParams *p_SchemeParams,
36798 + struct fman_kg_scheme_regs *p_SchemeRegs)
36799 +{
36800 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
36801 + uint32_t grpBits = 0;
36802 + uint8_t grpBase;
36803 + bool direct=TRUE, absolute=FALSE;
36804 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
36805 + t_Error err = E_OK;
36806 + int i = 0;
36807 + t_NetEnvParams netEnvParams;
36808 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
36809 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
36810 + uint8_t j, curr, idx;
36811 + uint8_t id, shift=0, code=0, offset=0, size=0;
36812 + t_FmPcdExtractEntry *p_Extract = NULL;
36813 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
36814 + bool generic = FALSE;
36815 + t_KnownFieldsMasks bitMask;
36816 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
36817 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
36818 + uint8_t numOfSwDefaults = 0;
36819 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
36820 + uint8_t currGenId = 0;
36821 +
36822 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
36823 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
36824 +
36825 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
36826 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
36827 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
36828 +
36829 + /* by netEnv parameters, get match vector */
36830 + if (!p_SchemeParams->alwaysDirect)
36831 + {
36832 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
36833 + netEnvParams.netEnvId = p_Scheme->netEnvId;
36834 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
36835 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
36836 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
36837 + if (err)
36838 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
36839 + p_Scheme->matchVector = netEnvParams.vector;
36840 + }
36841 + else
36842 + {
36843 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
36844 + p_Scheme->netEnvId = ILLEGAL_NETENV;
36845 + }
36846 +
36847 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
36848 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
36849 +
36850 + if (p_SchemeParams->bypassFqidGeneration)
36851 + {
36852 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
36853 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
36854 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
36855 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
36856 + if (p_SchemeParams->baseFqid)
36857 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
36858 + }
36859 + else
36860 + if (!p_SchemeParams->baseFqid)
36861 + DBG(WARNING, ("baseFqid is 0."));
36862 +
36863 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
36864 + {
36865 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
36866 + p_Scheme->directPlcr = direct;
36867 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
36868 + if (!direct && absolute)
36869 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
36870 +
36871 + if (direct)
36872 + {
36873 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
36874 + numOfProfiles = 1;
36875 + }
36876 + else
36877 + {
36878 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
36879 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
36880 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
36881 + }
36882 + }
36883 +
36884 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
36885 + {
36886 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
36887 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
36888 + {
36889 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
36890 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
36891 + }
36892 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
36893 +
36894 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
36895 + p_SchemeParams->kgNextEngineParams.cc.grpId,
36896 + &grpBits,
36897 + &grpBase);
36898 + if (err)
36899 + RETURN_ERROR(MAJOR, err, NO_MSG);
36900 + p_Scheme->ccUnits = grpBits;
36901 +
36902 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
36903 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
36904 + {
36905 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
36906 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
36907 + absolute = FALSE;
36908 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
36909 + if (direct)
36910 + {
36911 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
36912 + numOfProfiles = 1;
36913 + }
36914 + else
36915 + {
36916 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
36917 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
36918 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
36919 + }
36920 + }
36921 + }
36922 +
36923 + /* if policer is used directly after KG, or after CC */
36924 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
36925 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
36926 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
36927 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
36928 + {
36929 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
36930 + if (absolute)
36931 + {
36932 + /* for absolute direct policy only, */
36933 + relativeProfileId = profileId;
36934 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
36935 + if (err)
36936 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
36937 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
36938 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
36939 + p_Scheme->relativeProfileId = profileId;
36940 + }
36941 + else
36942 + {
36943 + /* save relative profile id's for later check */
36944 + p_Scheme->nextRelativePlcrProfile = TRUE;
36945 + p_Scheme->relativeProfileId = profileId;
36946 + p_Scheme->numOfProfiles = numOfProfiles;
36947 + }
36948 + }
36949 + else
36950 + {
36951 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
36952 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
36953 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
36954 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
36955 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
36956 + if (p_SchemeParams->bypassFqidGeneration &&
36957 + p_SchemeParams->useHash &&
36958 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
36959 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
36960 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
36961 + }
36962 +
36963 + /* configure all 21 scheme registers */
36964 + tmpReg = KG_SCH_MODE_EN;
36965 + switch (p_SchemeParams->nextEngine)
36966 + {
36967 + case (e_FM_PCD_PLCR):
36968 + /* add to mode register - NIA */
36969 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
36970 + tmpReg |= NIA_ENG_PLCR;
36971 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
36972 + /* initialize policer profile command - */
36973 + /* configure kgse_ppc */
36974 + if (direct)
36975 + /* use profileId as base, other fields are 0 */
36976 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
36977 + else
36978 + {
36979 + if (shift > MAX_PP_SHIFT)
36980 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
36981 +
36982 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
36983 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
36984 +
36985 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
36986 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
36987 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
36988 + ppcTmp |= (uint32_t)profileId;
36989 +
36990 + p_SchemeRegs->kgse_ppc = ppcTmp;
36991 + }
36992 + break;
36993 + case (e_FM_PCD_CC):
36994 + /* mode reg - define NIA */
36995 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
36996 +
36997 + p_SchemeRegs->kgse_ccbs = grpBits;
36998 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
36999 +
37000 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
37001 + {
37002 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
37003 + {
37004 + /* find out if absolute or relative */
37005 + if (absolute)
37006 + 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"));
37007 + if (direct)
37008 + {
37009 + /* mask = 0, base = directProfileId */
37010 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
37011 + }
37012 + else
37013 + {
37014 + if (shift > MAX_PP_SHIFT)
37015 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
37016 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
37017 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
37018 +
37019 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
37020 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
37021 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
37022 + ppcTmp |= (uint32_t)profileId;
37023 +
37024 + p_SchemeRegs->kgse_ppc = ppcTmp;
37025 + }
37026 + }
37027 + }
37028 + break;
37029 + case (e_FM_PCD_DONE):
37030 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
37031 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
37032 + else
37033 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
37034 + break;
37035 + default:
37036 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
37037 + }
37038 + p_SchemeRegs->kgse_mode = tmpReg;
37039 +
37040 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
37041 +
37042 +#if (DPAA_VERSION >= 11)
37043 + if (p_SchemeParams->overrideStorageProfile)
37044 + {
37045 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
37046 +
37047 + if (p_SchemeParams->storageProfile.direct)
37048 + {
37049 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
37050 + shift = 0;
37051 + numOfProfiles = 1;
37052 + }
37053 + else
37054 + {
37055 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
37056 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
37057 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
37058 + }
37059 + if (shift > MAX_SP_SHIFT)
37060 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
37061 +
37062 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
37063 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
37064 +
37065 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
37066 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
37067 + tmpReg |= (uint32_t)profileId;
37068 +
37069 +
37070 + p_SchemeRegs->kgse_vsp = tmpReg;
37071 +
37072 + p_Scheme->vspe = TRUE;
37073 +
37074 + }
37075 + else
37076 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
37077 +#endif /* (DPAA_VERSION >= 11) */
37078 +
37079 + if (p_SchemeParams->useHash)
37080 + {
37081 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
37082 +
37083 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
37084 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
37085 +
37086 + /* configure kgse_dv0 */
37087 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
37088 +
37089 + /* configure kgse_dv1 */
37090 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
37091 +
37092 + if (!p_SchemeParams->bypassFqidGeneration)
37093 + {
37094 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
37095 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
37096 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
37097 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
37098 + }
37099 +
37100 + /* configure kgse_ekdv */
37101 + tmpReg = 0;
37102 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
37103 + {
37104 + switch (p_KeyAndHash->dflts[i].type)
37105 + {
37106 + case (e_FM_PCD_KG_MAC_ADDR):
37107 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
37108 + break;
37109 + case (e_FM_PCD_KG_TCI):
37110 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
37111 + break;
37112 + case (e_FM_PCD_KG_ENET_TYPE):
37113 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
37114 + break;
37115 + case (e_FM_PCD_KG_PPP_SESSION_ID):
37116 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
37117 + break;
37118 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
37119 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
37120 + break;
37121 + case (e_FM_PCD_KG_MPLS_LABEL):
37122 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
37123 + break;
37124 + case (e_FM_PCD_KG_IP_ADDR):
37125 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
37126 + break;
37127 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
37128 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
37129 + break;
37130 + case (e_FM_PCD_KG_IP_TOS_TC):
37131 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
37132 + break;
37133 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
37134 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
37135 + break;
37136 + case (e_FM_PCD_KG_IPSEC_SPI):
37137 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
37138 + break;
37139 + case (e_FM_PCD_KG_L4_PORT):
37140 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
37141 + break;
37142 + case (e_FM_PCD_KG_TCP_FLAG):
37143 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
37144 + break;
37145 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
37146 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
37147 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
37148 + numOfSwDefaults ++;
37149 + break;
37150 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
37151 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
37152 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
37153 + numOfSwDefaults ++;
37154 + break;
37155 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
37156 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
37157 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
37158 + numOfSwDefaults ++;
37159 + break;
37160 + default:
37161 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37162 + }
37163 + }
37164 + p_SchemeRegs->kgse_ekdv = tmpReg;
37165 +
37166 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
37167 + if (!p_LocalExtractsArray)
37168 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
37169 +
37170 + /* configure kgse_ekfc and kgse_gec */
37171 + knownTmp = 0;
37172 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
37173 + {
37174 + p_Extract = &p_KeyAndHash->extractArray[i];
37175 + switch (p_Extract->type)
37176 + {
37177 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
37178 + knownTmp |= KG_SCH_KN_PORT_ID;
37179 + /* save in driver structure */
37180 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
37181 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
37182 + break;
37183 + case (e_FM_PCD_EXTRACT_BY_HDR):
37184 + switch (p_Extract->extractByHdr.hdr)
37185 + {
37186 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
37187 + case (HEADER_TYPE_UDP_LITE):
37188 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37189 + break;
37190 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
37191 + case (HEADER_TYPE_UDP_ENCAP_ESP):
37192 + switch (p_Extract->extractByHdr.type)
37193 + {
37194 + case (e_FM_PCD_EXTRACT_FROM_HDR):
37195 + /* case where extraction from ESP only */
37196 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
37197 + {
37198 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37199 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
37200 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37201 + }
37202 + else
37203 + {
37204 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37205 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
37206 + }
37207 + break;
37208 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
37209 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
37210 + {
37211 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
37212 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
37213 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
37214 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
37215 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37216 + break;
37217 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
37218 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37219 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37220 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
37221 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37222 + break;
37223 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
37224 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37225 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37226 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
37227 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37228 + break;
37229 + }
37230 + break;
37231 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
37232 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
37233 + {
37234 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
37235 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
37236 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
37237 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
37238 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37239 + break;
37240 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
37241 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37242 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37243 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
37244 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
37245 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37246 + break;
37247 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
37248 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37249 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37250 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
37251 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
37252 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37253 + break;
37254 + }
37255 + break;
37256 + }
37257 + break;
37258 + default:
37259 + break;
37260 + }
37261 + switch (p_Extract->extractByHdr.type)
37262 + {
37263 + case (e_FM_PCD_EXTRACT_FROM_HDR):
37264 + generic = TRUE;
37265 + /* get the header code for the generic extract */
37266 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
37267 + /* set generic register fields */
37268 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
37269 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
37270 + break;
37271 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
37272 + generic = TRUE;
37273 + /* get the field code for the generic extract */
37274 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
37275 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
37276 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
37277 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
37278 + break;
37279 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
37280 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
37281 + {
37282 + /* if we have a known field for it - use it, otherwise use generic */
37283 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
37284 + p_Extract->extractByHdr.extractByHdrType.fullField);
37285 + if (bitMask)
37286 + {
37287 + knownTmp |= bitMask;
37288 + /* save in driver structure */
37289 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
37290 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
37291 + }
37292 + else
37293 + generic = TRUE;
37294 + }
37295 + else
37296 + generic = TRUE;
37297 + if (generic)
37298 + {
37299 + /* tmp - till we cover more headers under generic */
37300 + XX_Free(p_LocalExtractsArray);
37301 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
37302 + }
37303 + break;
37304 + default:
37305 + XX_Free(p_LocalExtractsArray);
37306 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37307 + }
37308 + break;
37309 + case (e_FM_PCD_EXTRACT_NON_HDR):
37310 + /* use generic */
37311 + generic = TRUE;
37312 + offset = 0;
37313 + /* get the field code for the generic extract */
37314 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
37315 + offset += p_Extract->extractNonHdr.offset;
37316 + size = p_Extract->extractNonHdr.size;
37317 + break;
37318 + default:
37319 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37320 + }
37321 +
37322 + if (generic)
37323 + {
37324 + /* set generic register fields */
37325 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
37326 + {
37327 + XX_Free(p_LocalExtractsArray);
37328 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
37329 + }
37330 + if (!code)
37331 + {
37332 + XX_Free(p_LocalExtractsArray);
37333 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
37334 + }
37335 +
37336 + genTmp = KG_SCH_GEN_VALID;
37337 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
37338 + genTmp |= offset;
37339 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
37340 + {
37341 + XX_Free(p_LocalExtractsArray);
37342 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
37343 + }
37344 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
37345 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
37346 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
37347 + DBG(WARNING, ("No sw default configured"));
37348 + else
37349 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
37350 +
37351 + genTmp |= KG_SCH_GEN_MASK;
37352 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
37353 + /* save in driver structure */
37354 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
37355 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
37356 + generic = FALSE;
37357 + }
37358 + }
37359 + p_SchemeRegs->kgse_ekfc = knownTmp;
37360 +
37361 + selectTmp = 0;
37362 + maskTmp = 0xFFFFFFFF;
37363 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
37364 +
37365 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
37366 + {
37367 + XX_Free(p_LocalExtractsArray);
37368 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
37369 + }
37370 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
37371 + {
37372 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
37373 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
37374 + /* Get the shift of the select field (depending on i) */
37375 + GET_MASK_SEL_SHIFT(shift,i);
37376 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
37377 + selectTmp |= id << shift;
37378 + else
37379 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
37380 +
37381 + /* Get the shift of the offset field (depending on i) - may
37382 + be in kgse_bmch or in kgse_fqb (depending on i) */
37383 + GET_MASK_OFFSET_SHIFT(shift,i);
37384 + if (i<=1)
37385 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
37386 + else
37387 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
37388 +
37389 + /* Get the shift of the mask field (depending on i) */
37390 + GET_MASK_SHIFT(shift,i);
37391 + /* pass all bits */
37392 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
37393 + /* clear bits that need masking */
37394 + maskTmp &= ~(0xFF << shift) ;
37395 + /* set mask bits */
37396 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
37397 + }
37398 + p_SchemeRegs->kgse_bmch = selectTmp;
37399 + p_SchemeRegs->kgse_bmcl = maskTmp;
37400 + /* kgse_fqb will be written t the end of the routine */
37401 +
37402 + /* configure kgse_hc */
37403 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
37404 + {
37405 + XX_Free(p_LocalExtractsArray);
37406 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
37407 + }
37408 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
37409 + {
37410 + XX_Free(p_LocalExtractsArray);
37411 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
37412 + }
37413 +
37414 + tmpReg = 0;
37415 +
37416 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
37417 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
37418 +
37419 + if (p_KeyAndHash->symmetricHash)
37420 + {
37421 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
37422 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
37423 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
37424 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
37425 + {
37426 + XX_Free(p_LocalExtractsArray);
37427 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
37428 + }
37429 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
37430 + }
37431 + p_SchemeRegs->kgse_hc = tmpReg;
37432 +
37433 + /* build the return array describing the order of the extractions */
37434 +
37435 + /* the last currGenId places of the array
37436 + are for generic extracts that are always last.
37437 + We now sort for the calculation of the order of the known
37438 + extractions we sort the known extracts between orderedArray[0] and
37439 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
37440 + for the calculation of the order of the generic extractions we use:
37441 + num_of_generic - currGenId
37442 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
37443 + first_generic_index = num_of_known */
37444 + curr = 0;
37445 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
37446 + {
37447 + if (p_LocalExtractsArray->extractsArray[i].known)
37448 + {
37449 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
37450 + j = curr;
37451 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
37452 + index in the user's extractions array */
37453 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
37454 + location */
37455 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
37456 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
37457 + {
37458 + p_Scheme->orderedArray[j] =
37459 + p_Scheme->orderedArray[j-1];
37460 + j--;
37461 + }
37462 + p_Scheme->orderedArray[j] = (uint8_t)i;
37463 + curr++;
37464 + }
37465 + else
37466 + {
37467 + /* index is first_generic_index + generic index (id) */
37468 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
37469 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
37470 + p_Scheme->orderedArray[idx]= (uint8_t)i;
37471 + }
37472 + }
37473 + XX_Free(p_LocalExtractsArray);
37474 + }
37475 + else
37476 + {
37477 + /* clear all unused registers: */
37478 + p_SchemeRegs->kgse_ekfc = 0;
37479 + p_SchemeRegs->kgse_ekdv = 0;
37480 + p_SchemeRegs->kgse_bmch = 0;
37481 + p_SchemeRegs->kgse_bmcl = 0;
37482 + p_SchemeRegs->kgse_hc = 0;
37483 + p_SchemeRegs->kgse_dv0 = 0;
37484 + p_SchemeRegs->kgse_dv1 = 0;
37485 + }
37486 +
37487 + if (p_SchemeParams->bypassFqidGeneration)
37488 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
37489 +
37490 + /* configure kgse_spc */
37491 + if ( p_SchemeParams->schemeCounter.update)
37492 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
37493 +
37494 +
37495 + /* check that are enough generic registers */
37496 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
37497 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
37498 +
37499 + /* extracted OR mask on Qid */
37500 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
37501 + {
37502 +
37503 + p_Scheme->extractedOrs = TRUE;
37504 + /* configure kgse_gec[i] */
37505 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
37506 + switch (p_ExtractOr->type)
37507 + {
37508 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
37509 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
37510 + offset = 0;
37511 + break;
37512 + case (e_FM_PCD_EXTRACT_BY_HDR):
37513 + /* get the header code for the generic extract */
37514 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
37515 + /* set generic register fields */
37516 + offset = p_ExtractOr->extractionOffset;
37517 + break;
37518 + case (e_FM_PCD_EXTRACT_NON_HDR):
37519 + /* get the field code for the generic extract */
37520 + offset = 0;
37521 + code = GetGenCode(p_ExtractOr->src, &offset);
37522 + offset += p_ExtractOr->extractionOffset;
37523 + break;
37524 + default:
37525 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37526 + }
37527 +
37528 + /* set generic register fields */
37529 + if (!code)
37530 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
37531 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
37532 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
37533 + genTmp |= offset;
37534 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
37535 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
37536 +
37537 + /************************************************************************************
37538 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
37539 + in the following way:
37540 +
37541 + Driver API and implementation:
37542 + ==============================
37543 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
37544 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
37545 + are not overlapping FQID.
37546 + ------------------------
37547 + | FQID (24) |
37548 + ------------------------
37549 + --------
37550 + | | extracted OR byte
37551 + --------
37552 +
37553 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
37554 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
37555 + are not overlapping PP id.
37556 +
37557 + --------
37558 + | PP (8) |
37559 + --------
37560 + --------
37561 + | | extracted OR byte
37562 + --------
37563 +
37564 + HW implementation
37565 + =================
37566 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
37567 + as the highest byte of that word and may be rotated to effect any part os the FQID or
37568 + the PP.
37569 + ------------------------ --------
37570 + | FQID (24) || PP (8) |
37571 + ------------------------ --------
37572 + --------
37573 + | | extracted OR byte
37574 + --------
37575 +
37576 + ************************************************************************************/
37577 +
37578 + if (p_ExtractOr->bitOffsetInFqid)
37579 + {
37580 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
37581 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
37582 + if (p_ExtractOr->bitOffsetInFqid<8)
37583 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
37584 + else
37585 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
37586 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
37587 + }
37588 + else /* effect policer profile */
37589 + {
37590 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
37591 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
37592 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
37593 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
37594 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
37595 + }
37596 +
37597 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
37598 + /* clear bits that need masking */
37599 + genTmp &= ~KG_SCH_GEN_MASK ;
37600 + /* set mask bits */
37601 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
37602 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
37603 +
37604 + }
37605 + /* clear all unused GEC registers */
37606 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37607 + p_SchemeRegs->kgse_gec[i] = 0;
37608 +
37609 + /* add base Qid for this scheme */
37610 + /* add configuration for kgse_fqb */
37611 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
37612 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
37613 +
37614 + fqbTmp |= p_SchemeParams->baseFqid;
37615 + p_SchemeRegs->kgse_fqb = fqbTmp;
37616 +
37617 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
37618 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
37619 +
37620 + return E_OK;
37621 +}
37622 +
37623 +
37624 +/*****************************************************************************/
37625 +/* Inter-module API routines */
37626 +/*****************************************************************************/
37627 +
37628 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
37629 +{
37630 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37631 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
37632 + t_FmPcdIpcKgClsPlanParams kgAlloc;
37633 + t_Error err = E_OK;
37634 + uint32_t oredVectors = 0;
37635 + int i, j;
37636 +
37637 + /* this routine is protected by the calling routine ! */
37638 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
37639 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
37640 +
37641 + /* find a new clsPlan group */
37642 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
37643 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
37644 + break;
37645 + if (i == FM_MAX_NUM_OF_PORTS)
37646 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
37647 +
37648 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
37649 +
37650 + p_Grp->clsPlanGrpId = (uint8_t)i;
37651 +
37652 + if (p_Grp->numOfOptions == 0)
37653 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
37654 +
37655 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
37656 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
37657 + p_ClsPlanGrp->owners = 0;
37658 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
37659 + if (p_Grp->numOfOptions != 0)
37660 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
37661 +
37662 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
37663 + /* a minimal group of 8 is required */
37664 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
37665 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
37666 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
37667 + {
37668 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
37669 +
37670 + if (err)
37671 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
37672 + }
37673 + else
37674 + {
37675 + t_FmPcdIpcMsg msg;
37676 + uint32_t replyLength;
37677 + t_FmPcdIpcReply reply;
37678 +
37679 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
37680 + memset(&reply, 0, sizeof(reply));
37681 + memset(&msg, 0, sizeof(msg));
37682 + memset(&kgAlloc, 0, sizeof(kgAlloc));
37683 + kgAlloc.guestId = p_FmPcd->guestId;
37684 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
37685 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
37686 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
37687 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
37688 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
37689 + (uint8_t*)&msg,
37690 + sizeof(msg.msgId) + sizeof(kgAlloc),
37691 + (uint8_t*)&reply,
37692 + &replyLength,
37693 + NULL,
37694 + NULL)) != E_OK)
37695 + RETURN_ERROR(MAJOR, err, NO_MSG);
37696 +
37697 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
37698 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
37699 + if ((t_Error)reply.error != E_OK)
37700 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
37701 +
37702 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
37703 + }
37704 +
37705 + /* build classification plan entries parameters */
37706 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
37707 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
37708 +
37709 + oredVectors = 0;
37710 + for (i = 0; i<p_Grp->numOfOptions; i++)
37711 + {
37712 + oredVectors |= p_Grp->optVectors[i];
37713 + /* save an array of used options - the indexes represent the power of 2 index */
37714 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
37715 + }
37716 + /* set the classification plan relevant entries so that all bits
37717 + * relevant to the list of options is cleared
37718 + */
37719 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
37720 + p_ClsPlanSet->vectors[j] = ~oredVectors;
37721 +
37722 + for (i = 0; i<p_Grp->numOfOptions; i++)
37723 + {
37724 + /* option i got the place 2^i in the clsPlan array. all entries that
37725 + * have bit i set, should have the vector bit cleared. So each option
37726 + * has one location that it is exclusive (1,2,4,8...) and represent the
37727 + * presence of that option only, and other locations that represent a
37728 + * combination of options.
37729 + * e.g:
37730 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
37731 + * now represents a frame with ethernet-BC header - so the bit
37732 + * representing ethernet-BC should be set and all other option bits
37733 + * should be cleared.
37734 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
37735 + * vector[1] set, but they also have other bits set:
37736 + * 3=1+2, options 0 and 1
37737 + * 6=2+4, options 1 and 2
37738 + * 7=1+2+4, options 0,1,and 2
37739 + * 10=2+8, options 1 and 3
37740 + * etc.
37741 + * */
37742 +
37743 + /* now for each option (i), we set their bits in all entries (j)
37744 + * that contain bit 2^i.
37745 + */
37746 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
37747 + {
37748 + if (j & (1<<i))
37749 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
37750 + }
37751 + }
37752 +
37753 + return E_OK;
37754 +}
37755 +
37756 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
37757 +{
37758 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37759 + t_FmPcdIpcKgClsPlanParams kgAlloc;
37760 + t_Error err;
37761 + t_FmPcdIpcMsg msg;
37762 + uint32_t replyLength;
37763 + t_FmPcdIpcReply reply;
37764 +
37765 + /* check that no port is bound to this clsPlan */
37766 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
37767 + {
37768 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
37769 + return;
37770 + }
37771 +
37772 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
37773 +
37774 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
37775 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
37776 + else
37777 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
37778 +
37779 + /* free blocks */
37780 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
37781 + KgFreeClsPlanEntries(h_FmPcd,
37782 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
37783 + p_FmPcd->guestId,
37784 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
37785 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
37786 + {
37787 + memset(&reply, 0, sizeof(reply));
37788 + memset(&msg, 0, sizeof(msg));
37789 + kgAlloc.guestId = p_FmPcd->guestId;
37790 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
37791 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
37792 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
37793 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
37794 + replyLength = sizeof(uint32_t);
37795 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
37796 + (uint8_t*)&msg,
37797 + sizeof(msg.msgId) + sizeof(kgAlloc),
37798 + (uint8_t*)&reply,
37799 + &replyLength,
37800 + NULL,
37801 + NULL);
37802 + if (err != E_OK)
37803 + {
37804 + REPORT_ERROR(MINOR, err, NO_MSG);
37805 + return;
37806 + }
37807 + if (replyLength != sizeof(uint32_t))
37808 + {
37809 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
37810 + return;
37811 + }
37812 + if ((t_Error)reply.error != E_OK)
37813 + {
37814 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
37815 + return;
37816 + }
37817 + }
37818 +
37819 + /* clear clsPlan driver structure */
37820 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
37821 +}
37822 +
37823 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
37824 +{
37825 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37826 + uint32_t j, schemesPerPortVector = 0;
37827 + t_FmPcdKgScheme *p_Scheme;
37828 + uint8_t i, relativeSchemeId;
37829 + uint32_t tmp, walking1Mask;
37830 + uint8_t swPortIndex = 0;
37831 +
37832 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37833 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
37834 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
37835 +
37836 + /* for each scheme */
37837 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
37838 + {
37839 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
37840 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
37841 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37842 +
37843 + if (add)
37844 + {
37845 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37846 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37847 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37848 + /* check netEnvId of the port against the scheme netEnvId */
37849 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
37850 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
37851 +
37852 + /* if next engine is private port policer profile, we need to check that it is valid */
37853 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
37854 + if (p_Scheme->nextRelativePlcrProfile)
37855 + {
37856 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
37857 + {
37858 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
37859 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
37860 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
37861 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
37862 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
37863 + }
37864 + }
37865 + if (!p_BindPort->useClsPlan)
37866 + {
37867 + /* This check may be redundant as port is a assigned to the whole NetEnv */
37868 +
37869 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
37870 + cls plan options. Schemes that are used only directly, should not be checked.
37871 + it also may not be bound to schemes that go to CC with units that are options - so we OR
37872 + the match vector and the grpBits (= ccUnits) */
37873 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
37874 + {
37875 + uint8_t netEnvId;
37876 + walking1Mask = 0x80000000;
37877 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
37878 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
37879 + tmp |= p_Scheme->ccUnits;
37880 + while (tmp)
37881 + {
37882 + if (tmp & walking1Mask)
37883 + {
37884 + tmp &= ~walking1Mask;
37885 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
37886 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
37887 + }
37888 + walking1Mask >>= 1;
37889 + }
37890 + }
37891 + }
37892 + }
37893 + /* build vector */
37894 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
37895 + }
37896 +
37897 + *p_SpReg = schemesPerPortVector;
37898 +
37899 + return E_OK;
37900 +}
37901 +
37902 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
37903 +{
37904 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37905 + uint32_t spReg;
37906 + t_Error err = E_OK;
37907 +
37908 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
37909 + if (err)
37910 + RETURN_ERROR(MAJOR, err, NO_MSG);
37911 +
37912 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
37913 + if (err)
37914 + RETURN_ERROR(MAJOR, err, NO_MSG);
37915 +
37916 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
37917 +
37918 + return E_OK;
37919 +}
37920 +
37921 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
37922 +{
37923 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37924 + uint32_t spReg;
37925 + t_Error err = E_OK;
37926 +
37927 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
37928 + if (err)
37929 + RETURN_ERROR(MAJOR, err, NO_MSG);
37930 +
37931 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
37932 + if (err)
37933 + RETURN_ERROR(MAJOR, err, NO_MSG);
37934 +
37935 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
37936 +
37937 + return E_OK;
37938 +}
37939 +
37940 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
37941 +{
37942 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
37943 +
37944 + return p_Scheme->valid;
37945 +}
37946 +
37947 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
37948 +{
37949 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37950 +
37951 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
37952 + return TRUE;
37953 + else
37954 + return FALSE;
37955 +}
37956 +
37957 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
37958 +{
37959 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
37960 + uint8_t i, j;
37961 +
37962 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37963 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
37964 +
37965 + /* This routine is issued only on master core of master partition -
37966 + either directly or through IPC, so no need for lock */
37967 +
37968 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
37969 + {
37970 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
37971 + {
37972 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
37973 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
37974 + p_SchemesIds[j] = i;
37975 + j++;
37976 + }
37977 + }
37978 +
37979 + if (j != numOfSchemes)
37980 + {
37981 + /* roll back */
37982 + for (j--; j; j--)
37983 + {
37984 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
37985 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
37986 + p_SchemesIds[j] = 0;
37987 + }
37988 +
37989 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
37990 + }
37991 +
37992 + return E_OK;
37993 +}
37994 +
37995 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
37996 +{
37997 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
37998 + uint8_t i;
37999 +
38000 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
38001 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
38002 +
38003 + /* This routine is issued only on master core of master partition -
38004 + either directly or through IPC */
38005 +
38006 + for (i = 0; i < numOfSchemes; i++)
38007 + {
38008 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
38009 + {
38010 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
38011 + }
38012 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
38013 + {
38014 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
38015 + }
38016 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
38017 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
38018 + }
38019 +
38020 + return E_OK;
38021 +}
38022 +
38023 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
38024 +{
38025 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38026 + uint8_t numOfBlocks, blocksFound=0, first=0;
38027 + uint8_t i, j;
38028 +
38029 + /* This routine is issued only on master core of master partition -
38030 + either directly or through IPC, so no need for lock */
38031 +
38032 + if (!numOfClsPlanEntries)
38033 + return E_OK;
38034 +
38035 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
38036 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
38037 +
38038 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
38039 +
38040 + /* try to find consequent blocks */
38041 + first = 0;
38042 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
38043 + {
38044 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
38045 + {
38046 + blocksFound++;
38047 + i++;
38048 + if (blocksFound == numOfBlocks)
38049 + break;
38050 + }
38051 + else
38052 + {
38053 + blocksFound = 0;
38054 + /* advance i to the next aligned address */
38055 + first = i = (uint8_t)(first + numOfBlocks);
38056 + }
38057 + }
38058 +
38059 + if (blocksFound == numOfBlocks)
38060 + {
38061 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
38062 + for (j = first; j < (first + numOfBlocks); j++)
38063 + {
38064 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
38065 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
38066 + }
38067 + return E_OK;
38068 + }
38069 + else
38070 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
38071 +}
38072 +
38073 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
38074 +{
38075 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38076 + uint8_t numOfBlocks;
38077 + uint8_t i, baseBlock;
38078 +
38079 +#ifdef DISABLE_ASSERTIONS
38080 +UNUSED(guestId);
38081 +#endif /* DISABLE_ASSERTIONS */
38082 +
38083 + /* This routine is issued only on master core of master partition -
38084 + either directly or through IPC, so no need for lock */
38085 +
38086 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
38087 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
38088 +
38089 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
38090 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
38091 + {
38092 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
38093 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
38094 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
38095 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
38096 + }
38097 +}
38098 +
38099 +void KgEnable(t_FmPcd *p_FmPcd)
38100 +{
38101 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
38102 +
38103 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
38104 + fman_kg_enable(p_Regs);
38105 +}
38106 +
38107 +void KgDisable(t_FmPcd *p_FmPcd)
38108 +{
38109 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
38110 +
38111 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
38112 + fman_kg_disable(p_Regs);
38113 +}
38114 +
38115 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
38116 +{
38117 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38118 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
38119 + uint32_t tmpKgarReg = 0, intFlags;
38120 + uint16_t i, j;
38121 +
38122 + /* This routine is protected by the calling routine ! */
38123 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
38124 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
38125 +
38126 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38127 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
38128 + {
38129 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
38130 +
38131 + for (j = i; j < i+8; j++)
38132 + {
38133 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
38134 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
38135 + }
38136 +
38137 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
38138 + {
38139 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
38140 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38141 + return;
38142 + }
38143 + }
38144 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38145 +}
38146 +
38147 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
38148 +{
38149 + t_FmPcdKg *p_FmPcdKg;
38150 +
38151 + UNUSED(p_FmPcd);
38152 +
38153 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
38154 + {
38155 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
38156 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
38157 + return NULL;
38158 + }
38159 +
38160 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
38161 + if (!p_FmPcdKg)
38162 + {
38163 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
38164 + return NULL;
38165 + }
38166 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
38167 +
38168 +
38169 + if (FmIsMaster(p_FmPcd->h_Fm))
38170 + {
38171 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
38172 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
38173 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
38174 + }
38175 +
38176 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
38177 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
38178 + {
38179 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
38180 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
38181 + }
38182 +
38183 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
38184 +
38185 + return p_FmPcdKg;
38186 +}
38187 +
38188 +t_Error KgInit(t_FmPcd *p_FmPcd)
38189 +{
38190 + t_Error err = E_OK;
38191 +
38192 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
38193 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38194 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
38195 +
38196 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
38197 + err = KgInitMaster(p_FmPcd);
38198 + else
38199 + err = KgInitGuest(p_FmPcd);
38200 +
38201 + if (err != E_OK)
38202 + {
38203 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38204 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
38205 + }
38206 +
38207 + return err;
38208 +}
38209 +
38210 +t_Error KgFree(t_FmPcd *p_FmPcd)
38211 +{
38212 + t_FmPcdIpcKgSchemesParams kgAlloc;
38213 + t_Error err = E_OK;
38214 + t_FmPcdIpcMsg msg;
38215 + uint32_t replyLength;
38216 + t_FmPcdIpcReply reply;
38217 +
38218 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
38219 +
38220 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
38221 + {
38222 + err = FmPcdKgFreeSchemes(p_FmPcd,
38223 + p_FmPcd->p_FmPcdKg->numOfSchemes,
38224 + p_FmPcd->guestId,
38225 + p_FmPcd->p_FmPcdKg->schemesIds);
38226 + if (err)
38227 + RETURN_ERROR(MAJOR, err, NO_MSG);
38228 +
38229 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38230 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
38231 +
38232 + return E_OK;
38233 + }
38234 +
38235 + /* guest */
38236 + memset(&reply, 0, sizeof(reply));
38237 + memset(&msg, 0, sizeof(msg));
38238 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
38239 + kgAlloc.guestId = p_FmPcd->guestId;
38240 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
38241 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
38242 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
38243 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
38244 + replyLength = sizeof(uint32_t);
38245 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
38246 + (uint8_t*)&msg,
38247 + sizeof(msg.msgId) + sizeof(kgAlloc),
38248 + (uint8_t*)&reply,
38249 + &replyLength,
38250 + NULL,
38251 + NULL)) != E_OK)
38252 + RETURN_ERROR(MAJOR, err, NO_MSG);
38253 + if (replyLength != sizeof(uint32_t))
38254 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
38255 +
38256 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38257 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
38258 +
38259 + return (t_Error)reply.error;
38260 +}
38261 +
38262 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
38263 +{
38264 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38265 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
38266 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
38267 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
38268 + t_Error err;
38269 +
38270 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
38271 + so no need for lock here */
38272 +
38273 + memset(&grpParams, 0, sizeof(grpParams));
38274 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
38275 + p_GrpParams = &grpParams;
38276 +
38277 + p_GrpParams->netEnvId = netEnvId;
38278 +
38279 + /* Get from the NetEnv the information of the clsPlan (can be already created,
38280 + * or needs to build) */
38281 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
38282 + if (err)
38283 + RETURN_ERROR(MINOR,err,NO_MSG);
38284 +
38285 + if (p_GrpParams->grpExists)
38286 + {
38287 + /* this group was already updated (at least) in SW */
38288 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
38289 + }
38290 + else
38291 + {
38292 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
38293 + if (!p_ClsPlanSet)
38294 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
38295 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
38296 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
38297 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
38298 + if (err)
38299 + {
38300 + XX_Free(p_ClsPlanSet);
38301 + RETURN_ERROR(MINOR, err, NO_MSG);
38302 + }
38303 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
38304 +
38305 + if (p_FmPcd->h_Hc)
38306 + {
38307 + /* write clsPlan entries to memory */
38308 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
38309 + if (err)
38310 + {
38311 + XX_Free(p_ClsPlanSet);
38312 + RETURN_ERROR(MAJOR, err, NO_MSG);
38313 + }
38314 + }
38315 + else
38316 + /* write clsPlan entries to memory */
38317 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
38318 +
38319 + XX_Free(p_ClsPlanSet);
38320 + }
38321 +
38322 + /* Set caller parameters */
38323 +
38324 + /* mark if this is an empty classification group */
38325 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
38326 + *p_IsEmptyClsPlanGrp = TRUE;
38327 + else
38328 + *p_IsEmptyClsPlanGrp = FALSE;
38329 +
38330 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
38331 +
38332 + /* increment owners number */
38333 + p_ClsPlanGrp->owners++;
38334 +
38335 + /* copy options array for port */
38336 + 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));
38337 +
38338 + /* bind port to the new or existing group */
38339 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
38340 + if (err)
38341 + RETURN_ERROR(MINOR, err, NO_MSG);
38342 +
38343 + return E_OK;
38344 +}
38345 +
38346 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
38347 +{
38348 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38349 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
38350 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
38351 + t_Error err;
38352 +
38353 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
38354 + so no need for lock here */
38355 +
38356 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
38357 +
38358 + /* decrement owners number */
38359 + ASSERT_COND(p_ClsPlanGrp->owners);
38360 + p_ClsPlanGrp->owners--;
38361 +
38362 + if (!p_ClsPlanGrp->owners)
38363 + {
38364 + if (p_FmPcd->h_Hc)
38365 + {
38366 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
38367 + return err;
38368 + }
38369 + else
38370 + {
38371 + /* clear clsPlan entries in memory */
38372 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
38373 + if (!p_ClsPlanSet)
38374 + {
38375 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
38376 + }
38377 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
38378 +
38379 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
38380 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
38381 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
38382 + XX_Free(p_ClsPlanSet);
38383 +
38384 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
38385 + }
38386 + }
38387 + return E_OK;
38388 +}
38389 +
38390 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
38391 +{
38392 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38393 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38394 +
38395 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
38396 +}
38397 +
38398 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
38399 +{
38400 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38401 +
38402 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38403 +
38404 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
38405 +}
38406 +
38407 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
38408 +{
38409 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38410 +
38411 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38412 +
38413 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
38414 +}
38415 +
38416 +
38417 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
38418 +{
38419 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38420 +
38421 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38422 +
38423 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
38424 +}
38425 +
38426 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
38427 +{
38428 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38429 +
38430 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38431 +
38432 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
38433 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
38434 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
38435 + return TRUE;
38436 + else
38437 + return FALSE;
38438 +
38439 +}
38440 +
38441 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
38442 +{
38443 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38444 +
38445 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
38446 +
38447 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
38448 +}
38449 +
38450 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
38451 +{
38452 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38453 +
38454 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38455 +
38456 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
38457 +}
38458 +
38459 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
38460 +{
38461 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
38462 +
38463 + /* this routine is protected by calling routine */
38464 +
38465 + ASSERT_COND(p_Scheme->valid);
38466 +
38467 + p_Scheme->requiredAction |= requiredAction;
38468 +}
38469 +
38470 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
38471 +{
38472 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
38473 +}
38474 +
38475 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
38476 +{
38477 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
38478 + FM_KG_KGAR_GO |
38479 + FM_KG_KGAR_WRITE |
38480 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
38481 + DUMMY_PORT_ID |
38482 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
38483 +}
38484 +
38485 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
38486 +{
38487 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
38488 + FM_KG_KGAR_GO |
38489 + FM_KG_KGAR_READ |
38490 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
38491 + DUMMY_PORT_ID |
38492 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
38493 +
38494 +}
38495 +
38496 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
38497 +{
38498 + return (uint32_t)(FM_KG_KGAR_GO |
38499 + FM_KG_KGAR_WRITE |
38500 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
38501 + DUMMY_PORT_ID |
38502 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
38503 + FM_PCD_KG_KGAR_WSEL_MASK);
38504 +
38505 + /* if we ever want to write 1 by 1, use:
38506 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
38507 + */
38508 +}
38509 +
38510 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
38511 +{
38512 +
38513 + return (uint32_t)(FM_KG_KGAR_GO |
38514 + FM_KG_KGAR_WRITE |
38515 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
38516 + hardwarePortId |
38517 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
38518 +}
38519 +
38520 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
38521 +{
38522 +
38523 + return (uint32_t)(FM_KG_KGAR_GO |
38524 + FM_KG_KGAR_READ |
38525 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
38526 + hardwarePortId |
38527 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
38528 +}
38529 +
38530 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
38531 +{
38532 +
38533 + return (uint32_t)(FM_KG_KGAR_GO |
38534 + FM_KG_KGAR_WRITE |
38535 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
38536 + hardwarePortId |
38537 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
38538 +}
38539 +
38540 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
38541 +{
38542 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38543 +
38544 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
38545 +}
38546 +
38547 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
38548 +{
38549 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38550 +
38551 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
38552 +}
38553 +
38554 +
38555 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
38556 +{
38557 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
38558 +
38559 +}
38560 +
38561 +#if (DPAA_VERSION >= 11)
38562 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
38563 +{
38564 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
38565 +
38566 +}
38567 +#endif /* (DPAA_VERSION >= 11) */
38568 +
38569 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
38570 +{
38571 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38572 + uint8_t i;
38573 +
38574 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
38575 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
38576 + return i;
38577 +
38578 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
38579 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
38580 +
38581 + return FM_PCD_KG_NUM_OF_SCHEMES;
38582 +}
38583 +
38584 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
38585 +{
38586 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38587 +
38588 + ASSERT_COND(p_FmPcd);
38589 +
38590 + /* check that schemeId is in range */
38591 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
38592 + {
38593 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
38594 + return NULL;
38595 + }
38596 +
38597 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
38598 + return NULL;
38599 +
38600 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
38601 +}
38602 +
38603 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
38604 +{
38605 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
38606 +}
38607 +
38608 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
38609 +{
38610 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38611 + uint8_t relativeSchemeId, physicalSchemeId;
38612 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
38613 + t_Error err;
38614 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
38615 +
38616 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
38617 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
38618 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
38619 +
38620 + /* Calling function locked all PCD modules, so no need to lock here */
38621 +
38622 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
38623 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
38624 +
38625 + if (p_FmPcd->h_Hc)
38626 + {
38627 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
38628 +
38629 + UpdateRequiredActionFlag(h_Scheme,TRUE);
38630 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
38631 + return err;
38632 + }
38633 +
38634 + physicalSchemeId = p_Scheme->schemeId;
38635 +
38636 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
38637 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
38638 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
38639 +
38640 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
38641 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
38642 + {
38643 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
38644 + {
38645 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
38646 + {
38647 + case (e_FM_PCD_DONE):
38648 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
38649 + {
38650 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
38651 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38652 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38653 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
38654 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
38655 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
38656 + /* call indirect command for scheme write */
38657 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
38658 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38659 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38660 + }
38661 + break;
38662 + case (e_FM_PCD_PLCR):
38663 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
38664 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
38665 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
38666 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
38667 + {
38668 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
38669 + }
38670 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
38671 + if (err)
38672 + {
38673 + RETURN_ERROR(MAJOR, err, NO_MSG);
38674 + }
38675 + break;
38676 + default:
38677 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
38678 + }
38679 + }
38680 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
38681 + {
38682 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
38683 + {
38684 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
38685 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38686 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38687 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
38688 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
38689 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
38690 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
38691 + /* call indirect command for scheme write */
38692 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
38693 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38694 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38695 + }
38696 + }
38697 + if (requiredAction & UPDATE_KG_OPT_MODE)
38698 + {
38699 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
38700 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38701 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38702 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
38703 + /* call indirect command for scheme write */
38704 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
38705 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38706 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38707 + }
38708 + if (requiredAction & UPDATE_KG_NIA)
38709 + {
38710 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
38711 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38712 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38713 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
38714 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
38715 + tmpReg32 |= value;
38716 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
38717 + /* call indirect command for scheme write */
38718 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
38719 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38720 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38721 + }
38722 + }
38723 +
38724 + UpdateRequiredActionFlag(h_Scheme, TRUE);
38725 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
38726 +
38727 + return E_OK;
38728 +}
38729 +/*********************** End of inter-module routines ************************/
38730 +
38731 +
38732 +/****************************************/
38733 +/* API routines */
38734 +/****************************************/
38735 +
38736 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
38737 +{
38738 + t_FmPcd *p_FmPcd;
38739 + struct fman_kg_scheme_regs schemeRegs;
38740 + struct fman_kg_scheme_regs *p_MemRegs;
38741 + uint8_t i;
38742 + t_Error err = E_OK;
38743 + uint32_t tmpKgarReg;
38744 + uint32_t intFlags;
38745 + uint8_t physicalSchemeId, relativeSchemeId = 0;
38746 + t_FmPcdKgScheme *p_Scheme;
38747 +
38748 + if (p_SchemeParams->modify)
38749 + {
38750 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
38751 + p_FmPcd = p_Scheme->h_FmPcd;
38752 +
38753 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
38754 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
38755 +
38756 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
38757 + {
38758 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
38759 + ("Scheme is invalid"));
38760 + return NULL;
38761 + }
38762 +
38763 + if (!KgSchemeFlagTryLock(p_Scheme))
38764 + {
38765 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
38766 + /* Signal to caller BUSY condition */
38767 + p_SchemeParams->id.h_Scheme = NULL;
38768 + return NULL;
38769 + }
38770 + }
38771 + else
38772 + {
38773 + p_FmPcd = (t_FmPcd*)h_FmPcd;
38774 +
38775 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
38776 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
38777 +
38778 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
38779 + /* check that schemeId is in range */
38780 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
38781 + {
38782 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
38783 + return NULL;
38784 + }
38785 +
38786 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
38787 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
38788 + {
38789 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
38790 + ("Scheme id (%d)!", relativeSchemeId));
38791 + return NULL;
38792 + }
38793 + /* Clear all fields, scheme may have beed previously used */
38794 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
38795 +
38796 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
38797 + p_Scheme->h_FmPcd = p_FmPcd;
38798 +
38799 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
38800 + if (!p_Scheme->p_Lock)
38801 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
38802 + }
38803 +
38804 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
38805 + if (err)
38806 + {
38807 + REPORT_ERROR(MAJOR, err, NO_MSG);
38808 + if (p_SchemeParams->modify)
38809 + KgSchemeFlagUnlock(p_Scheme);
38810 + if (!p_SchemeParams->modify &&
38811 + p_Scheme->p_Lock)
38812 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
38813 + return NULL;
38814 + }
38815 +
38816 + if (p_FmPcd->h_Hc)
38817 + {
38818 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
38819 + (t_Handle)p_Scheme,
38820 + &schemeRegs,
38821 + p_SchemeParams->schemeCounter.update);
38822 + if (p_SchemeParams->modify)
38823 + KgSchemeFlagUnlock(p_Scheme);
38824 + if (err)
38825 + {
38826 + if (!p_SchemeParams->modify &&
38827 + p_Scheme->p_Lock)
38828 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
38829 + return NULL;
38830 + }
38831 + if (!p_SchemeParams->modify)
38832 + ValidateSchemeSw(p_Scheme);
38833 + return (t_Handle)p_Scheme;
38834 + }
38835 +
38836 + physicalSchemeId = p_Scheme->schemeId;
38837 +
38838 + /* configure all 21 scheme registers */
38839 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
38840 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38841 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
38842 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
38843 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
38844 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
38845 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
38846 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
38847 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
38848 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
38849 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
38850 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
38851 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
38852 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
38853 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
38854 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
38855 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
38856 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
38857 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
38858 +
38859 + /* call indirect command for scheme write */
38860 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
38861 +
38862 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38863 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38864 +
38865 + if (!p_SchemeParams->modify)
38866 + ValidateSchemeSw(p_Scheme);
38867 + else
38868 + KgSchemeFlagUnlock(p_Scheme);
38869 +
38870 + return (t_Handle)p_Scheme;
38871 +}
38872 +
38873 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
38874 +{
38875 + t_FmPcd *p_FmPcd;
38876 + uint8_t physicalSchemeId;
38877 + uint32_t tmpKgarReg, intFlags;
38878 + t_Error err = E_OK;
38879 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
38880 +
38881 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
38882 +
38883 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
38884 +
38885 + UpdateRequiredActionFlag(h_Scheme, FALSE);
38886 +
38887 + /* check that no port is bound to this scheme */
38888 + err = InvalidateSchemeSw(h_Scheme);
38889 + if (err)
38890 + RETURN_ERROR(MINOR, err, NO_MSG);
38891 +
38892 + if (p_FmPcd->h_Hc)
38893 + {
38894 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
38895 + if (p_Scheme->p_Lock)
38896 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
38897 + return err;
38898 + }
38899 +
38900 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
38901 +
38902 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38903 + /* clear mode register, including enable bit */
38904 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
38905 +
38906 + /* call indirect command for scheme write */
38907 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
38908 +
38909 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38910 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38911 +
38912 + if (p_Scheme->p_Lock)
38913 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
38914 +
38915 + return E_OK;
38916 +}
38917 +
38918 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
38919 +{
38920 + t_FmPcd *p_FmPcd;
38921 + uint32_t tmpKgarReg, spc, intFlags;
38922 + uint8_t physicalSchemeId;
38923 +
38924 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
38925 +
38926 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
38927 + if (p_FmPcd->h_Hc)
38928 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
38929 +
38930 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
38931 +
38932 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
38933 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
38934 +
38935 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
38936 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38937 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38938 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
38939 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
38940 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
38941 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38942 +
38943 + return spc;
38944 +}
38945 +
38946 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
38947 +{
38948 + t_FmPcd *p_FmPcd;
38949 + uint32_t tmpKgarReg, intFlags;
38950 + uint8_t physicalSchemeId;
38951 +
38952 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
38953 +
38954 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
38955 +
38956 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
38957 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
38958 +
38959 + if (p_FmPcd->h_Hc)
38960 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
38961 +
38962 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
38963 + /* check that schemeId is in range */
38964 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
38965 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
38966 +
38967 + /* read specified scheme into scheme registers */
38968 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
38969 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38970 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38971 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
38972 + {
38973 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38974 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
38975 + }
38976 +
38977 + /* change counter value */
38978 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
38979 +
38980 + /* call indirect command for scheme write */
38981 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
38982 +
38983 + WriteKgarWait(p_FmPcd, tmpKgarReg);
38984 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38985 +
38986 + return E_OK;
38987 +}
38988 +
38989 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
38990 +{
38991 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38992 + struct fman_kg_regs *p_Regs;
38993 +
38994 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
38995 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
38996 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
38997 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
38998 +
38999 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
39000 + if (!FmIsMaster(p_FmPcd->h_Fm))
39001 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
39002 +
39003 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
39004 +
39005 + return E_OK;
39006 +}
39007 +
39008 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
39009 +{
39010 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39011 + struct fman_kg_regs *p_Regs;
39012 +
39013 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
39014 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
39015 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
39016 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
39017 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
39018 +
39019 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
39020 +
39021 + if (!FmIsMaster(p_FmPcd->h_Fm))
39022 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
39023 +
39024 + if (valueId == 0)
39025 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
39026 + else
39027 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
39028 + return E_OK;
39029 +}
39030 --- /dev/null
39031 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
39032 @@ -0,0 +1,206 @@
39033 +/*
39034 + * Copyright 2008-2012 Freescale Semiconductor Inc.
39035 + *
39036 + * Redistribution and use in source and binary forms, with or without
39037 + * modification, are permitted provided that the following conditions are met:
39038 + * * Redistributions of source code must retain the above copyright
39039 + * notice, this list of conditions and the following disclaimer.
39040 + * * Redistributions in binary form must reproduce the above copyright
39041 + * notice, this list of conditions and the following disclaimer in the
39042 + * documentation and/or other materials provided with the distribution.
39043 + * * Neither the name of Freescale Semiconductor nor the
39044 + * names of its contributors may be used to endorse or promote products
39045 + * derived from this software without specific prior written permission.
39046 + *
39047 + *
39048 + * ALTERNATIVELY, this software may be distributed under the terms of the
39049 + * GNU General Public License ("GPL") as published by the Free Software
39050 + * Foundation, either version 2 of that License or (at your option) any
39051 + * later version.
39052 + *
39053 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
39054 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39055 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39056 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
39057 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39058 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39059 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39060 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39061 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39062 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39063 + */
39064 +
39065 +
39066 +/******************************************************************************
39067 + @File fm_kg.h
39068 +
39069 + @Description FM KG private header
39070 +*//***************************************************************************/
39071 +#ifndef __FM_KG_H
39072 +#define __FM_KG_H
39073 +
39074 +#include "std_ext.h"
39075 +
39076 +/***********************************************************************/
39077 +/* Keygen defines */
39078 +/***********************************************************************/
39079 +/* maskes */
39080 +#if (DPAA_VERSION >= 11)
39081 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
39082 +#define KG_SCH_OM_VSPE 0x00000001
39083 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
39084 +
39085 +#define MAX_SP_SHIFT 23
39086 +#define KG_SCH_VSP_MASK_SHIFT 12
39087 +#define KG_SCH_VSP_SHIFT 24
39088 +#endif /* (DPAA_VERSION >= 11) */
39089 +
39090 +typedef uint32_t t_KnownFieldsMasks;
39091 +#define KG_SCH_KN_PORT_ID 0x80000000
39092 +#define KG_SCH_KN_MACDST 0x40000000
39093 +#define KG_SCH_KN_MACSRC 0x20000000
39094 +#define KG_SCH_KN_TCI1 0x10000000
39095 +#define KG_SCH_KN_TCI2 0x08000000
39096 +#define KG_SCH_KN_ETYPE 0x04000000
39097 +#define KG_SCH_KN_PPPSID 0x02000000
39098 +#define KG_SCH_KN_PPPID 0x01000000
39099 +#define KG_SCH_KN_MPLS1 0x00800000
39100 +#define KG_SCH_KN_MPLS2 0x00400000
39101 +#define KG_SCH_KN_MPLS_LAST 0x00200000
39102 +#define KG_SCH_KN_IPSRC1 0x00100000
39103 +#define KG_SCH_KN_IPDST1 0x00080000
39104 +#define KG_SCH_KN_PTYPE1 0x00040000
39105 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
39106 +#define KG_SCH_KN_IPV6FL1 0x00010000
39107 +#define KG_SCH_KN_IPSRC2 0x00008000
39108 +#define KG_SCH_KN_IPDST2 0x00004000
39109 +#define KG_SCH_KN_PTYPE2 0x00002000
39110 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
39111 +#define KG_SCH_KN_IPV6FL2 0x00000800
39112 +#define KG_SCH_KN_GREPTYPE 0x00000400
39113 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
39114 +#define KG_SCH_KN_IPSEC_NH 0x00000100
39115 +#define KG_SCH_KN_IPPID 0x00000080
39116 +#define KG_SCH_KN_L4PSRC 0x00000004
39117 +#define KG_SCH_KN_L4PDST 0x00000002
39118 +#define KG_SCH_KN_TFLG 0x00000001
39119 +
39120 +typedef uint8_t t_GenericCodes;
39121 +#define KG_SCH_GEN_SHIM1 0x70
39122 +#define KG_SCH_GEN_DEFAULT 0x10
39123 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
39124 +#define KG_SCH_GEN_START_OF_FRM 0x40
39125 +#define KG_SCH_GEN_SHIM2 0x71
39126 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
39127 +#define KG_SCH_GEN_ETH 0x03
39128 +#define KG_SCH_GEN_ETH_NO_V 0x73
39129 +#define KG_SCH_GEN_SNAP 0x04
39130 +#define KG_SCH_GEN_SNAP_NO_V 0x74
39131 +#define KG_SCH_GEN_VLAN1 0x05
39132 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
39133 +#define KG_SCH_GEN_VLAN2 0x06
39134 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
39135 +#define KG_SCH_GEN_ETH_TYPE 0x07
39136 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
39137 +#define KG_SCH_GEN_PPP 0x08
39138 +#define KG_SCH_GEN_PPP_NO_V 0x78
39139 +#define KG_SCH_GEN_MPLS1 0x09
39140 +#define KG_SCH_GEN_MPLS2 0x19
39141 +#define KG_SCH_GEN_MPLS3 0x29
39142 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
39143 +#define KG_SCH_GEN_MPLS_LAST 0x0a
39144 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
39145 +#define KG_SCH_GEN_IPV4 0x0b
39146 +#define KG_SCH_GEN_IPV6 0x1b
39147 +#define KG_SCH_GEN_L3_NO_V 0x7b
39148 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
39149 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
39150 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
39151 +#define KG_SCH_GEN_IP2_NO_V 0x7c
39152 +#define KG_SCH_GEN_GRE 0x0d
39153 +#define KG_SCH_GEN_GRE_NO_V 0x7d
39154 +#define KG_SCH_GEN_TCP 0x0e
39155 +#define KG_SCH_GEN_UDP 0x1e
39156 +#define KG_SCH_GEN_IPSEC_AH 0x2e
39157 +#define KG_SCH_GEN_SCTP 0x3e
39158 +#define KG_SCH_GEN_DCCP 0x4e
39159 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
39160 +#define KG_SCH_GEN_L4_NO_V 0x7e
39161 +#define KG_SCH_GEN_NEXTHDR 0x7f
39162 +/* shifts */
39163 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
39164 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
39165 +#define KG_SCH_PP_MASK_SHIFT 16
39166 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
39167 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
39168 +#define KG_SCH_DEF_TCI_SHIFT 28
39169 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
39170 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
39171 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
39172 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
39173 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
39174 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
39175 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
39176 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
39177 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
39178 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
39179 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
39180 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
39181 +#define KG_SCH_GEN_MASK_SHIFT 16
39182 +#define KG_SCH_GEN_HT_SHIFT 8
39183 +#define KG_SCH_GEN_SIZE_SHIFT 24
39184 +#define KG_SCH_GEN_DEF_SHIFT 29
39185 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
39186 +
39187 +/* others */
39188 +#define NUM_OF_SW_DEFAULTS 3
39189 +#define MAX_PP_SHIFT 23
39190 +#define MAX_KG_SCH_SIZE 16
39191 +#define MASK_FOR_GENERIC_BASE_ID 0x20
39192 +#define MAX_HASH_SHIFT 40
39193 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
39194 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
39195 +#define MAX_DIST_FQID_SHIFT 23
39196 +
39197 +#define GET_MASK_SEL_SHIFT(shift,i) \
39198 +switch (i) { \
39199 + case (0):shift = 26;break; \
39200 + case (1):shift = 20;break; \
39201 + case (2):shift = 10;break; \
39202 + case (3):shift = 4;break; \
39203 + default: \
39204 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
39205 +}
39206 +
39207 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
39208 +switch (i) { \
39209 + case (0):shift = 16;break; \
39210 + case (1):shift = 0;break; \
39211 + case (2):shift = 28;break; \
39212 + case (3):shift = 24;break; \
39213 + default: \
39214 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
39215 +}
39216 +
39217 +#define GET_MASK_SHIFT(shift,i) \
39218 +switch (i) { \
39219 + case (0):shift = 24;break; \
39220 + case (1):shift = 16;break; \
39221 + case (2):shift = 8;break; \
39222 + case (3):shift = 0;break; \
39223 + default: \
39224 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
39225 +}
39226 +
39227 +/***********************************************************************/
39228 +/* Keygen defines */
39229 +/***********************************************************************/
39230 +
39231 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
39232 +#define NO_VALIDATION 0x70
39233 +#define KG_ACTION_REG_TO 1024
39234 +#define KG_MAX_PROFILE 255
39235 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
39236 +
39237 +
39238 +#endif /* __FM_KG_H */
39239 --- /dev/null
39240 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
39241 @@ -0,0 +1,5571 @@
39242 +/*
39243 + * Copyright 2008-2012 Freescale Semiconductor Inc.
39244 + *
39245 + * Redistribution and use in source and binary forms, with or without
39246 + * modification, are permitted provided that the following conditions are met:
39247 + * * Redistributions of source code must retain the above copyright
39248 + * notice, this list of conditions and the following disclaimer.
39249 + * * Redistributions in binary form must reproduce the above copyright
39250 + * notice, this list of conditions and the following disclaimer in the
39251 + * documentation and/or other materials provided with the distribution.
39252 + * * Neither the name of Freescale Semiconductor nor the
39253 + * names of its contributors may be used to endorse or promote products
39254 + * derived from this software without specific prior written permission.
39255 + *
39256 + *
39257 + * ALTERNATIVELY, this software may be distributed under the terms of the
39258 + * GNU General Public License ("GPL") as published by the Free Software
39259 + * Foundation, either version 2 of that License or (at your option) any
39260 + * later version.
39261 + *
39262 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
39263 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39264 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39265 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
39266 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39267 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39268 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39269 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39270 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39271 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39272 + */
39273 +
39274 +
39275 +/******************************************************************************
39276 + @File fm_manip.c
39277 +
39278 + @Description FM PCD manip ...
39279 + *//***************************************************************************/
39280 +#include "std_ext.h"
39281 +#include "error_ext.h"
39282 +#include "string_ext.h"
39283 +#include "debug_ext.h"
39284 +#include "fm_pcd_ext.h"
39285 +#include "fm_port_ext.h"
39286 +#include "fm_muram_ext.h"
39287 +#include "memcpy_ext.h"
39288 +
39289 +#include "fm_common.h"
39290 +#include "fm_hc.h"
39291 +#include "fm_manip.h"
39292 +
39293 +/****************************************/
39294 +/* static functions */
39295 +/****************************************/
39296 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
39297 +{
39298 + t_FmPcdManip *p_CurManip = p_Manip;
39299 +
39300 + if (!MANIP_IS_UNIFIED(p_Manip))
39301 + p_CurManip = p_Manip;
39302 + else
39303 + {
39304 + /* go to first unified */
39305 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
39306 + p_CurManip = p_CurManip->h_PrevManip;
39307 + }
39308 +
39309 + switch (manipInfo)
39310 + {
39311 + case (e_MANIP_HMCT):
39312 + return p_CurManip->p_Hmct;
39313 + case (e_MANIP_HMTD):
39314 + return p_CurManip->h_Ad;
39315 + case (e_MANIP_HANDLER_TABLE_OWNER):
39316 + return (t_Handle)p_CurManip;
39317 + default:
39318 + return NULL;
39319 + }
39320 +}
39321 +
39322 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
39323 +{
39324 + uint16_t size = 0;
39325 + t_FmPcdManip *p_CurManip = p_Manip;
39326 +
39327 + if (!MANIP_IS_UNIFIED(p_Manip))
39328 + return p_Manip->tableSize;
39329 +
39330 + /* accumulate sizes, starting with the first node */
39331 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
39332 + p_CurManip = p_CurManip->h_PrevManip;
39333 +
39334 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39335 + {
39336 + size += p_CurManip->tableSize;
39337 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
39338 + }
39339 + size += p_CurManip->tableSize; /* add last size */
39340 +
39341 + return (size);
39342 +}
39343 +
39344 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
39345 +{
39346 + uint16_t size = 0;
39347 + t_FmPcdManip *p_CurManip = p_Manip;
39348 +
39349 + if (!MANIP_IS_UNIFIED(p_Manip))
39350 + return p_Manip->dataSize;
39351 +
39352 + /* accumulate sizes, starting with the first node */
39353 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
39354 + p_CurManip = p_CurManip->h_PrevManip;
39355 +
39356 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39357 + {
39358 + size += p_CurManip->dataSize;
39359 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
39360 + }
39361 + size += p_CurManip->dataSize; /* add last size */
39362 +
39363 + return (size);
39364 +}
39365 +
39366 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
39367 + uint16_t *p_TableSize, uint8_t *p_DataSize)
39368 +{
39369 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
39370 +
39371 + if (p_FmPcdManipParams->u.hdr.rmv)
39372 + {
39373 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
39374 + {
39375 + case (e_FM_PCD_MANIP_RMV_GENERIC):
39376 + tableSize += HMCD_BASIC_SIZE;
39377 + break;
39378 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
39379 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
39380 + {
39381 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
39382 +#if (DPAA_VERSION >= 11)
39383 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
39384 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
39385 +#endif /* (DPAA_VERSION >= 11) */
39386 + tableSize += HMCD_BASIC_SIZE;
39387 + break;
39388 + default:
39389 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39390 + ("Unknown byHdr.type"));
39391 + }
39392 + break;
39393 + default:
39394 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39395 + ("Unknown rmvParams.type"));
39396 + }
39397 + }
39398 +
39399 + if (p_FmPcdManipParams->u.hdr.insrt)
39400 + {
39401 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
39402 + {
39403 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
39404 + remain =
39405 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
39406 + % 4);
39407 + if (remain)
39408 + localDataSize =
39409 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
39410 + + 4 - remain);
39411 + else
39412 + localDataSize =
39413 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
39414 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
39415 + break;
39416 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
39417 + {
39418 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
39419 + {
39420 +
39421 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
39422 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
39423 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
39424 + {
39425 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
39426 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
39427 + dataSize +=
39428 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
39429 + break;
39430 + default:
39431 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
39432 + }
39433 + break;
39434 +#if (DPAA_VERSION >= 11)
39435 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
39436 + tableSize +=
39437 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
39438 + + HMCD_PARAM_SIZE
39439 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
39440 + dataSize += 2;
39441 + break;
39442 +
39443 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
39444 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
39445 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
39446 +
39447 + break;
39448 +
39449 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
39450 + tableSize +=
39451 + (HMCD_BASIC_SIZE
39452 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
39453 + break;
39454 +#endif /* (DPAA_VERSION >= 11) */
39455 + default:
39456 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39457 + ("Unknown byHdr.type"));
39458 + }
39459 + }
39460 + break;
39461 + default:
39462 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39463 + ("Unknown insrtParams.type"));
39464 + }
39465 + }
39466 +
39467 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
39468 + {
39469 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
39470 + {
39471 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
39472 + tableSize += HMCD_BASIC_SIZE;
39473 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
39474 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
39475 + {
39476 + tableSize += HMCD_PTR_SIZE;
39477 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
39478 + }
39479 + break;
39480 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
39481 + tableSize += HMCD_BASIC_SIZE;
39482 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39483 + & HDR_MANIP_IPV4_ID)
39484 + {
39485 + tableSize += HMCD_PARAM_SIZE;
39486 + dataSize += 2;
39487 + }
39488 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39489 + & HDR_MANIP_IPV4_SRC)
39490 + tableSize += HMCD_IPV4_ADDR_SIZE;
39491 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39492 + & HDR_MANIP_IPV4_DST)
39493 + tableSize += HMCD_IPV4_ADDR_SIZE;
39494 + break;
39495 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
39496 + tableSize += HMCD_BASIC_SIZE;
39497 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39498 + & HDR_MANIP_IPV6_SRC)
39499 + tableSize += HMCD_IPV6_ADDR_SIZE;
39500 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39501 + & HDR_MANIP_IPV6_DST)
39502 + tableSize += HMCD_IPV6_ADDR_SIZE;
39503 + break;
39504 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
39505 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
39506 + == HDR_MANIP_TCP_UDP_CHECKSUM)
39507 + /* we implement this case with the update-checksum descriptor */
39508 + tableSize += HMCD_BASIC_SIZE;
39509 + else
39510 + /* we implement this case with the TCP/UDP-update descriptor */
39511 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
39512 + break;
39513 + default:
39514 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39515 + ("Unknown fieldUpdateParams.type"));
39516 + }
39517 + }
39518 +
39519 + if (p_FmPcdManipParams->u.hdr.custom)
39520 + {
39521 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
39522 + {
39523 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
39524 + {
39525 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
39526 + dataSize +=
39527 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
39528 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
39529 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
39530 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
39531 + dataSize += 2;
39532 + }
39533 + break;
39534 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
39535 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
39536 + break;
39537 + default:
39538 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39539 + ("Unknown customParams.type"));
39540 + }
39541 + }
39542 +
39543 + *p_TableSize = tableSize;
39544 + *p_DataSize = dataSize;
39545 +
39546 + return E_OK;
39547 +}
39548 +
39549 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
39550 + uint8_t *parseArrayOffset)
39551 +{
39552 + e_NetHeaderType hdr = p_HdrInfo->hdr;
39553 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
39554 + bool byField = p_HdrInfo->byField;
39555 + t_FmPcdFields field;
39556 +
39557 + if (byField)
39558 + field = p_HdrInfo->fullField;
39559 +
39560 + if (byField)
39561 + {
39562 + switch (hdr)
39563 + {
39564 + case (HEADER_TYPE_ETH):
39565 + switch (field.eth)
39566 + {
39567 + case (NET_HEADER_FIELD_ETH_TYPE):
39568 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
39569 + break;
39570 + default:
39571 + RETURN_ERROR(
39572 + MAJOR,
39573 + E_NOT_SUPPORTED,
39574 + ("Header manipulation of the type Ethernet with this field not supported"));
39575 + }
39576 + break;
39577 + case (HEADER_TYPE_VLAN):
39578 + switch (field.vlan)
39579 + {
39580 + case (NET_HEADER_FIELD_VLAN_TCI):
39581 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
39582 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
39583 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
39584 + else
39585 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
39586 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
39587 + break;
39588 + default:
39589 + RETURN_ERROR(
39590 + MAJOR,
39591 + E_NOT_SUPPORTED,
39592 + ("Header manipulation of the type VLAN with this field not supported"));
39593 + }
39594 + break;
39595 + default:
39596 + RETURN_ERROR(
39597 + MAJOR,
39598 + E_NOT_SUPPORTED,
39599 + ("Header manipulation of this header by field not supported"));
39600 + }
39601 + }
39602 + else
39603 + {
39604 + switch (hdr)
39605 + {
39606 + case (HEADER_TYPE_ETH):
39607 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
39608 + break;
39609 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
39610 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
39611 + break;
39612 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
39613 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
39614 + break;
39615 + case (HEADER_TYPE_LLC_SNAP):
39616 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
39617 + break;
39618 + case (HEADER_TYPE_PPPoE):
39619 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
39620 + break;
39621 + case (HEADER_TYPE_MPLS):
39622 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
39623 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
39624 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
39625 + else
39626 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
39627 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
39628 + break;
39629 + case (HEADER_TYPE_IPv4):
39630 + case (HEADER_TYPE_IPv6):
39631 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
39632 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
39633 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
39634 + else
39635 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
39636 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
39637 + break;
39638 + case (HEADER_TYPE_MINENCAP):
39639 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
39640 + break;
39641 + case (HEADER_TYPE_GRE):
39642 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
39643 + break;
39644 + case (HEADER_TYPE_TCP):
39645 + case (HEADER_TYPE_UDP):
39646 + case (HEADER_TYPE_IPSEC_AH):
39647 + case (HEADER_TYPE_IPSEC_ESP):
39648 + case (HEADER_TYPE_DCCP):
39649 + case (HEADER_TYPE_SCTP):
39650 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
39651 + break;
39652 + case (HEADER_TYPE_CAPWAP):
39653 + case (HEADER_TYPE_CAPWAP_DTLS):
39654 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
39655 + break;
39656 + default:
39657 + RETURN_ERROR(
39658 + MAJOR,
39659 + E_NOT_SUPPORTED,
39660 + ("Header manipulation of this header is not supported"));
39661 + }
39662 + }
39663 + return E_OK;
39664 +}
39665 +
39666 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
39667 + t_FmPcdManipParams *p_FmPcdManipParams,
39668 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
39669 +{
39670 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
39671 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
39672 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
39673 + p_DestData;
39674 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
39675 + uint8_t j = 0;
39676 +
39677 + if (p_FmPcdManipParams->u.hdr.rmv)
39678 + {
39679 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
39680 + == e_FM_PCD_MANIP_RMV_GENERIC)
39681 + {
39682 + /* initialize HMCD */
39683 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
39684 + /* tmp, should be conditional */
39685 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
39686 + << HMCD_RMV_OFFSET_SHIFT;
39687 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
39688 + << HMCD_RMV_SIZE_SHIFT;
39689 + }
39690 + else
39691 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
39692 + == e_FM_PCD_MANIP_RMV_BY_HDR)
39693 + {
39694 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
39695 + {
39696 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
39697 + {
39698 + uint8_t hmcdOpt;
39699 +
39700 + /* initialize HMCD */
39701 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
39702 +
39703 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
39704 + {
39705 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
39706 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
39707 + break;
39708 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
39709 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
39710 + break;
39711 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
39712 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
39713 + break;
39714 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
39715 + hmcdOpt = HMCD_RMV_L2_MPLS;
39716 + break;
39717 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
39718 + hmcdOpt = HMCD_RMV_L2_PPPOE;
39719 + break;
39720 + default:
39721 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
39722 + }
39723 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
39724 + break;
39725 + }
39726 +#if (DPAA_VERSION >= 11)
39727 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
39728 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
39729 + << HMCD_OC_SHIFT;
39730 + break;
39731 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
39732 + {
39733 + uint8_t prsArrayOffset;
39734 + t_Error err = E_OK;
39735 +
39736 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
39737 + << HMCD_OC_SHIFT;
39738 +
39739 + err =
39740 + GetPrOffsetByHeaderOrField(
39741 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
39742 + &prsArrayOffset);
39743 + ASSERT_COND(!err);
39744 + /* was previously checked */
39745 +
39746 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
39747 + }
39748 + break;
39749 +#endif /* (DPAA_VERSION >= 11) */
39750 + default:
39751 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
39752 + ("manip header remove by hdr type!"));
39753 + }
39754 + }
39755 +
39756 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39757 + /* save a pointer to the "last" indication word */
39758 + p_Last = p_TmpHmct;
39759 + /* advance to next command */
39760 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39761 + }
39762 +
39763 + if (p_FmPcdManipParams->u.hdr.insrt)
39764 + {
39765 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
39766 + == e_FM_PCD_MANIP_INSRT_GENERIC)
39767 + {
39768 + /* initialize HMCD */
39769 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
39770 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
39771 + << HMCD_OC_SHIFT;
39772 + else
39773 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
39774 +
39775 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
39776 + << HMCD_INSRT_OFFSET_SHIFT;
39777 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
39778 + << HMCD_INSRT_SIZE_SHIFT;
39779 +
39780 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
39781 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
39782 +
39783 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39784 + /* save a pointer to the "last" indication word */
39785 + p_Last = p_TmpHmct;
39786 +
39787 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39788 +
39789 + /* initialize data to be inserted */
39790 + /* if size is not a multiple of 4, padd with 0's */
39791 + origSize = size;
39792 + remain = (uint8_t)(size % 4);
39793 + if (remain)
39794 + {
39795 + size += (uint8_t)(4 - remain);
39796 + p_LocalData = (uint32_t *)XX_Malloc(size);
39797 + memset((uint8_t *)p_LocalData, 0, size);
39798 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
39799 + }
39800 + else
39801 + p_LocalData = (uint32_t*)p_UsrData;
39802 +
39803 + /* initialize data and advance pointer to next command */
39804 + MemCpy8(p_TmpHmct, p_LocalData, size);
39805 + p_TmpHmct += size / sizeof(uint32_t);
39806 +
39807 + if (remain)
39808 + XX_Free(p_LocalData);
39809 + }
39810 +
39811 + else
39812 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
39813 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
39814 + {
39815 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
39816 + {
39817 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
39818 + {
39819 + uint8_t hmcdOpt;
39820 +
39821 + /* initialize HMCD */
39822 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
39823 + << HMCD_OC_SHIFT;
39824 +
39825 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
39826 + {
39827 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
39828 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
39829 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
39830 + else
39831 + hmcdOpt = HMCD_INSRT_L2_MPLS;
39832 + break;
39833 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
39834 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
39835 + break;
39836 + default:
39837 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
39838 + }
39839 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
39840 +
39841 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39842 + /* save a pointer to the "last" indication word */
39843 + p_Last = p_TmpHmct;
39844 +
39845 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39846 +
39847 + /* set size and pointer of user's data */
39848 + size =
39849 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
39850 +
39851 + ASSERT_COND(p_TmpData);
39852 + MemCpy8(
39853 + p_TmpData,
39854 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
39855 + size);
39856 + tmpReg =
39857 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
39858 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
39859 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
39860 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39861 + p_TmpHmct += HMCD_PTR_SIZE / 4;
39862 + p_TmpData += size;
39863 + }
39864 + break;
39865 +#if (DPAA_VERSION >= 11)
39866 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
39867 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
39868 + << HMCD_OC_SHIFT;
39869 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
39870 + tmpReg |= HMCD_IP_L4_CS_CALC;
39871 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
39872 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
39873 + tmpReg |= HMCD_IP_OR_QOS;
39874 + tmpReg |=
39875 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
39876 + & HMCD_IP_LAST_PID_MASK;
39877 + tmpReg |=
39878 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
39879 + << HMCD_IP_SIZE_SHIFT)
39880 + & HMCD_IP_SIZE_MASK);
39881 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
39882 + tmpReg |= HMCD_IP_DF_MODE;
39883 +
39884 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39885 +
39886 + /* save a pointer to the "last" indication word */
39887 + p_Last = p_TmpHmct;
39888 +
39889 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39890 +
39891 + /* set IP id */
39892 + ASSERT_COND(p_TmpData);
39893 + WRITE_UINT16(
39894 + *(uint16_t*)p_TmpData,
39895 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
39896 + WRITE_UINT32(
39897 + *p_TmpHmct,
39898 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
39899 + p_TmpData += 2;
39900 + p_TmpHmct += HMCD_PTR_SIZE / 4;
39901 +
39902 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
39903 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
39904 +
39905 + MemCpy8(
39906 + p_TmpHmct,
39907 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
39908 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
39909 + p_TmpHmct +=
39910 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
39911 + / 4;
39912 + break;
39913 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
39914 + tmpReg = HMCD_INSRT_UDP_LITE;
39915 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
39916 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
39917 + << HMCD_OC_SHIFT;
39918 +
39919 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39920 +
39921 + /* save a pointer to the "last" indication word */
39922 + p_Last = p_TmpHmct;
39923 +
39924 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39925 +
39926 + MemCpy8(
39927 + p_TmpHmct,
39928 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
39929 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
39930 + p_TmpHmct +=
39931 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
39932 + / 4;
39933 + break;
39934 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
39935 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
39936 + << HMCD_OC_SHIFT;
39937 + tmpReg |= HMCD_CAPWAP_INSRT;
39938 +
39939 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39940 +
39941 + /* save a pointer to the "last" indication word */
39942 + p_Last = p_TmpHmct;
39943 +
39944 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39945 +
39946 + MemCpy8(
39947 + p_TmpHmct,
39948 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
39949 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
39950 + p_TmpHmct +=
39951 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
39952 + / 4;
39953 + break;
39954 +#endif /* (DPAA_VERSION >= 11) */
39955 + default:
39956 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
39957 + ("manip header insert by header type!"));
39958 +
39959 + }
39960 + }
39961 + }
39962 +
39963 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
39964 + {
39965 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
39966 + {
39967 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
39968 + /* set opcode */
39969 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
39970 + << HMCD_OC_SHIFT;
39971 +
39972 + /* set mode & table pointer */
39973 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
39974 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
39975 + {
39976 + /* set Mode */
39977 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
39978 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
39979 + /* set VPRI default */
39980 + tmpReg |=
39981 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
39982 + WRITE_UINT32(*p_TmpHmct, tmpReg);
39983 + /* save a pointer to the "last" indication word */
39984 + p_Last = p_TmpHmct;
39985 + /* write the table pointer into the Manip descriptor */
39986 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
39987 +
39988 + tmpReg = 0;
39989 + ASSERT_COND(p_TmpData);
39990 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
39991 + {
39992 + /* first we build from each 8 values a 32bit register */
39993 + tmpReg |=
39994 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
39995 + << (32 - 4 * (j + 1));
39996 + j++;
39997 + /* Than we write this register to the next table word
39998 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
39999 + if ((i % 8) == 7)
40000 + {
40001 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
40002 + tmpReg);
40003 + tmpReg = 0;
40004 + j = 0;
40005 + }
40006 + }
40007 +
40008 + WRITE_UINT32(
40009 + *p_TmpHmct,
40010 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
40011 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40012 +
40013 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
40014 + }
40015 + else
40016 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40017 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40018 + {
40019 + /* set Mode */
40020 + /* line commented out as it has no-side-effect ('0' value). */
40021 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
40022 + /* set VPRI parameter */
40023 + tmpReg |=
40024 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
40025 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40026 + /* save a pointer to the "last" indication word */
40027 + p_Last = p_TmpHmct;
40028 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40029 + }
40030 + break;
40031 +
40032 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
40033 + /* set opcode */
40034 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
40035 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40036 + & HDR_MANIP_IPV4_TTL)
40037 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
40038 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40039 + & HDR_MANIP_IPV4_TOS)
40040 + {
40041 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
40042 + tmpReg |=
40043 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
40044 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
40045 + }
40046 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40047 + & HDR_MANIP_IPV4_ID)
40048 + tmpReg |= HMCD_IPV4_UPDATE_ID;
40049 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40050 + & HDR_MANIP_IPV4_SRC)
40051 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
40052 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40053 + & HDR_MANIP_IPV4_DST)
40054 + tmpReg |= HMCD_IPV4_UPDATE_DST;
40055 + /* write the first 4 bytes of the descriptor */
40056 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40057 + /* save a pointer to the "last" indication word */
40058 + p_Last = p_TmpHmct;
40059 +
40060 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40061 +
40062 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40063 + & HDR_MANIP_IPV4_ID)
40064 + {
40065 + ASSERT_COND(p_TmpData);
40066 + WRITE_UINT16(
40067 + *(uint16_t*)p_TmpData,
40068 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
40069 + WRITE_UINT32(
40070 + *p_TmpHmct,
40071 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
40072 + p_TmpData += 2;
40073 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40074 + }
40075 +
40076 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40077 + & HDR_MANIP_IPV4_SRC)
40078 + {
40079 + WRITE_UINT32(
40080 + *p_TmpHmct,
40081 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
40082 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
40083 + }
40084 +
40085 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40086 + & HDR_MANIP_IPV4_DST)
40087 + {
40088 + WRITE_UINT32(
40089 + *p_TmpHmct,
40090 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
40091 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
40092 + }
40093 + break;
40094 +
40095 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
40096 + /* set opcode */
40097 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
40098 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40099 + & HDR_MANIP_IPV6_HL)
40100 + tmpReg |= HMCD_IPV6_UPDATE_HL;
40101 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40102 + & HDR_MANIP_IPV6_TC)
40103 + {
40104 + tmpReg |= HMCD_IPV6_UPDATE_TC;
40105 + tmpReg |=
40106 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
40107 + << HMCD_IPV6_UPDATE_TC_SHIFT;
40108 + }
40109 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40110 + & HDR_MANIP_IPV6_SRC)
40111 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
40112 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40113 + & HDR_MANIP_IPV6_DST)
40114 + tmpReg |= HMCD_IPV6_UPDATE_DST;
40115 + /* write the first 4 bytes of the descriptor */
40116 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40117 + /* save a pointer to the "last" indication word */
40118 + p_Last = p_TmpHmct;
40119 +
40120 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40121 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40122 + & HDR_MANIP_IPV6_SRC)
40123 + {
40124 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
40125 + {
40126 + memcpy(&tmp_ipv6_addr,
40127 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
40128 + sizeof(uint32_t));
40129 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
40130 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40131 + }
40132 + }
40133 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40134 + & HDR_MANIP_IPV6_DST)
40135 + {
40136 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
40137 + {
40138 + memcpy(&tmp_ipv6_addr,
40139 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
40140 + sizeof(uint32_t));
40141 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
40142 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40143 + }
40144 + }
40145 + break;
40146 +
40147 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
40148 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40149 + == HDR_MANIP_TCP_UDP_CHECKSUM)
40150 + {
40151 + /* we implement this case with the update-checksum descriptor */
40152 + /* set opcode */
40153 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
40154 + << HMCD_OC_SHIFT;
40155 + /* write the first 4 bytes of the descriptor */
40156 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40157 + /* save a pointer to the "last" indication word */
40158 + p_Last = p_TmpHmct;
40159 +
40160 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40161 + }
40162 + else
40163 + {
40164 + /* we implement this case with the TCP/UDP update descriptor */
40165 + /* set opcode */
40166 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
40167 + << HMCD_OC_SHIFT;
40168 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40169 + & HDR_MANIP_TCP_UDP_DST)
40170 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
40171 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40172 + & HDR_MANIP_TCP_UDP_SRC)
40173 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
40174 + /* write the first 4 bytes of the descriptor */
40175 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40176 + /* save a pointer to the "last" indication word */
40177 + p_Last = p_TmpHmct;
40178 +
40179 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40180 +
40181 + tmpReg = 0;
40182 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40183 + & HDR_MANIP_TCP_UDP_SRC)
40184 + tmpReg |=
40185 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
40186 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
40187 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40188 + & HDR_MANIP_TCP_UDP_DST)
40189 + tmpReg |=
40190 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
40191 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40192 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40193 + }
40194 + break;
40195 +
40196 + default:
40197 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
40198 + ("Unknown fieldUpdateParams.type"));
40199 + }
40200 + }
40201 +
40202 + if (p_FmPcdManipParams->u.hdr.custom)
40203 + {
40204 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
40205 + {
40206 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
40207 + /* set opcode */
40208 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
40209 +
40210 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
40211 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
40212 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
40213 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
40214 + /* line commented out as it has no-side-effect ('0' value). */
40215 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
40216 + else
40217 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
40218 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
40219 + {
40220 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
40221 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
40222 + tmpReg |= HMCD_IP_REPLACE_ID;
40223 + }
40224 + else
40225 + RETURN_ERROR(
40226 + MINOR,
40227 + E_NOT_SUPPORTED,
40228 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
40229 +
40230 + /* write the first 4 bytes of the descriptor */
40231 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40232 + /* save a pointer to the "last" indication word */
40233 + p_Last = p_TmpHmct;
40234 +
40235 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40236 +
40237 + size =
40238 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
40239 + ASSERT_COND(p_TmpData);
40240 + MemCpy8(
40241 + p_TmpData,
40242 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
40243 + size);
40244 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
40245 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
40246 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
40247 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40248 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40249 + p_TmpData += size;
40250 +
40251 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
40252 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
40253 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
40254 + {
40255 + WRITE_UINT16(
40256 + *(uint16_t*)p_TmpData,
40257 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
40258 + WRITE_UINT32(
40259 + *p_TmpHmct,
40260 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
40261 + p_TmpData += 2;
40262 + }
40263 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40264 + break;
40265 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
40266 + /* set opcode */
40267 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
40268 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
40269 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
40270 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
40271 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
40272 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
40273 +
40274 + /* write the first 4 bytes of the descriptor */
40275 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40276 + /* save a pointer to the "last" indication word */
40277 + p_Last = p_TmpHmct;
40278 +
40279 + p_TmpHmct += HMCD_BASIC_SIZE/4;
40280 +
40281 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
40282 + {
40283 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
40284 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
40285 + /* write the next 4 bytes of the descriptor */
40286 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40287 + }
40288 + p_TmpHmct += HMCD_PARAM_SIZE/4;
40289 + break;
40290 + default:
40291 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
40292 + ("Unknown customParams.type"));
40293 + }
40294 + }
40295 +
40296 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
40297 + the old table and should be freed */
40298 + if (p_FmPcdManipParams->h_NextManip
40299 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
40300 + && (MANIP_DONT_REPARSE(p_Manip)))
40301 + {
40302 + if (new)
40303 + {
40304 + /* If this is the first time this manip is created we need to free unused memory. If it
40305 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
40306 + * table - no allocation, no free */
40307 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
40308 +
40309 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
40310 + }
40311 + }
40312 + else
40313 + {
40314 + ASSERT_COND(p_Last);
40315 + /* set the "last" indication on the last command of the current table */
40316 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
40317 + }
40318 +
40319 + return E_OK;
40320 +}
40321 +
40322 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
40323 + t_FmPcdManipParams *p_FmPcdManipParams)
40324 +{
40325 + t_FmPcdManip *p_CurManip;
40326 + t_Error err;
40327 + uint32_t nextSize = 0, totalSize;
40328 + uint16_t tmpReg;
40329 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
40330 +
40331 + /* set Manip structure */
40332 +
40333 + p_Manip->dontParseAfterManip =
40334 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
40335 +
40336 + if (p_FmPcdManipParams->h_NextManip)
40337 + { /* Next Header manipulation exists */
40338 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
40339 +
40340 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
40341 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
40342 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
40343 + else /* either parsing is required or next manip is Frag; no table merging. */
40344 + p_Manip->cascaded = TRUE;
40345 + /* pass up the "cascaded" attribute. The whole chain is cascaded
40346 + * if something is cascaded along the way. */
40347 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
40348 + p_Manip->cascaded = TRUE;
40349 + }
40350 +
40351 + /* Allocate new table */
40352 + /* calculate table size according to manip parameters */
40353 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
40354 + &p_Manip->dataSize);
40355 + if (err)
40356 + RETURN_ERROR(MINOR, err, NO_MSG);
40357 +
40358 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
40359 +
40360 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
40361 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
40362 + if (!p_Manip->p_Hmct)
40363 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
40364 +
40365 + if (p_Manip->dataSize)
40366 + p_Manip->p_Data =
40367 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
40368 +
40369 + /* update shadow size to allow runtime replacement of Header manipulation */
40370 + /* The allocated shadow is divided as follows:
40371 + 0 . . . 16 . . .
40372 + --------------------------------
40373 + | Shadow | Shadow HMTD |
40374 + | HMTD | Match Table |
40375 + | (16 bytes) | (maximal size) |
40376 + --------------------------------
40377 + */
40378 +
40379 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
40380 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
40381 + if (err != E_OK)
40382 + {
40383 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
40384 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
40385 + ("MURAM allocation for HdrManip node shadow"));
40386 + }
40387 +
40388 + if (p_FmPcdManipParams->h_NextManip
40389 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
40390 + && (MANIP_DONT_REPARSE(p_Manip)))
40391 + {
40392 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
40393 + e_MANIP_HMCT);
40394 + p_CurManip = p_FmPcdManipParams->h_NextManip;
40395 + /* Run till the last Manip (which is the first to configure) */
40396 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
40397 + p_CurManip = p_CurManip->h_NextManip;
40398 +
40399 + while (p_CurManip)
40400 + {
40401 + /* If this is a unified table, point to the part of the table
40402 + * which is the relative offset in HMCT.
40403 + */
40404 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
40405 + (p_Manip->tableSize +
40406 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
40407 + PTR_TO_UINT(p_OldHmct))));
40408 + if (p_CurManip->p_Data)
40409 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
40410 + (p_Manip->tableSize +
40411 + (PTR_TO_UINT(p_CurManip->p_Data) -
40412 + PTR_TO_UINT(p_OldHmct))));
40413 + else
40414 + p_TmpDataPtr = NULL;
40415 +
40416 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
40417 + p_TmpDataPtr, FALSE);
40418 + /* update old manip table pointer */
40419 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
40420 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
40421 +
40422 + p_CurManip = p_CurManip->h_PrevManip;
40423 + }
40424 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
40425 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
40426 + p_OldHmct);
40427 + }
40428 +
40429 + /* Fill table */
40430 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
40431 + p_Manip->p_Data, TRUE);
40432 + if (err)
40433 + {
40434 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
40435 + RETURN_ERROR(MINOR, err, NO_MSG);
40436 + }
40437 +
40438 + /* Build HMTD (table descriptor) */
40439 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
40440 +
40441 + /* add parseAfterManip */
40442 + if (!p_Manip->dontParseAfterManip)
40443 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
40444 +
40445 + /* create cascade */
40446 + /*if (p_FmPcdManipParams->h_NextManip
40447 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
40448 + if (p_Manip->cascaded)
40449 + {
40450 + uint16_t nextAd;
40451 + /* indicate that there's another HM table descriptor */
40452 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
40453 + /* get address of next HMTD (table descriptor; h_Ad).
40454 + * If the next HMTD was removed due to table unifing, get the address
40455 + * of the "next next" as written in the h_Ad of the next h_Manip node.
40456 + */
40457 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
40458 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
40459 + else
40460 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
40461 +
40462 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
40463 + }
40464 +
40465 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
40466 + WRITE_UINT32(
40467 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
40468 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
40469 +
40470 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
40471 +
40472 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
40473 + {
40474 + /* The HMTD of the next Manip is never going to be used */
40475 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
40476 + FM_MURAM_FreeMem(
40477 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
40478 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
40479 + else
40480 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
40481 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
40482 + }
40483 +
40484 + return E_OK;
40485 +}
40486 +
40487 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
40488 + t_FmPcdManipParams *p_FmPcdManipParams)
40489 +{
40490 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
40491 + uint16_t newSize;
40492 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
40493 + t_Error err;
40494 + t_FmPcdManip *p_CurManip = p_Manip;
40495 +
40496 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
40497 + if (err)
40498 + RETURN_ERROR(MINOR, err, NO_MSG);
40499 +
40500 + /* check coherency of new table parameters */
40501 + if (newSize > p_Manip->tableSize)
40502 + RETURN_ERROR(
40503 + MINOR,
40504 + E_INVALID_VALUE,
40505 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
40506 + if (newDataSize > p_Manip->dataSize)
40507 + RETURN_ERROR(
40508 + MINOR,
40509 + E_INVALID_VALUE,
40510 + ("New Hdr Manip configuration requires larger size than current one (data)."));
40511 + if (p_FmPcdManipParams->h_NextManip)
40512 + RETURN_ERROR(
40513 + MINOR, E_INVALID_VALUE,
40514 + ("New Hdr Manip configuration can not contain h_NextManip."));
40515 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
40516 + RETURN_ERROR(
40517 + MINOR,
40518 + E_INVALID_VALUE,
40519 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
40520 + if (p_Manip->dontParseAfterManip
40521 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
40522 + RETURN_ERROR(
40523 + MINOR,
40524 + E_INVALID_VALUE,
40525 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
40526 +
40527 + p_Manip->tableSize = newSize;
40528 + p_Manip->dataSize = newDataSize;
40529 +
40530 + /* Build the new table in the shadow */
40531 + if (!MANIP_IS_UNIFIED(p_Manip))
40532 + {
40533 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
40534 + if (p_Manip->p_Data)
40535 + p_TmpDataPtr =
40536 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
40537 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
40538 +
40539 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
40540 + FALSE);
40541 + }
40542 + else
40543 + {
40544 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
40545 + ASSERT_COND(p_WholeHmct);
40546 +
40547 + /* Run till the last Manip (which is the first to configure) */
40548 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
40549 + p_CurManip = p_CurManip->h_NextManip;
40550 +
40551 + while (p_CurManip)
40552 + {
40553 + /* If this is a non-head node in a unified table, point to the part of the shadow
40554 + * which is the relative offset in HMCT.
40555 + * else, point to the beginning of the
40556 + * shadow table (we save 16 for the HMTD.
40557 + */
40558 + p_TmpHmctPtr =
40559 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
40560 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
40561 + if (p_CurManip->p_Data)
40562 + p_TmpDataPtr =
40563 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
40564 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
40565 +
40566 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
40567 + p_TmpDataPtr, FALSE);
40568 + p_CurManip = p_CurManip->h_PrevManip;
40569 + }
40570 + }
40571 +
40572 + return E_OK;
40573 +}
40574 +
40575 +static t_Error CreateManipActionBackToOrig(
40576 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
40577 +{
40578 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
40579 + t_FmPcdManip *p_CurManip = p_Manip;
40580 +
40581 + /* Build the new table in the shadow */
40582 + if (!MANIP_IS_UNIFIED(p_Manip))
40583 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
40584 + FALSE);
40585 + else
40586 + {
40587 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
40588 + ASSERT_COND(p_WholeHmct);
40589 +
40590 + /* Run till the last Manip (which is the first to configure) */
40591 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
40592 + p_CurManip = p_CurManip->h_NextManip;
40593 +
40594 + while (p_CurManip)
40595 + {
40596 + /* If this is a unified table, point to the part of the table
40597 + * which is the relative offset in HMCT.
40598 + */
40599 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
40600 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
40601 +
40602 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
40603 + p_TmpDataPtr, FALSE);
40604 +
40605 + p_CurManip = p_CurManip->h_PrevManip;
40606 + }
40607 + }
40608 +
40609 + return E_OK;
40610 +}
40611 +
40612 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40613 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
40614 +{
40615 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
40616 + t_Handle p_Ad;
40617 + uint32_t tmpReg32 = 0;
40618 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
40619 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
40620 +
40621 + switch (p_Manip->opcode)
40622 + {
40623 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
40624 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40625 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
40626 + {
40627 + tmpReg32 =
40628 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
40629 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
40630 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
40631 + tmpReg32;
40632 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
40633 + p_Manip->icOffset = icOffset;
40634 + }
40635 + else
40636 + {
40637 + if (p_Manip->icOffset != icOffset)
40638 + RETURN_ERROR(
40639 + MAJOR,
40640 + E_INVALID_VALUE,
40641 + ("this manipulation was updated previously by different value"););
40642 + }
40643 + break;
40644 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
40645 + if (p_Manip->h_Frag)
40646 + {
40647 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
40648 + {
40649 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40650 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
40651 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
40652 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
40653 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
40654 + p_Manip->icOffset = icOffset;
40655 + }
40656 + else
40657 + {
40658 + if (p_Manip->icOffset != icOffset)
40659 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
40660 + }
40661 + }
40662 + break;
40663 + }
40664 +
40665 + return E_OK;
40666 +}
40667 +
40668 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
40669 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
40670 +{
40671 +
40672 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
40673 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40674 + t_Error err;
40675 + uint32_t tmpReg32;
40676 +
40677 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40678 +
40679 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
40680 + SANITY_CHECK_RETURN_ERROR(
40681 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
40682 + E_INVALID_STATE);
40683 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
40684 +
40685 + if (p_Manip->updateParams)
40686 + {
40687 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
40688 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
40689 + RETURN_ERROR(
40690 + MAJOR, E_INVALID_STATE,
40691 + ("in this stage parameters from Port has not be updated"));
40692 +
40693 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
40694 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
40695 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
40696 +
40697 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40698 + if (err)
40699 + RETURN_ERROR(MAJOR, err, NO_MSG);
40700 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
40701 + RETURN_ERROR(
40702 + MAJOR, E_INVALID_STATE,
40703 + ("Parser result offset wasn't configured previousely"));
40704 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
40705 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
40706 +#endif
40707 + }
40708 + else
40709 + if (validate)
40710 + {
40711 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
40712 + || (p_Manip->updateParams & OFFSET_OF_PR))
40713 + RETURN_ERROR(
40714 + MAJOR, E_INVALID_STATE,
40715 + ("in this stage parameters from Port has be updated"));
40716 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
40717 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
40718 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
40719 +
40720 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40721 + if (err)
40722 + RETURN_ERROR(MAJOR, err, NO_MSG);
40723 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
40724 + RETURN_ERROR(
40725 + MAJOR, E_INVALID_STATE,
40726 + ("Parser result offset wasn't configured previousely"));
40727 +
40728 + }
40729 +
40730 + ASSERT_COND(p_Ad);
40731 +
40732 + if (p_Manip->updateParams & OFFSET_OF_PR)
40733 + {
40734 + tmpReg32 = 0;
40735 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
40736 + WRITE_UINT32(p_Ad->matchTblPtr,
40737 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
40738 + p_Manip->updateParams &= ~OFFSET_OF_PR;
40739 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
40740 + }
40741 + else
40742 + if (validate)
40743 + {
40744 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
40745 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
40746 + RETURN_ERROR(
40747 + MAJOR,
40748 + E_INVALID_STATE,
40749 + ("this manipulation was updated previousely by different value"););
40750 + }
40751 +
40752 + return E_OK;
40753 +}
40754 +
40755 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
40756 +{
40757 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
40758 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
40759 + uint32_t tmpReg32 = 0;
40760 +
40761 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40762 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
40763 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
40764 + 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);
40765 +
40766 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
40767 +
40768 + if (p_Manip->updateParams)
40769 + {
40770 +
40771 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
40772 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
40773 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
40774 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
40775 + if (!p_SavedManipParams)
40776 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
40777 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
40778 +
40779 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
40780 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
40781 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
40782 +
40783 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
40784 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
40785 + }
40786 + else if (validate)
40787 + {
40788 +
40789 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
40790 + if (!p_SavedManipParams)
40791 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
40792 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
40793 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
40794 + }
40795 +
40796 + return E_OK;
40797 +}
40798 +
40799 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
40800 + t_FmPcdManip *p_Manip,
40801 + t_Handle h_Ad,
40802 + bool validate,
40803 + t_Handle h_FmTree)
40804 +{
40805 + t_AdOfTypeContLookup *p_Ad;
40806 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40807 + t_Error err;
40808 + uint32_t tmpReg32 = 0;
40809 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
40810 +
40811 + UNUSED(h_Ad);
40812 +
40813 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40814 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
40815 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
40816 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
40817 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
40818 +
40819 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
40820 +
40821 + if (p_Manip->updateParams)
40822 + {
40823 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
40824 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
40825 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
40826 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
40827 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
40828 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
40829 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
40830 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
40831 +
40832 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40833 + if (err)
40834 + RETURN_ERROR(MAJOR, err, NO_MSG);
40835 +
40836 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
40837 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
40838 +
40839 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
40840 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
40841 +
40842 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
40843 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
40844 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
40845 +
40846 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
40847 + }
40848 + else if (validate)
40849 + {
40850 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
40851 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
40852 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
40853 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
40854 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
40855 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
40856 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40857 + if (err)
40858 + RETURN_ERROR(MAJOR, err, NO_MSG);
40859 +
40860 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
40861 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
40862 + }
40863 +
40864 + if (p_Manip->updateParams)
40865 + {
40866 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
40867 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
40868 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
40869 +
40870 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
40871 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
40872 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
40873 + }
40874 + else if (validate)
40875 + {
40876 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
40877 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
40878 + }
40879 +
40880 + return E_OK;
40881 +}
40882 +
40883 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
40884 + t_Handle h_FmPort,
40885 + t_FmPcdManip *p_Manip,
40886 + t_Handle h_Ad,
40887 + bool validate)
40888 +{
40889 + t_CapwapReasmPram *p_ReassmTbl;
40890 + t_Error err;
40891 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40892 + uint8_t i = 0;
40893 + uint16_t size;
40894 + uint32_t tmpReg32;
40895 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40896 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
40897 +
40898 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40899 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
40900 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
40901 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
40902 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
40903 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
40904 +
40905 + if (p_Manip->h_FmPcd != h_FmPcd)
40906 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40907 + ("handler of PCD previously was initiated by different value"));
40908 +
40909 + UNUSED(h_Ad);
40910 +
40911 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40912 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
40913 +
40914 + if (p_Manip->updateParams)
40915 + {
40916 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
40917 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
40918 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
40919 + !(p_Manip->updateParams & HW_PORT_ID)) ||
40920 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
40921 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
40922 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
40923 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
40924 +
40925 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
40926 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
40927 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
40928 +
40929 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40930 + if (err)
40931 + RETURN_ERROR(MAJOR, err, NO_MSG);
40932 +
40933 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
40934 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
40935 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
40936 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
40937 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
40938 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
40939 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
40940 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
40941 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
40942 + }
40943 + else if (validate)
40944 + {
40945 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
40946 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
40947 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
40948 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
40949 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
40950 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
40951 + (p_Manip->updateParams & HW_PORT_ID)))
40952 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
40953 +
40954 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
40955 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
40956 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
40957 +
40958 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40959 + if (err)
40960 + RETURN_ERROR(MAJOR, err, NO_MSG);
40961 +
40962 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
40963 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
40964 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
40965 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
40966 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
40967 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
40968 + }
40969 +
40970 + if (p_Manip->updateParams)
40971 + {
40972 + if (p_Manip->updateParams & NUM_OF_TASKS)
40973 + {
40974 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
40975 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
40976 + if (size > 255)
40977 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
40978 +
40979 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
40980 +
40981 + /*p_ReassmFrmDescrIndxPoolTbl*/
40982 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
40983 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40984 + (uint32_t)(size + 1),
40985 + 4);
40986 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40987 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
40988 +
40989 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
40990 +
40991 + for ( i = 0; i < size; i++)
40992 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
40993 +
40994 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
40995 +
40996 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
40997 +
40998 + /*p_ReassmFrmDescrPoolTbl*/
40999 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
41000 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41001 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
41002 + 4);
41003 +
41004 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
41005 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
41006 +
41007 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
41008 +
41009 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
41010 +
41011 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
41012 +
41013 + /*p_TimeOutTbl*/
41014 +
41015 + p_Manip->capwapFragParams.p_TimeOutTbl =
41016 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41017 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
41018 + 4);
41019 +
41020 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
41021 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
41022 +
41023 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
41024 +
41025 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
41026 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
41027 +
41028 + p_Manip->updateParams &= ~NUM_OF_TASKS;
41029 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
41030 + }
41031 +
41032 + if (p_Manip->updateParams & OFFSET_OF_DATA)
41033 + {
41034 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
41035 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
41036 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
41037 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
41038 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
41039 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
41040 + }
41041 +
41042 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
41043 + {
41044 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
41045 +
41046 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
41047 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
41048 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
41049 +
41050 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
41051 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
41052 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
41053 + p_Manip->updateParams &= ~OFFSET_OF_PR;
41054 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
41055 + }
41056 + else
41057 + {
41058 + p_Manip->capwapFragParams.prOffset = 0xff;
41059 + p_Manip->updateParams &= ~OFFSET_OF_PR;
41060 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
41061 + }
41062 +
41063 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
41064 + p_Manip->updateParams &= ~HW_PORT_ID;
41065 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
41066 +
41067 + /*timeout hc */
41068 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
41069 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
41070 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
41071 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
41072 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
41073 + }
41074 +
41075 + else if (validate)
41076 + {
41077 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
41078 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
41079 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
41080 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
41081 +
41082 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
41083 + {
41084 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
41085 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
41086 + }
41087 + else
41088 + {
41089 + if (p_Manip->capwapFragParams.prOffset != 0xff)
41090 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
41091 + }
41092 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
41093 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
41094 + }
41095 +
41096 + return E_OK;
41097 +}
41098 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41099 +
41100 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
41101 +{
41102 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
41103 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
41104 + t_Error err = E_OK;
41105 + uint8_t result;
41106 + uint32_t bitFor1Micro, tsbs, log2num;
41107 +
41108 + ASSERT_COND(p_FmPcd);
41109 + ASSERT_COND(h_ReasmCommonPramTbl);
41110 +
41111 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
41112 + if (bitFor1Micro == 0)
41113 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
41114 +
41115 + bitFor1Micro = 32 - bitFor1Micro;
41116 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
41117 + tsbs = bitFor1Micro - log2num;
41118 +
41119 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
41120 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
41121 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
41122 + ccReassmTimeoutParams.activate = TRUE;
41123 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
41124 + &result)) != E_OK)
41125 + RETURN_ERROR(MAJOR, err, NO_MSG);
41126 +
41127 + switch (result)
41128 + {
41129 + case (0):
41130 + return E_OK;
41131 + case (1):
41132 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
41133 + case (2):
41134 + RETURN_ERROR(
41135 + MAJOR, E_NO_MEMORY,
41136 + ("failed to allocate internal buffer from the HC-Port"));
41137 + case (3):
41138 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
41139 + ("'Disable Timeout Task' with invalid IPRCPT"));
41140 + case (4):
41141 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
41142 + case (5):
41143 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
41144 + default:
41145 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
41146 + }
41147 + return E_OK;
41148 +}
41149 +
41150 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
41151 +{
41152 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
41153 + uint64_t tmpReg64, size;
41154 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41155 + t_Error err = E_OK;
41156 +
41157 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
41158 + if (bitFor1Micro == 0)
41159 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
41160 +
41161 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
41162 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
41163 + p_Manip->reassmParams.p_ReassCommonTbl =
41164 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
41165 + p_FmPcd->h_FmMuram,
41166 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
41167 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
41168 +
41169 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
41170 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41171 + ("MURAM alloc for Reassembly common parameters table"));
41172 +
41173 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
41174 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
41175 +
41176 + /* Setting the TimeOut Mode.*/
41177 + tmpReg32 = 0;
41178 + if (p_Manip->reassmParams.timeOutMode
41179 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
41180 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
41181 +
41182 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
41183 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
41184 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
41185 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
41186 + tmpReg32);
41187 +
41188 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
41189 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
41190 +
41191 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
41192 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
41193 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41194 + (uint32_t)(size * 2),
41195 + 256));
41196 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
41197 + RETURN_ERROR(
41198 + MAJOR, E_NO_MEMORY,
41199 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
41200 +
41201 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
41202 + 0, (uint32_t)(size * 2));
41203 +
41204 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
41205 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
41206 + The last entry in this pool must contain the index zero*/
41207 + for (i = 0; i < (size - 1); i++)
41208 + WRITE_UINT16(
41209 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
41210 + (uint16_t)(i+1));
41211 +
41212 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
41213 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
41214 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
41215 + - p_FmPcd->physicalMuramBase);
41216 + WRITE_UINT32(
41217 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
41218 + tmpReg32);
41219 +
41220 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
41221 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
41222 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
41223 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
41224 +
41225 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
41226 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
41227 +
41228 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
41229 + (uint32_t)(size * 64));
41230 +
41231 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
41232 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
41233 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
41234 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41235 + & FM_PCD_MANIP_REASM_LIODN_MASK)
41236 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
41237 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41238 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
41239 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
41240 + WRITE_UINT32(
41241 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
41242 + (uint32_t)(tmpReg64 >> 32));
41243 + WRITE_UINT32(
41244 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
41245 + (uint32_t)tmpReg64);
41246 +
41247 + /*Allocation of the TimeOut table - This table resides in the MURAM.
41248 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
41249 + p_Manip->reassmParams.timeOutTblAddr =
41250 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
41251 +
41252 + if (!p_Manip->reassmParams.timeOutTblAddr)
41253 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41254 + ("MURAM alloc for Reassembly timeout table"));
41255 +
41256 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
41257 + (uint16_t)(size * 8));
41258 +
41259 + /* Sets the TimeOut table offset from MURAM */
41260 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
41261 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
41262 + - p_FmPcd->physicalMuramBase);
41263 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
41264 + tmpReg32);
41265 +
41266 + /* Sets the Expiration Delay */
41267 + tmpReg32 = 0;
41268 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
41269 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
41270 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
41271 + tmpReg32);
41272 +
41273 + err = FmPcdRegisterReassmPort(p_FmPcd,
41274 + p_Manip->reassmParams.p_ReassCommonTbl);
41275 + if (err != E_OK)
41276 + {
41277 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41278 + p_Manip->reassmParams.p_ReassCommonTbl);
41279 + RETURN_ERROR(MAJOR, err, ("port registration"));
41280 + }
41281 +
41282 + return err;
41283 +}
41284 +
41285 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41286 +{
41287 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
41288 + uint32_t tmpReg32, autoLearnHashTblSize;
41289 + uint32_t numOfWays, setSize, setSizeCode, keySize;
41290 + uint32_t waySize, numOfSets, numOfEntries;
41291 + uint64_t tmpReg64;
41292 + uint16_t minFragSize;
41293 + uint16_t maxReassemSize;
41294 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
41295 + t_ReassTbl **p_ReassTbl;
41296 +
41297 + switch (hdr)
41298 + {
41299 + case HEADER_TYPE_IPv4:
41300 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
41301 + p_AutoLearnHashTblAddr =
41302 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
41303 + p_AutoLearnSetLockTblAddr =
41304 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
41305 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
41306 + maxReassemSize = 0;
41307 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
41308 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
41309 + break;
41310 + case HEADER_TYPE_IPv6:
41311 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
41312 + p_AutoLearnHashTblAddr =
41313 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
41314 + p_AutoLearnSetLockTblAddr =
41315 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
41316 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
41317 + maxReassemSize = 0;
41318 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
41319 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
41320 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
41321 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
41322 + break;
41323 + case HEADER_TYPE_CAPWAP:
41324 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
41325 + p_AutoLearnHashTblAddr =
41326 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
41327 + p_AutoLearnSetLockTblAddr =
41328 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
41329 + minFragSize = 0;
41330 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
41331 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
41332 + keySize = 4;
41333 + break;
41334 + default:
41335 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41336 + }
41337 + keySize += 2; /* 2 bytes reserved for RFDIndex */
41338 +#if (DPAA_VERSION >= 11)
41339 + keySize += 2; /* 2 bytes reserved */
41340 +#endif /* (DPAA_VERSION >= 11) */
41341 + waySize = ROUND_UP(keySize, 8);
41342 +
41343 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
41344 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
41345 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
41346 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
41347 + if (!*p_ReassTbl)
41348 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
41349 + ("MURAM alloc for Reassembly specific parameters table"));
41350 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
41351 +
41352 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
41353 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
41354 + - p_FmPcd->physicalMuramBase);
41355 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
41356 +
41357 + /* Calculate set size (set size is rounded-up to next power of 2) */
41358 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
41359 +
41360 + /* Get set size code */
41361 + LOG2(setSize, setSizeCode);
41362 +
41363 + /* Sets ways number and set size code */
41364 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
41365 + (uint16_t)((numOfWays << 8) | setSizeCode));
41366 +
41367 + /* It is recommended that the total number of entries in this table
41368 + (number of sets * number of ways) will be twice the number of frames that
41369 + are expected to be reassembled simultaneously.*/
41370 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
41371 +
41372 + /* sets number calculation - number of entries = number of sets * number of ways */
41373 + numOfSets = numOfEntries / numOfWays;
41374 +
41375 + /* Sets AutoLearnHashKeyMask*/
41376 + NEXT_POWER_OF_2(numOfSets, numOfSets);
41377 +
41378 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
41379 + (uint16_t)(numOfSets - 1));
41380 +
41381 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
41382 + The size of this table is determined by the number of sets and the set size.
41383 + Table size = set size * number of sets
41384 + This table base address should be aligned to SetSize.*/
41385 + autoLearnHashTblSize = numOfSets * setSize;
41386 +
41387 + *p_AutoLearnHashTblAddr =
41388 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
41389 + if (!*p_AutoLearnHashTblAddr)
41390 + {
41391 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
41392 + *p_ReassTbl = NULL;
41393 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
41394 + }
41395 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
41396 +
41397 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
41398 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41399 + & FM_PCD_MANIP_REASM_LIODN_MASK)
41400 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
41401 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41402 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
41403 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
41404 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
41405 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
41406 + (uint32_t)(tmpReg64 >> 32));
41407 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
41408 +
41409 + /* Allocation of the Set Lock table - This table resides in external memory
41410 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
41411 + This table resides in external memory and its base address should be 4-byte aligned */
41412 + *p_AutoLearnSetLockTblAddr =
41413 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
41414 + if (!*p_AutoLearnSetLockTblAddr)
41415 + {
41416 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
41417 + *p_ReassTbl = NULL;
41418 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
41419 + *p_AutoLearnHashTblAddr = 0;
41420 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
41421 + }
41422 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
41423 +
41424 + /* sets Set Lock table pointer and liodn offset*/
41425 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41426 + & FM_PCD_MANIP_REASM_LIODN_MASK)
41427 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
41428 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41429 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
41430 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
41431 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
41432 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
41433 + (uint32_t)(tmpReg64 >> 32));
41434 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
41435 +
41436 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
41437 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
41438 +
41439 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
41440 +
41441 + return E_OK;
41442 +}
41443 +
41444 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
41445 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41446 + t_Handle h_Ad, bool validate)
41447 +{
41448 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41449 + uint32_t tmpReg32;
41450 + t_Error err;
41451 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
41452 +#if (DPAA_VERSION >= 11)
41453 + t_FmPcdCtrlParamsPage *p_ParamsPage;
41454 +#endif /* (DPAA_VERSION >= 11) */
41455 +
41456 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41457 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
41458 + SANITY_CHECK_RETURN_ERROR(
41459 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
41460 + E_INVALID_STATE);
41461 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41462 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
41463 + E_INVALID_HANDLE);
41464 +
41465 + UNUSED(h_Ad);
41466 +
41467 + if (!p_Manip->updateParams)
41468 + return E_OK;
41469 +
41470 + if (p_Manip->h_FmPcd != h_FmPcd)
41471 + RETURN_ERROR(
41472 + MAJOR, E_INVALID_STATE,
41473 + ("handler of PCD previously was initiated by different value"));
41474 +
41475 + if (p_Manip->updateParams)
41476 + {
41477 + if ((!(p_Manip->updateParams
41478 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
41479 + || ((p_Manip->shadowUpdateParams
41480 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
41481 + RETURN_ERROR(
41482 + MAJOR, E_INVALID_STATE,
41483 + ("in this stage parameters from Port has not be updated"));
41484 +
41485 + fmPortGetSetCcParams.setCcParams.type = 0;
41486 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
41487 + {
41488 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
41489 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
41490 + }
41491 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
41492 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
41493 + != E_OK)
41494 + RETURN_ERROR(MAJOR, err, NO_MSG);
41495 + if (fmPortGetSetCcParams.getCcParams.type
41496 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
41497 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
41498 + ("offset of the data wasn't configured previously"));
41499 + if (p_Manip->updateParams
41500 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
41501 + {
41502 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
41503 + uint8_t *p_Ptr, i, totalNumOfTnums;
41504 +
41505 + totalNumOfTnums =
41506 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
41507 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
41508 +
41509 + p_Manip->reassmParams.internalBufferPoolAddr =
41510 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41511 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
41512 + BMI_FIFO_UNITS));
41513 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
41514 + RETURN_ERROR(
41515 + MAJOR, E_NO_MEMORY,
41516 + ("MURAM alloc for Reassembly internal buffers pool"));
41517 + MemSet8(
41518 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
41519 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
41520 +
41521 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
41522 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41523 + (uint32_t)(5 + totalNumOfTnums),
41524 + 4));
41525 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
41526 + RETURN_ERROR(
41527 + MAJOR,
41528 + E_NO_MEMORY,
41529 + ("MURAM alloc for Reassembly internal buffers management"));
41530 +
41531 + p_Ptr =
41532 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
41533 + WRITE_UINT32(
41534 + *(uint32_t*)p_Ptr,
41535 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
41536 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
41537 + WRITE_UINT8(*p_Ptr, i);
41538 + WRITE_UINT8(*p_Ptr, 0xFF);
41539 +
41540 + tmpReg32 =
41541 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
41542 + | ((uint32_t)(XX_VirtToPhys(
41543 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
41544 + - p_FmPcd->physicalMuramBase));
41545 + WRITE_UINT32(
41546 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
41547 + tmpReg32);
41548 +
41549 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
41550 + | DISCARD_MASK);
41551 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
41552 + | DISCARD_MASK);
41553 + }
41554 + }
41555 +
41556 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
41557 + {
41558 + if (p_Manip->reassmParams.capwap.h_Scheme)
41559 + {
41560 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
41561 + p_Manip->reassmParams.capwap.h_Scheme;
41562 + p_PcdParams->p_KgParams->numOfSchemes++;
41563 + }
41564 +
41565 + }
41566 + else
41567 + {
41568 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
41569 + {
41570 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
41571 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
41572 + p_PcdParams->p_KgParams->numOfSchemes++;
41573 + }
41574 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
41575 + {
41576 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
41577 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
41578 + p_PcdParams->p_KgParams->numOfSchemes++;
41579 + }
41580 +#if (DPAA_VERSION >= 11)
41581 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
41582 + {
41583 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
41584 + (void**)&p_ParamsPage)) != E_OK)
41585 + RETURN_ERROR(MAJOR, err, NO_MSG);
41586 +
41587 + tmpReg32 = NIA_ENG_KG;
41588 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
41589 + {
41590 + tmpReg32 |= NIA_KG_DIRECT;
41591 + tmpReg32 |= NIA_KG_CC_EN;
41592 + tmpReg32 |= FmPcdKgGetSchemeId(
41593 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
41594 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
41595 + }
41596 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
41597 + {
41598 + tmpReg32 &= ~NIA_AC_MASK;
41599 + tmpReg32 |= NIA_KG_DIRECT;
41600 + tmpReg32 |= NIA_KG_CC_EN;
41601 + tmpReg32 |= FmPcdKgGetSchemeId(
41602 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
41603 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
41604 + }
41605 + }
41606 +#else
41607 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
41608 + {
41609 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
41610 + fmPortGetSetCcParams.getCcParams.discardMask);
41611 + }
41612 +#endif /* (DPAA_VERSION >= 11) */
41613 + }
41614 + return E_OK;
41615 +}
41616 +
41617 +#if (DPAA_VERSION == 10)
41618 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
41619 +{
41620 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
41621 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
41622 + t_Error err;
41623 +
41624 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41625 +
41626 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
41627 +
41628 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
41629 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
41630 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
41631 + RETURN_ERROR(MAJOR, err, NO_MSG);
41632 +
41633 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
41634 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
41635 + "Failed to release %d buffers to the BM (missing FBPRs)",
41636 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
41637 +
41638 + return E_OK;
41639 +}
41640 +
41641 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
41642 +{
41643 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
41644 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
41645 + t_Error err;
41646 +
41647 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41648 +
41649 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
41650 +
41651 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
41652 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
41653 + RETURN_ERROR(MAJOR, err, NO_MSG);
41654 +
41655 + return E_OK;
41656 +}
41657 +#endif /* (DPAA_VERSION == 10) */
41658 +
41659 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
41660 +{
41661 + if (p_Manip->h_Ad)
41662 + {
41663 + if (p_Manip->muramAllocate)
41664 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
41665 + else
41666 + XX_Free(p_Manip->h_Ad);
41667 + p_Manip->h_Ad = NULL;
41668 + }
41669 + if (p_Manip->p_Template)
41670 + {
41671 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
41672 + p_Manip->p_Template = NULL;
41673 + }
41674 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
41675 + if (p_Manip->h_Frag)
41676 + {
41677 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
41678 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41679 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
41680 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
41681 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41682 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
41683 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
41684 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41685 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
41686 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
41687 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41688 + p_Manip->capwapFragParams.p_TimeOutTbl);
41689 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
41690 +
41691 + }
41692 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41693 + if (p_Manip->frag)
41694 + {
41695 + if (p_Manip->fragParams.p_Frag)
41696 + {
41697 +#if (DPAA_VERSION == 10)
41698 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
41699 +#endif /* (DPAA_VERSION == 10) */
41700 +
41701 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41702 + }
41703 + }
41704 + else
41705 + if (p_Manip->reassm)
41706 + {
41707 + FmPcdUnregisterReassmPort(p_FmPcd,
41708 + p_Manip->reassmParams.p_ReassCommonTbl);
41709 +
41710 + if (p_Manip->reassmParams.timeOutTblAddr)
41711 + FM_MURAM_FreeMem(
41712 + p_FmPcd->h_FmMuram,
41713 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
41714 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
41715 + XX_FreeSmart(
41716 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
41717 + if (p_Manip->reassmParams.p_ReassCommonTbl)
41718 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41719 + p_Manip->reassmParams.p_ReassCommonTbl);
41720 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
41721 + FM_MURAM_FreeMem(
41722 + p_FmPcd->h_FmMuram,
41723 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
41724 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
41725 + FM_MURAM_FreeMem(
41726 + p_FmPcd->h_FmMuram,
41727 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
41728 + if (p_Manip->reassmParams.internalBufferPoolAddr)
41729 + FM_MURAM_FreeMem(
41730 + p_FmPcd->h_FmMuram,
41731 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
41732 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
41733 + {
41734 +
41735 + }
41736 + else
41737 + {
41738 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
41739 + XX_FreeSmart(
41740 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
41741 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
41742 + XX_FreeSmart(
41743 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
41744 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
41745 + XX_FreeSmart(
41746 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
41747 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
41748 + XX_FreeSmart(
41749 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
41750 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41751 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41752 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
41753 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41754 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41755 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
41756 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
41757 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
41758 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
41759 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
41760 + }
41761 + }
41762 +
41763 + if (p_Manip->p_StatsTbl)
41764 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
41765 +}
41766 +
41767 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
41768 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
41769 +{
41770 + if (p_ManipParams->u.hdr.rmv)
41771 + {
41772 + switch (p_ManipParams->u.hdr.rmvParams.type)
41773 + {
41774 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
41775 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
41776 + {
41777 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
41778 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
41779 + {
41780 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
41781 + {
41782 + case (HEADER_TYPE_CAPWAP_DTLS) :
41783 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
41784 + p_Manip->muramAllocate = TRUE;
41785 + if (p_ManipParams->u.hdr.insrt)
41786 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
41787 + if (p_ManipParams->fragOrReasm)
41788 + {
41789 + if (!p_ManipParams->fragOrReasmParams.frag)
41790 + {
41791 + switch (p_ManipParams->fragOrReasmParams.hdr)
41792 + {
41793 + case (HEADER_TYPE_CAPWAP):
41794 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
41795 + break;
41796 + default:
41797 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
41798 + }
41799 + }
41800 + else
41801 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
41802 + }
41803 + break;
41804 + default:
41805 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
41806 + }
41807 + }
41808 + else
41809 + {
41810 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
41811 + {
41812 + case (HEADER_TYPE_CAPWAP_DTLS) :
41813 + case (HEADER_TYPE_CAPWAP) :
41814 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
41815 + 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"));
41816 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
41817 + p_Manip->muramAllocate = TRUE;
41818 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
41819 + break;
41820 + default :
41821 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
41822 + }
41823 + }
41824 + break;
41825 + default :
41826 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
41827 + }
41828 + break;
41829 + default:
41830 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
41831 + }
41832 + }
41833 + else if (p_ManipParams->u.hdr.insrt)
41834 + {
41835 + switch (p_ManipParams->u.hdr.insrtParams.type)
41836 + {
41837 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
41838 +
41839 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41840 + p_Manip->muramAllocate = FALSE;
41841 + if (p_ManipParams->fragOrReasm)
41842 + {
41843 + if (p_ManipParams->fragOrReasmParams.frag)
41844 + {
41845 + switch (p_ManipParams->fragOrReasmParams.hdr)
41846 + {
41847 + case (HEADER_TYPE_CAPWAP):
41848 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
41849 + break;
41850 + default:
41851 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
41852 + }
41853 + }
41854 + else
41855 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
41856 + }
41857 + break;
41858 +
41859 + default:
41860 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
41861 + }
41862 + }
41863 + else if (p_ManipParams->fragOrReasm)
41864 + {
41865 + if (p_ManipParams->fragOrReasmParams.frag)
41866 + {
41867 + switch (p_ManipParams->fragOrReasmParams.hdr)
41868 + {
41869 + case (HEADER_TYPE_CAPWAP):
41870 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
41871 + p_Manip->muramAllocate = FALSE;
41872 + break;
41873 + default:
41874 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
41875 + }
41876 + }
41877 + else
41878 + {
41879 + switch (p_ManipParams->fragOrReasmParams.hdr)
41880 + {
41881 + case (HEADER_TYPE_CAPWAP):
41882 + 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"));
41883 + default:
41884 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
41885 + }
41886 + }
41887 +
41888 + }
41889 + else
41890 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
41891 +
41892 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
41893 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
41894 +
41895 + return E_OK;
41896 +}
41897 +
41898 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41899 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
41900 + t_FmPcdManipParams *p_ManipParams)
41901 +{
41902 + switch (p_ManipParams->type)
41903 + {
41904 + case e_FM_PCD_MANIP_HDR:
41905 + /* Check that next-manip is not already used */
41906 + if (p_ManipParams->h_NextManip)
41907 + {
41908 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
41909 + RETURN_ERROR(
41910 + MAJOR, E_INVALID_STATE,
41911 + ("h_NextManip is already a part of another chain"));
41912 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
41913 + != e_FM_PCD_MANIP_HDR) &&
41914 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
41915 + != e_FM_PCD_MANIP_FRAG))
41916 + RETURN_ERROR(
41917 + MAJOR,
41918 + E_NOT_SUPPORTED,
41919 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
41920 + }
41921 +
41922 + if (p_ManipParams->u.hdr.rmv)
41923 + {
41924 + switch (p_ManipParams->u.hdr.rmvParams.type)
41925 + {
41926 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
41927 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
41928 + {
41929 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
41930 + break;
41931 +#if (DPAA_VERSION >= 11)
41932 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
41933 + break;
41934 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
41935 + {
41936 + t_Error err;
41937 + uint8_t prsArrayOffset;
41938 +
41939 + err =
41940 + GetPrOffsetByHeaderOrField(
41941 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
41942 + &prsArrayOffset);
41943 + if (err)
41944 + RETURN_ERROR(MAJOR, err, NO_MSG);
41945 + break;
41946 + }
41947 +#endif /* (DPAA_VERSION >= 11) */
41948 + default:
41949 + RETURN_ERROR(
41950 + MAJOR,
41951 + E_INVALID_STATE,
41952 + ("invalid type of remove manipulation"));
41953 + }
41954 + break;
41955 + case (e_FM_PCD_MANIP_RMV_GENERIC):
41956 + break;
41957 + default:
41958 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
41959 + ("invalid type of remove manipulation"));
41960 + }
41961 + p_Manip->opcode = HMAN_OC;
41962 + p_Manip->muramAllocate = TRUE;
41963 + p_Manip->rmv = TRUE;
41964 + }
41965 + else
41966 + if (p_ManipParams->u.hdr.insrt)
41967 + {
41968 + switch (p_ManipParams->u.hdr.insrtParams.type)
41969 + {
41970 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
41971 + {
41972 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
41973 + {
41974 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
41975 + /* nothing to check */
41976 + break;
41977 +#if (DPAA_VERSION >= 11)
41978 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
41979 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
41980 + % 4)
41981 + RETURN_ERROR(
41982 + MAJOR,
41983 + E_INVALID_VALUE,
41984 + ("IP inserted header must be of size which is a multiple of four bytes"));
41985 + break;
41986 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
41987 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
41988 + % 4)
41989 + RETURN_ERROR(
41990 + MAJOR,
41991 + E_INVALID_VALUE,
41992 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
41993 + break;
41994 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
41995 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
41996 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
41997 + != 8)
41998 + RETURN_ERROR(
41999 + MAJOR,
42000 + E_INVALID_VALUE,
42001 + ("Inserted header must be of size 8"));
42002 + break;
42003 +#endif /* (DPAA_VERSION >= 11) */
42004 + default:
42005 + RETURN_ERROR(
42006 + MAJOR,
42007 + E_INVALID_STATE,
42008 + ("unsupported insert by header type"));
42009 + }
42010 + }
42011 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
42012 + break;
42013 + default:
42014 + RETURN_ERROR(
42015 + MAJOR,
42016 + E_INVALID_STATE,
42017 + ("for only insert manipulation unsupported type"));
42018 + }
42019 + p_Manip->opcode = HMAN_OC;
42020 + p_Manip->muramAllocate = TRUE;
42021 + p_Manip->insrt = TRUE;
42022 + }
42023 + else
42024 + if (p_ManipParams->u.hdr.fieldUpdate)
42025 + {
42026 + /* Check parameters */
42027 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
42028 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
42029 + {
42030 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
42031 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
42032 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
42033 + > 7))
42034 + RETURN_ERROR(
42035 + MAJOR, E_INVALID_VALUE,
42036 + ("vpri should get values of 0-7 "));
42037 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
42038 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
42039 + {
42040 + int i;
42041 +
42042 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
42043 + > 7)
42044 + RETURN_ERROR(
42045 + MAJOR,
42046 + E_INVALID_VALUE,
42047 + ("vpriDefVal should get values of 0-7 "));
42048 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
42049 + i++)
42050 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
42051 + & 0xf0)
42052 + RETURN_ERROR(
42053 + MAJOR,
42054 + E_INVALID_VALUE,
42055 + ("dscpToVpriTabl value out of range (0-15)"));
42056 + }
42057 +
42058 + }
42059 +
42060 + p_Manip->opcode = HMAN_OC;
42061 + p_Manip->muramAllocate = TRUE;
42062 + p_Manip->fieldUpdate = TRUE;
42063 + }
42064 + else
42065 + if (p_ManipParams->u.hdr.custom)
42066 + {
42067 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
42068 + {
42069 +
42070 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
42071 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
42072 + RETURN_ERROR(
42073 + MAJOR, E_INVALID_VALUE,
42074 + ("size should get values of 1-8 "));
42075 +
42076 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
42077 + RETURN_ERROR(
42078 + MAJOR, E_INVALID_VALUE,
42079 + ("srcOffset should be <= 7"));
42080 +
42081 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
42082 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
42083 + RETURN_ERROR(
42084 + MAJOR, E_INVALID_VALUE,
42085 + ("(srcOffset + size) should be <= 8"));
42086 +
42087 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
42088 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
42089 + RETURN_ERROR(
42090 + MAJOR, E_INVALID_VALUE,
42091 + ("(dstOffset + size) should be <= 256"));
42092 +
42093 + }
42094 +
42095 + p_Manip->opcode = HMAN_OC;
42096 + p_Manip->muramAllocate = TRUE;
42097 + p_Manip->custom = TRUE;
42098 + }
42099 + break;
42100 + case e_FM_PCD_MANIP_REASSEM:
42101 + if (p_ManipParams->h_NextManip)
42102 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42103 + ("next manip with reassembly"));
42104 + switch (p_ManipParams->u.reassem.hdr)
42105 + {
42106 + case (HEADER_TYPE_IPv4):
42107 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
42108 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
42109 + break;
42110 + case (HEADER_TYPE_IPv6):
42111 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
42112 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
42113 + break;
42114 +#if (DPAA_VERSION >= 11)
42115 + case (HEADER_TYPE_CAPWAP):
42116 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
42117 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
42118 + break;
42119 +#endif /* (DPAA_VERSION >= 11) */
42120 + default:
42121 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42122 + ("header for reassembly"));
42123 + }
42124 + break;
42125 + case e_FM_PCD_MANIP_FRAG:
42126 + if (p_ManipParams->h_NextManip)
42127 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42128 + ("next manip with fragmentation"));
42129 + switch (p_ManipParams->u.frag.hdr)
42130 + {
42131 + case (HEADER_TYPE_IPv4):
42132 + case (HEADER_TYPE_IPv6):
42133 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
42134 + break;
42135 +#if (DPAA_VERSION >= 11)
42136 + case (HEADER_TYPE_CAPWAP):
42137 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
42138 + break;
42139 +#endif /* (DPAA_VERSION >= 11) */
42140 + default:
42141 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42142 + ("header for fragmentation"));
42143 + }
42144 + p_Manip->muramAllocate = TRUE;
42145 + break;
42146 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
42147 + switch (p_ManipParams->u.specialOffload.type)
42148 + {
42149 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
42150 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
42151 + p_Manip->muramAllocate = TRUE;
42152 + break;
42153 +#if (DPAA_VERSION >= 11)
42154 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
42155 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
42156 + p_Manip->muramAllocate = TRUE;
42157 + break;
42158 +#endif /* (DPAA_VERSION >= 11) */
42159 + default:
42160 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42161 + ("special offload type"));
42162 + }
42163 + break;
42164 + default:
42165 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
42166 + }
42167 +
42168 + return E_OK;
42169 +}
42170 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42171 +
42172 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42173 +
42174 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
42175 + t_Handle h_FmPort,
42176 + t_FmPcdManip *p_Manip)
42177 +{
42178 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42179 + uint32_t tmpReg32 = 0;
42180 + t_AdOfTypeContLookup *p_Ad;
42181 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42182 + t_Error err;
42183 +
42184 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
42185 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42186 +
42187 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42188 + if (p_Manip->h_FmPcd != h_FmPcd)
42189 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
42190 + ("handler of PCD previously was initiated by different value"));
42191 +
42192 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
42193 +
42194 + if (!p_Manip->p_StatsTbl)
42195 + {
42196 +
42197 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
42198 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
42199 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
42200 + if (err)
42201 + RETURN_ERROR(MAJOR, err, NO_MSG);
42202 +
42203 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
42204 +
42205 + p_Manip->p_StatsTbl =
42206 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42207 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
42208 + 4);
42209 + if (!p_Manip->p_StatsTbl)
42210 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
42211 +
42212 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
42213 +
42214 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
42215 +
42216 + if (p_Manip->cnia)
42217 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
42218 +
42219 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
42220 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42221 + }
42222 + else
42223 + {
42224 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
42225 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
42226 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
42227 + if (err)
42228 + RETURN_ERROR(MAJOR, err, NO_MSG);
42229 + }
42230 +
42231 + return E_OK;
42232 +}
42233 +
42234 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
42235 +{
42236 + t_AdOfTypeContLookup *p_Ad;
42237 + uint32_t tmpReg32 = 0;
42238 + uint8_t prsArrayOffset = 0;
42239 + t_Error err;
42240 +
42241 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
42242 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
42243 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42244 +
42245 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42246 + if (p_Manip->rmv)
42247 + {
42248 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
42249 + if (err)
42250 + RETURN_ERROR(MAJOR, err, NO_MSG);
42251 +
42252 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
42253 + tmpReg32 |= HMAN_RMV_HDR;
42254 + }
42255 +
42256 + if (p_Manip->insrt)
42257 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
42258 +
42259 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
42260 +
42261 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42262 +
42263 + tmpReg32 = 0;
42264 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42265 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42266 +
42267 + return E_OK;
42268 +}
42269 +
42270 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
42271 + bool caamUsed)
42272 +{
42273 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42274 + uint32_t tmpReg32 = 0;
42275 +
42276 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
42277 +
42278 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
42279 +
42280 + tmpReg32 = 0;
42281 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42282 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
42283 +
42284 + tmpReg32 = 0;
42285 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
42286 + tmpReg32 |= (uint32_t)0x16 << 16;
42287 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
42288 +
42289 + if (caamUsed)
42290 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
42291 +
42292 + return E_OK;
42293 +}
42294 +
42295 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
42296 +{
42297 + t_AdOfTypeContLookup *p_Ad;
42298 + uint32_t tmpReg32 = 0;
42299 + t_Error err = E_OK;
42300 +
42301 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42302 +
42303 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42304 +
42305 + tmpReg32 = 0;
42306 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
42307 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42308 +
42309 + tmpReg32 = 0;
42310 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42311 +
42312 +
42313 + if (p_Manip->h_Frag)
42314 + {
42315 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
42316 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
42317 + }
42318 +
42319 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42320 +
42321 + return err;
42322 +}
42323 +
42324 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
42325 + t_FmPcdManip *p_Manip,
42326 + t_FmPcd *p_FmPcd,
42327 + uint8_t poolId)
42328 +{
42329 + t_Handle p_Table;
42330 + uint32_t tmpReg32 = 0;
42331 + int i = 0;
42332 + uint8_t log2Num;
42333 + uint8_t numOfSets;
42334 + uint32_t j = 0;
42335 + uint32_t bitFor1Micro;
42336 +
42337 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
42338 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
42339 +
42340 + if (!p_FmPcd->h_Hc)
42341 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
42342 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
42343 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
42344 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
42345 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
42346 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
42347 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
42348 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
42349 + {
42350 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
42351 + (p_ManipParams->maxNumFramesInProcess > 512))
42352 + 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"));
42353 + }
42354 + else
42355 + {
42356 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
42357 + (p_ManipParams->maxNumFramesInProcess > 2048))
42358 + 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"));
42359 + }
42360 +
42361 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
42362 + if (bitFor1Micro == 0)
42363 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
42364 +
42365 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
42366 +
42367 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42368 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
42369 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
42370 + if (!p_Manip->h_Frag)
42371 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
42372 +
42373 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
42374 +
42375 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
42376 +
42377 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
42378 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42379 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
42380 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
42381 +
42382 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
42383 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
42384 +
42385 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
42386 +
42387 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
42388 +
42389 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
42390 +
42391 + tmpReg32 = 0;
42392 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
42393 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
42394 + if (p_ManipParams->haltOnDuplicationFrag)
42395 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
42396 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
42397 + {
42398 + i = 8;
42399 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
42400 + }
42401 + else
42402 + i = 4;
42403 +
42404 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
42405 + LOG2(numOfSets, log2Num);
42406 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
42407 +
42408 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
42409 +
42410 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
42411 + if (((j / i) % 2)== 0)
42412 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
42413 +
42414 + tmpReg32 = 0x00008000;
42415 + tmpReg32 |= (uint32_t)poolId << 16;
42416 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
42417 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
42418 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
42419 +
42420 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
42421 +
42422 + p_Manip->capwapFragParams.sgBpid = poolId;
42423 +
42424 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
42425 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
42426 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
42427 +
42428 + tmpReg32 = 0;
42429 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
42430 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
42431 +
42432 + return E_OK;
42433 +}
42434 +
42435 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
42436 + t_FmPcdManip *p_Manip,
42437 + t_FmPcd *p_FmPcd,
42438 + uint8_t poolId)
42439 +{
42440 + t_AdOfTypeContLookup *p_Ad;
42441 + uint32_t tmpReg32 = 0;
42442 +
42443 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42444 +
42445 + p_Manip->updateParams |= OFFSET_OF_DATA;
42446 +
42447 + p_Manip->frag = TRUE;
42448 +
42449 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42450 + FM_PCD_CC_AD_ENTRY_SIZE,
42451 + FM_PCD_CC_AD_TABLE_ALIGN);
42452 + if (!p_Manip->h_Frag)
42453 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
42454 +
42455 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42456 +
42457 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
42458 +
42459 + tmpReg32 = 0;
42460 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42461 +
42462 + if (p_ManipParams->headerOptionsCompr)
42463 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
42464 + tmpReg32 |= ((uint32_t)poolId << 8);
42465 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42466 +
42467 + tmpReg32 = 0;
42468 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42469 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42470 +
42471 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42472 + p_Manip->capwapFragParams.sgBpid = poolId;
42473 +
42474 + return E_OK;
42475 +}
42476 +
42477 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
42478 +{
42479 + t_AdOfTypeContLookup *p_Ad;
42480 + uint32_t tmpReg32 = 0;
42481 +
42482 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42483 +
42484 + UNUSED(p_FmPcd);
42485 +
42486 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42487 +
42488 + tmpReg32 = 0;
42489 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
42490 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
42491 + tmpReg32 |= (uint32_t)0x16 << 16;
42492 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42493 +
42494 + tmpReg32 = 0;
42495 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42496 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42497 +
42498 + return E_OK;
42499 +}
42500 +
42501 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
42502 +{
42503 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
42504 + uint8_t tmpReg8 = 0xff;
42505 + t_AdOfTypeContLookup *p_Ad;
42506 + bool ipModify = FALSE;
42507 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
42508 + uint16_t tmpReg16 = 0;
42509 + t_Error err = E_OK;
42510 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
42511 + uint8_t *p_Template = NULL;
42512 +
42513 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
42514 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
42515 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42516 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
42517 +
42518 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42519 + if (p_Manip->insrt)
42520 + {
42521 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
42522 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
42523 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
42524 +
42525 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
42526 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
42527 +
42528 + if (p_InsrtByTemplate->size > 128)
42529 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
42530 +
42531 + if (p_InsrtByTemplate->size)
42532 + {
42533 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42534 + p_InsrtByTemplate->size,
42535 + FM_PCD_CC_AD_TABLE_ALIGN);
42536 + if(!p_Manip->p_Template)
42537 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
42538 +
42539 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
42540 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
42541 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
42542 + }
42543 +
42544 + tmpReg32 = 0;
42545 +
42546 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
42547 +
42548 + if (!p_Template)
42549 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
42550 +
42551 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
42552 +
42553 + if (p_InsrtByTemplate->modifyOuterIp)
42554 + {
42555 + ipModify = TRUE;
42556 +
42557 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
42558 +
42559 + if((tmpReg8 & 0xf0) == 0x40)
42560 + tmpReg8 = 4;
42561 + else if((tmpReg8 & 0xf0) == 0x60)
42562 + tmpReg8 = 6;
42563 + else
42564 + tmpReg8 = 0xff;
42565 +
42566 + if (tmpReg8 != 0xff)
42567 + {
42568 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
42569 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
42570 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
42571 + {
42572 +
42573 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
42574 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
42575 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
42576 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
42577 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
42578 + /*IP header template - IP totalLength -
42579 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
42580 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
42581 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
42582 + }
42583 + if (blockSize)
42584 + {
42585 + if (!POWER_OF_2(blockSize))
42586 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
42587 + }
42588 +
42589 + }
42590 + if (tmpReg8 == 4)
42591 + {
42592 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
42593 + 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"));
42594 +
42595 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
42596 +
42597 + if (blockSize)
42598 + blockSize -= 1;
42599 +
42600 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
42601 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
42602 +
42603 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
42604 + 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
42605 +
42606 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
42607 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
42608 +
42609 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
42610 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
42611 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
42612 +
42613 + /*UDP checksum has to be 0*/
42614 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
42615 + {
42616 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
42617 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
42618 +
42619 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
42620 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
42621 +
42622 + }
42623 +
42624 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
42625 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
42626 +
42627 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
42628 + }
42629 + else if (tmpReg8 == 6)
42630 + {
42631 + /*TODO - add check for maximum value of blockSize;*/
42632 + if (blockSize)
42633 + LOG2(blockSize, log2Num);
42634 + tmpRegNia |= (uint32_t)log2Num << 24;
42635 +
42636 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
42637 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
42638 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
42639 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
42640 + {
42641 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
42642 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
42643 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
42644 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
42645 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
42646 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
42647 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
42648 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
42649 + }
42650 + }
42651 + else
42652 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
42653 + }
42654 +
42655 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
42656 + /*TODO - check it*/
42657 + if (p_InsrtByTemplate->modifyOuterVlan)
42658 + {
42659 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
42660 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
42661 +
42662 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
42663 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
42664 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
42665 +
42666 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
42667 + tmpReg8 &= 0x1f;
42668 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
42669 +
42670 + p_Template[14] = tmpReg8;
42671 + }
42672 +
42673 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
42674 +
42675 + XX_Free(p_Template);
42676 + }
42677 +
42678 + tmpReg32 = 0;
42679 + if (p_Manip->h_Frag)
42680 + {
42681 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
42682 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
42683 + }
42684 + else
42685 + tmpReg32 = 0xffff0000;
42686 +
42687 + if (ipModify)
42688 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
42689 + else
42690 + tmpReg32 |= (uint32_t)0x0000ff00;
42691 +
42692 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
42693 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
42694 +
42695 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42696 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
42697 +
42698 + return err;
42699 +}
42700 +
42701 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
42702 +{
42703 +
42704 + switch (p_StatsParams->type)
42705 + {
42706 + case (e_FM_PCD_STATS_PER_FLOWID):
42707 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
42708 + p_Manip->muramAllocate = TRUE;
42709 + break;
42710 + default:
42711 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
42712 + }
42713 +
42714 + return E_OK;
42715 +}
42716 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42717 +
42718 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
42719 +{
42720 + t_AdOfTypeContLookup *p_Ad;
42721 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
42722 + uint32_t tmpReg32;
42723 + t_Error err = E_OK;
42724 +
42725 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
42726 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
42727 + two separate IP Reassembly Parameter tables are required.*/
42728 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
42729 + RETURN_ERROR(MAJOR, err, NO_MSG);
42730 +
42731 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
42732 + tmpReg32 = 0;
42733 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42734 +
42735 + /* Gets the required Action descriptor table pointer */
42736 + switch (hdr)
42737 + {
42738 + case HEADER_TYPE_IPv4:
42739 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
42740 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
42741 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
42742 + - (p_FmPcd->physicalMuramBase));
42743 + break;
42744 + case HEADER_TYPE_IPv6:
42745 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
42746 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
42747 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
42748 + - (p_FmPcd->physicalMuramBase));
42749 + break;
42750 + case HEADER_TYPE_CAPWAP:
42751 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
42752 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
42753 + p_Manip->reassmParams.capwap.p_ReassTbl)
42754 + - (p_FmPcd->physicalMuramBase));
42755 + break;
42756 + default:
42757 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
42758 + }
42759 +
42760 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42761 +
42762 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
42763 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
42764 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
42765 +
42766 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
42767 + {
42768 +#if (DPAA_VERSION == 10)
42769 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
42770 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
42771 +#endif /* (DPAA_VERSION == 10) */
42772 +#if (DPAA_VERSION >= 11)
42773 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
42774 + {
42775 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
42776 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
42777 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
42778 + }
42779 +#endif /* (DPAA_VERSION >= 11) */
42780 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
42781 + tmpReg32 = 0;
42782 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
42783 + }
42784 +#if (DPAA_VERSION >= 11)
42785 + else
42786 + if (hdr == HEADER_TYPE_CAPWAP)
42787 + {
42788 + tmpReg32 = 0;
42789 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
42790 + }
42791 +#endif /* (DPAA_VERSION >= 11) */
42792 +
42793 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42794 +
42795 + p_Manip->reassm = TRUE;
42796 +
42797 + return E_OK;
42798 +}
42799 +
42800 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
42801 +{
42802 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
42803 +
42804 + /* Allocation if IPv4 Action descriptor */
42805 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
42806 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
42807 + FM_PCD_CC_AD_TABLE_ALIGN);
42808 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
42809 + {
42810 + ReleaseManipHandler(p_Manip, p_FmPcd);
42811 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42812 + ("Allocation of IPv4 table descriptor"));
42813 + }
42814 +
42815 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42816 +
42817 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
42818 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
42819 +}
42820 +
42821 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
42822 +{
42823 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
42824 +
42825 + /* Allocation if IPv6 Action descriptor */
42826 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
42827 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
42828 + FM_PCD_CC_AD_TABLE_ALIGN);
42829 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
42830 + {
42831 + ReleaseManipHandler(p_Manip, p_FmPcd);
42832 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42833 + ("Allocation of IPv6 table descriptor"));
42834 + }
42835 +
42836 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42837 +
42838 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
42839 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
42840 +}
42841 +
42842 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
42843 + t_FmPcdManip *p_Manip)
42844 +{
42845 + uint32_t maxSetNumber = 10000;
42846 + t_FmPcdManipReassemIpParams reassmManipParams =
42847 + p_ManipReassmParams->u.ipReassem;
42848 + t_Error res;
42849 +
42850 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
42851 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
42852 + E_INVALID_HANDLE);
42853 +
42854 + /* Check validation of user's parameter.*/
42855 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
42856 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
42857 + RETURN_ERROR(
42858 + MAJOR, E_INVALID_VALUE,
42859 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
42860 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
42861 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
42862 + if (reassmManipParams.maxNumFramesInProcess
42863 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
42864 + RETURN_ERROR(
42865 + MAJOR,
42866 + E_INVALID_VALUE,
42867 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
42868 +
42869 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
42870 + && (reassmManipParams.minFragSize[1] < 256))
42871 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
42872 +
42873 + /* Saves user's reassembly manipulation parameters */
42874 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
42875 + reassmManipParams.relativeSchemeId[0];
42876 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
42877 + reassmManipParams.relativeSchemeId[1];
42878 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
42879 + reassmManipParams.numOfFramesPerHashEntry[0];
42880 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
42881 + reassmManipParams.numOfFramesPerHashEntry[1];
42882 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
42883 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
42884 + p_Manip->reassmParams.maxNumFramesInProcess =
42885 + reassmManipParams.maxNumFramesInProcess;
42886 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
42887 + p_Manip->reassmParams.fqidForTimeOutFrames =
42888 + reassmManipParams.fqidForTimeOutFrames;
42889 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
42890 + reassmManipParams.timeoutThresholdForReassmProcess;
42891 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
42892 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
42893 +#if (DPAA_VERSION == 10)
42894 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
42895 +#endif /* (DPAA_VERSION == 10) */
42896 +#if (DPAA_VERSION >= 11)
42897 + if (reassmManipParams.nonConsistentSpFqid != 0)
42898 + {
42899 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
42900 + reassmManipParams.nonConsistentSpFqid;
42901 + }
42902 +#endif /* (DPAA_VERSION >= 11) */
42903 +
42904 + /* Creates and initializes the IP Reassembly common parameter table */
42905 + CreateReassCommonTable(p_Manip);
42906 +
42907 + /* Creation of IPv4 reassembly manipulation */
42908 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
42909 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
42910 + {
42911 + res = SetIpv4ReassmManip(p_Manip);
42912 + if (res != E_OK)
42913 + return res;
42914 + }
42915 +
42916 + /* Creation of IPv6 reassembly manipulation */
42917 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
42918 + {
42919 + res = SetIpv6ReassmManip(p_Manip);
42920 + if (res != E_OK)
42921 + return res;
42922 + }
42923 +
42924 + return E_OK;
42925 +}
42926 +
42927 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
42928 + t_FmPcdKgSchemeParams *p_Scheme,
42929 + t_Handle h_CcTree, bool ipv4,
42930 + uint8_t groupId)
42931 +{
42932 + uint32_t j;
42933 + uint8_t res;
42934 +
42935 + /* Configures scheme's network environment parameters */
42936 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
42937 + if (ipv4)
42938 + res = FmPcdNetEnvGetUnitId(
42939 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
42940 + HEADER_TYPE_IPv4, FALSE, 0);
42941 + else
42942 + res = FmPcdNetEnvGetUnitId(
42943 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
42944 + HEADER_TYPE_IPv6, FALSE, 0);
42945 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
42946 + p_Scheme->netEnvParams.unitIds[0] = res;
42947 +
42948 + res = FmPcdNetEnvGetUnitId(
42949 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
42950 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
42951 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
42952 + p_Scheme->netEnvParams.unitIds[1] = res;
42953 +
42954 + /* Configures scheme's next engine parameters*/
42955 + p_Scheme->nextEngine = e_FM_PCD_CC;
42956 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
42957 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
42958 + p_Scheme->useHash = TRUE;
42959 +
42960 + /* Configures scheme's key*/
42961 + if (ipv4 == TRUE)
42962 + {
42963 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
42964 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
42965 + e_FM_PCD_EXTRACT_BY_HDR;
42966 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
42967 + e_FM_PCD_EXTRACT_FULL_FIELD;
42968 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
42969 + HEADER_TYPE_IPv4;
42970 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
42971 + NET_HEADER_FIELD_IPv4_DST_IP;
42972 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
42973 + e_FM_PCD_EXTRACT_BY_HDR;
42974 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
42975 + e_FM_PCD_EXTRACT_FULL_FIELD;
42976 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
42977 + HEADER_TYPE_IPv4;
42978 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
42979 + NET_HEADER_FIELD_IPv4_SRC_IP;
42980 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
42981 + e_FM_PCD_EXTRACT_BY_HDR;
42982 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
42983 + e_FM_PCD_EXTRACT_FULL_FIELD;
42984 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
42985 + HEADER_TYPE_IPv4;
42986 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
42987 + NET_HEADER_FIELD_IPv4_PROTO;
42988 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
42989 + e_FM_PCD_EXTRACT_BY_HDR;
42990 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
42991 + HEADER_TYPE_IPv4;
42992 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
42993 + e_FM_PCD_EXTRACT_FROM_HDR;
42994 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
42995 + FALSE;
42996 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
42997 + 2;
42998 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
42999 + 4;
43000 + }
43001 + else /* IPv6 */
43002 + {
43003 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
43004 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
43005 + e_FM_PCD_EXTRACT_BY_HDR;
43006 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
43007 + e_FM_PCD_EXTRACT_FULL_FIELD;
43008 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
43009 + HEADER_TYPE_IPv6;
43010 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
43011 + NET_HEADER_FIELD_IPv6_DST_IP;
43012 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
43013 + e_FM_PCD_EXTRACT_BY_HDR;
43014 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
43015 + e_FM_PCD_EXTRACT_FULL_FIELD;
43016 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
43017 + HEADER_TYPE_IPv6;
43018 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
43019 + NET_HEADER_FIELD_IPv6_SRC_IP;
43020 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
43021 + e_FM_PCD_EXTRACT_BY_HDR;
43022 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
43023 + HEADER_TYPE_USER_DEFINED_SHIM2;
43024 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
43025 + e_FM_PCD_EXTRACT_FROM_HDR;
43026 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
43027 + 4;
43028 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
43029 + 4;
43030 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
43031 + TRUE;
43032 + }
43033 +
43034 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
43035 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
43036 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
43037 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
43038 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
43039 + {
43040 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
43041 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
43042 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
43043 + e_FM_PCD_KG_DFLT_GBL_0;
43044 + }
43045 +}
43046 +
43047 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
43048 + t_FmPcdManipReassemIpStats *p_Stats)
43049 +{
43050 + ASSERT_COND(p_Manip);
43051 + ASSERT_COND(p_Stats);
43052 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
43053 +
43054 + p_Stats->timeout =
43055 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
43056 + p_Stats->rfdPoolBusy =
43057 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
43058 + p_Stats->internalBufferBusy =
43059 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
43060 + p_Stats->externalBufferBusy =
43061 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
43062 + p_Stats->sgFragments =
43063 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
43064 + p_Stats->dmaSemaphoreDepletion =
43065 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
43066 +#if (DPAA_VERSION >= 11)
43067 + p_Stats->nonConsistentSp =
43068 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
43069 +#endif /* (DPAA_VERSION >= 11) */
43070 +
43071 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
43072 + {
43073 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
43074 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
43075 + p_Stats->specificHdrStatistics[0].validFragments =
43076 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
43077 + p_Stats->specificHdrStatistics[0].processedFragments =
43078 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
43079 + p_Stats->specificHdrStatistics[0].malformedFragments =
43080 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
43081 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
43082 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
43083 + p_Stats->specificHdrStatistics[0].discardedFragments =
43084 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
43085 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
43086 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
43087 + }
43088 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
43089 + {
43090 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
43091 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
43092 + p_Stats->specificHdrStatistics[1].validFragments =
43093 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
43094 + p_Stats->specificHdrStatistics[1].processedFragments =
43095 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
43096 + p_Stats->specificHdrStatistics[1].malformedFragments =
43097 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
43098 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
43099 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
43100 + p_Stats->specificHdrStatistics[1].discardedFragments =
43101 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
43102 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
43103 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
43104 + }
43105 + return E_OK;
43106 +}
43107 +
43108 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
43109 + t_FmPcdManipFragIpStats *p_Stats)
43110 +{
43111 + t_AdOfTypeContLookup *p_Ad;
43112 +
43113 + ASSERT_COND(p_Manip);
43114 + ASSERT_COND(p_Stats);
43115 + ASSERT_COND(p_Manip->h_Ad);
43116 + ASSERT_COND(p_Manip->fragParams.p_Frag);
43117 +
43118 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43119 +
43120 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
43121 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
43122 + & 0x00ffffff;
43123 + p_Stats->generatedFragments =
43124 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
43125 +
43126 + return E_OK;
43127 +}
43128 +
43129 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
43130 + t_FmPcdManip *p_Manip)
43131 +{
43132 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
43133 + t_FmPcd *p_FmPcd;
43134 +#if (DPAA_VERSION == 10)
43135 + t_Error err = E_OK;
43136 +#endif /* (DPAA_VERSION == 10) */
43137 +
43138 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
43139 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
43140 + E_INVALID_VALUE);
43141 +
43142 + p_FmPcd = p_Manip->h_FmPcd;
43143 + /* Allocation of fragmentation Action Descriptor */
43144 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
43145 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
43146 + FM_PCD_CC_AD_TABLE_ALIGN);
43147 + if (!p_Manip->fragParams.p_Frag)
43148 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43149 + ("MURAM alloc for Fragmentation table descriptor"));
43150 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43151 +
43152 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
43153 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
43154 +
43155 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
43156 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
43157 + ccAdBaseReg |= (p_ManipParams->dontFragAction
43158 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
43159 +
43160 +
43161 + /* Set Scatter/Gather BPid */
43162 + if (p_ManipParams->sgBpidEn)
43163 + {
43164 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
43165 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
43166 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
43167 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
43168 + }
43169 +
43170 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
43171 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
43172 + - p_FmPcd->physicalMuramBase);
43173 +#if (DPAA_VERSION == 10)
43174 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
43175 +#else
43176 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
43177 +#endif /* (DPAA_VERSION == 10) */
43178 +
43179 + /* Set all Ad registers */
43180 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
43181 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
43182 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
43183 +
43184 + /* Saves user's fragmentation manipulation parameters */
43185 + p_Manip->frag = TRUE;
43186 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
43187 +
43188 +#if (DPAA_VERSION == 10)
43189 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
43190 +
43191 + /* scratch buffer pool initialization */
43192 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
43193 + {
43194 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
43195 + p_Manip->fragParams.p_Frag = NULL;
43196 + RETURN_ERROR(MAJOR, err, NO_MSG);
43197 + }
43198 +#endif /* (DPAA_VERSION == 10) */
43199 +
43200 + return E_OK;
43201 +}
43202 +
43203 +static t_Error IPManip(t_FmPcdManip *p_Manip)
43204 +{
43205 + t_Error err = E_OK;
43206 + t_FmPcd *p_FmPcd;
43207 + t_AdOfTypeContLookup *p_Ad;
43208 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
43209 +
43210 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43211 + p_FmPcd = p_Manip->h_FmPcd;
43212 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43213 +
43214 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43215 +
43216 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
43217 + if (p_Manip->frag == TRUE)
43218 + {
43219 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
43220 + - (p_FmPcd->physicalMuramBase));
43221 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
43222 + << FM_PCD_MANIP_IP_MTU_SHIFT;
43223 + }
43224 +
43225 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43226 + tmpReg32 |= HMAN_OC_IP_MANIP;
43227 +
43228 +#if (DPAA_VERSION >= 11)
43229 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
43230 +#endif /* (DPAA_VERSION >= 11) */
43231 +
43232 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43233 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
43234 + WRITE_UINT32(p_Ad->gmask, 0);
43235 + /* Total frame counter - MUST be initialized to zero.*/
43236 +
43237 + return err;
43238 +}
43239 +
43240 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
43241 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
43242 + t_Handle h_Ad, bool validate)
43243 +{
43244 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
43245 + t_Error err;
43246 +
43247 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43248 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
43249 + E_INVALID_STATE);
43250 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
43251 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
43252 +
43253 + UNUSED(h_FmPcd);
43254 + UNUSED(h_Ad);
43255 + UNUSED(h_PcdParams);
43256 + UNUSED(validate);
43257 + UNUSED(p_Manip);
43258 +
43259 + fmPortGetSetCcParams.setCcParams.type = 0;
43260 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
43261 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
43262 + RETURN_ERROR(MAJOR, err, NO_MSG);
43263 +
43264 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
43265 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
43266 +
43267 + return E_OK;
43268 +}
43269 +
43270 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
43271 + t_FmPcdManip *p_Manip)
43272 +{
43273 + t_AdOfTypeContLookup *p_Ad;
43274 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
43275 + t_Error err = E_OK;
43276 + uint32_t tmpReg32 = 0;
43277 + uint32_t power;
43278 +
43279 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43280 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43281 +
43282 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
43283 +
43284 + SANITY_CHECK_RETURN_ERROR(
43285 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
43286 + E_INVALID_VALUE);
43287 + SANITY_CHECK_RETURN_ERROR(
43288 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
43289 + E_INVALID_VALUE);
43290 + SANITY_CHECK_RETURN_ERROR(
43291 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
43292 + E_INVALID_VALUE);
43293 + SANITY_CHECK_RETURN_ERROR(
43294 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
43295 + E_INVALID_VALUE);
43296 + SANITY_CHECK_RETURN_ERROR(
43297 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
43298 + E_INVALID_VALUE);
43299 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
43300 +
43301 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43302 +
43303 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43304 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
43305 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
43306 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
43307 + tmpReg32 |=
43308 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
43309 + tmpReg32 |=
43310 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
43311 + if (p_IPSecParams->arwSize)
43312 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
43313 + & (FM_MURAM_SIZE-1));
43314 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
43315 +
43316 + tmpReg32 = 0;
43317 + if (p_IPSecParams->arwSize) {
43318 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
43319 + LOG2(power, power);
43320 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
43321 + }
43322 +
43323 + if (p_ManipParams->h_NextManip)
43324 + tmpReg32 |=
43325 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
43326 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
43327 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
43328 +
43329 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
43330 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
43331 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
43332 + if (p_ManipParams->h_NextManip)
43333 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
43334 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43335 +
43336 + return err;
43337 +}
43338 +
43339 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
43340 +{
43341 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
43342 +
43343 + /* Allocation if CAPWAP Action descriptor */
43344 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
43345 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
43346 + FM_PCD_CC_AD_TABLE_ALIGN);
43347 + if (!p_Manip->reassmParams.capwap.h_Ad)
43348 + {
43349 + ReleaseManipHandler(p_Manip, p_FmPcd);
43350 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43351 + ("Allocation of CAPWAP table descriptor"));
43352 + }
43353 +
43354 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43355 +
43356 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
43357 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
43358 +}
43359 +
43360 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
43361 + t_FmPcdKgSchemeParams *p_Scheme,
43362 + t_Handle h_CcTree, uint8_t groupId)
43363 +{
43364 + uint8_t res;
43365 +
43366 + /* Configures scheme's network environment parameters */
43367 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
43368 + res = FmPcdNetEnvGetUnitId(
43369 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
43370 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
43371 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
43372 + p_Scheme->netEnvParams.unitIds[0] = res;
43373 +
43374 + /* Configures scheme's next engine parameters*/
43375 + p_Scheme->nextEngine = e_FM_PCD_CC;
43376 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
43377 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
43378 + p_Scheme->useHash = TRUE;
43379 +
43380 + /* Configures scheme's key*/
43381 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
43382 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
43383 + e_FM_PCD_EXTRACT_NON_HDR;
43384 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
43385 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
43386 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
43387 + e_FM_PCD_ACTION_NONE;
43388 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
43389 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
43390 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
43391 + e_FM_PCD_EXTRACT_NON_HDR;
43392 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
43393 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
43394 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
43395 + e_FM_PCD_ACTION_NONE;
43396 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
43397 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
43398 +
43399 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
43400 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
43401 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
43402 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
43403 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
43404 +}
43405 +
43406 +#if (DPAA_VERSION >= 11)
43407 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
43408 + t_FmPcdManipReassemCapwapStats *p_Stats)
43409 +{
43410 + ASSERT_COND(p_Manip);
43411 + ASSERT_COND(p_Stats);
43412 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
43413 +
43414 + p_Stats->timeout =
43415 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
43416 + p_Stats->rfdPoolBusy =
43417 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
43418 + p_Stats->internalBufferBusy =
43419 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
43420 + p_Stats->externalBufferBusy =
43421 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
43422 + p_Stats->sgFragments =
43423 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
43424 + p_Stats->dmaSemaphoreDepletion =
43425 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
43426 + p_Stats->exceedMaxReassemblyFrameLen =
43427 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
43428 +
43429 + p_Stats->successfullyReassembled =
43430 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
43431 + p_Stats->validFragments =
43432 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
43433 + p_Stats->processedFragments =
43434 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
43435 + p_Stats->malformedFragments =
43436 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
43437 + p_Stats->autoLearnBusy =
43438 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
43439 + p_Stats->discardedFragments =
43440 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
43441 + p_Stats->moreThan16Fragments =
43442 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
43443 +
43444 + return E_OK;
43445 +}
43446 +
43447 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
43448 + t_FmPcdManipFragCapwapStats *p_Stats)
43449 +{
43450 + t_AdOfTypeContLookup *p_Ad;
43451 +
43452 + ASSERT_COND(p_Manip);
43453 + ASSERT_COND(p_Stats);
43454 + ASSERT_COND(p_Manip->h_Ad);
43455 + ASSERT_COND(p_Manip->fragParams.p_Frag);
43456 +
43457 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43458 +
43459 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
43460 +
43461 + return E_OK;
43462 +}
43463 +
43464 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
43465 + t_FmPcdManip *p_Manip)
43466 +{
43467 + uint32_t maxSetNumber = 10000;
43468 + t_FmPcdManipReassemCapwapParams reassmManipParams =
43469 + p_ManipReassmParams->u.capwapReassem;
43470 + t_Error res;
43471 +
43472 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
43473 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
43474 + E_INVALID_HANDLE);
43475 +
43476 + /* Check validation of user's parameter.*/
43477 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
43478 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
43479 + RETURN_ERROR(
43480 + MAJOR, E_INVALID_VALUE,
43481 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
43482 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
43483 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
43484 + if (reassmManipParams.maxNumFramesInProcess
43485 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
43486 + RETURN_ERROR(
43487 + MAJOR,
43488 + E_INVALID_VALUE,
43489 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
43490 +
43491 + /* Saves user's reassembly manipulation parameters */
43492 + p_Manip->reassmParams.capwap.relativeSchemeId =
43493 + reassmManipParams.relativeSchemeId;
43494 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
43495 + reassmManipParams.numOfFramesPerHashEntry;
43496 + p_Manip->reassmParams.capwap.maxRessembledsSize =
43497 + reassmManipParams.maxReassembledFrameLength;
43498 + p_Manip->reassmParams.maxNumFramesInProcess =
43499 + reassmManipParams.maxNumFramesInProcess;
43500 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
43501 + p_Manip->reassmParams.fqidForTimeOutFrames =
43502 + reassmManipParams.fqidForTimeOutFrames;
43503 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
43504 + reassmManipParams.timeoutThresholdForReassmProcess;
43505 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
43506 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
43507 +
43508 + /* Creates and initializes the Reassembly common parameter table */
43509 + CreateReassCommonTable(p_Manip);
43510 +
43511 + res = SetCapwapReassmManip(p_Manip);
43512 + if (res != E_OK)
43513 + return res;
43514 +
43515 + return E_OK;
43516 +}
43517 +
43518 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
43519 + t_FmPcdManip *p_Manip)
43520 +{
43521 + t_FmPcd *p_FmPcd;
43522 + t_AdOfTypeContLookup *p_Ad;
43523 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
43524 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
43525 +
43526 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
43527 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
43528 + E_INVALID_VALUE);
43529 + p_FmPcd = p_Manip->h_FmPcd;
43530 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43531 +
43532 + /* Allocation of fragmentation Action Descriptor */
43533 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
43534 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
43535 + FM_PCD_CC_AD_TABLE_ALIGN);
43536 + if (!p_Manip->fragParams.p_Frag)
43537 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43538 + ("MURAM alloc for Fragmentation table descriptor"));
43539 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43540 +
43541 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
43542 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
43543 +
43544 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
43545 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
43546 + ccAdBaseReg |=
43547 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
43548 + 0;
43549 +
43550 + /* Set Scatter/Gather BPid */
43551 + if (p_ManipParams->sgBpidEn)
43552 + {
43553 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
43554 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
43555 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
43556 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
43557 + }
43558 +
43559 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
43560 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
43561 + - p_FmPcd->physicalMuramBase);
43562 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
43563 +
43564 + /* Set all Ad registers */
43565 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
43566 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
43567 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
43568 +
43569 + /* Saves user's fragmentation manipulation parameters */
43570 + p_Manip->frag = TRUE;
43571 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
43572 +
43573 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43574 +
43575 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
43576 + - (p_FmPcd->physicalMuramBase));
43577 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
43578 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
43579 +
43580 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43581 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
43582 +
43583 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
43584 +
43585 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43586 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
43587 + WRITE_UINT32(p_Ad->gmask, 0);
43588 + /* Total frame counter - MUST be initialized to zero.*/
43589 +
43590 + return E_OK;
43591 +}
43592 +
43593 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
43594 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
43595 + t_Handle h_Ad, bool validate)
43596 +{
43597 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
43598 + t_Error err;
43599 +
43600 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43601 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
43602 + E_INVALID_STATE);
43603 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
43604 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
43605 +
43606 + UNUSED(h_FmPcd);
43607 + UNUSED(h_Ad);
43608 + UNUSED(h_PcdParams);
43609 + UNUSED(validate);
43610 + UNUSED(p_Manip);
43611 +
43612 + fmPortGetSetCcParams.setCcParams.type = 0;
43613 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
43614 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
43615 + RETURN_ERROR(MAJOR, err, NO_MSG);
43616 +
43617 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
43618 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
43619 +
43620 + return E_OK;
43621 +}
43622 +
43623 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
43624 + t_FmPcdManip *p_Manip)
43625 +{
43626 + t_AdOfTypeContLookup *p_Ad;
43627 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
43628 + t_Error err = E_OK;
43629 + uint32_t tmpReg32 = 0;
43630 +
43631 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43632 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43633 +
43634 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
43635 +
43636 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43637 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43638 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
43639 + /* TODO - add 'qosSrc' */
43640 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
43641 +
43642 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
43643 + if (p_ManipParams->h_NextManip)
43644 + {
43645 + WRITE_UINT32(
43646 + p_Ad->matchTblPtr,
43647 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
43648 +
43649 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
43650 + }
43651 +
43652 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43653 +
43654 + return err;
43655 +}
43656 +#endif /* (DPAA_VERSION >= 11) */
43657 +
43658 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
43659 + bool stats)
43660 +{
43661 + t_FmPcdManip *p_Manip;
43662 + t_Error err;
43663 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43664 +
43665 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
43666 + if (!p_Manip)
43667 + {
43668 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
43669 + return NULL;
43670 + }
43671 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
43672 +
43673 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
43674 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
43675 + sizeof(p_Manip->manipParams));
43676 +
43677 + if (!stats)
43678 + err = CheckManipParamsAndSetType(p_Manip,
43679 + (t_FmPcdManipParams *)p_Params);
43680 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43681 + else
43682 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
43683 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43684 + else
43685 + {
43686 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
43687 + XX_Free(p_Manip);
43688 + return NULL;
43689 + }
43690 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43691 + if (err)
43692 + {
43693 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
43694 + XX_Free(p_Manip);
43695 + return NULL;
43696 + }
43697 +
43698 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
43699 + {
43700 + /* In Case of reassembly manipulation the reassembly action descriptor will
43701 + be defines later on */
43702 + if (p_Manip->muramAllocate)
43703 + {
43704 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
43705 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
43706 + FM_PCD_CC_AD_TABLE_ALIGN);
43707 + if (!p_Manip->h_Ad)
43708 + {
43709 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
43710 + ReleaseManipHandler(p_Manip, p_FmPcd);
43711 + XX_Free(p_Manip);
43712 + return NULL;
43713 + }
43714 +
43715 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43716 + }
43717 + else
43718 + {
43719 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
43720 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
43721 + if (!p_Manip->h_Ad)
43722 + {
43723 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
43724 + ReleaseManipHandler(p_Manip, p_FmPcd);
43725 + XX_Free(p_Manip);
43726 + return NULL;
43727 + }
43728 +
43729 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
43730 + }
43731 + }
43732 +
43733 + p_Manip->h_FmPcd = h_FmPcd;
43734 +
43735 + return p_Manip;
43736 +}
43737 +
43738 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
43739 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
43740 +{
43741 + t_CcNodeInformation *p_CcNodeInformation;
43742 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
43743 + t_List *p_Pos;
43744 + int i = 0;
43745 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
43746 + t_CcNodeInformation ccNodeInfo;
43747 +
43748 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
43749 + {
43750 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
43751 + p_NodePtrOnCurrentMdfManip =
43752 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
43753 +
43754 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
43755 +
43756 + /* Search in the previous node which exact index points on this current modified node for getting AD */
43757 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
43758 + {
43759 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
43760 + == e_FM_PCD_CC)
43761 + {
43762 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
43763 + == (t_Handle)p_CrntMdfManip)
43764 + {
43765 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
43766 + p_AdTablePtOnCrntCurrentMdfNode =
43767 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
43768 + else
43769 + p_AdTablePtOnCrntCurrentMdfNode =
43770 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
43771 +
43772 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
43773 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
43774 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
43775 + }
43776 + }
43777 + }
43778 +
43779 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
43780 + }
43781 +}
43782 +
43783 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
43784 + t_FmPcd *p_FmPcd)
43785 +{
43786 + t_Error err;
43787 +
43788 + /* Copy the HMTD */
43789 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
43790 + /* Replace the HMCT table pointer */
43791 + WRITE_UINT32(
43792 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
43793 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
43794 + /* Call Host Command to replace HMTD by a new HMTD */
43795 + err = FmHcPcdCcDoDynamicChange(
43796 + p_FmPcd->h_Hc,
43797 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
43798 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
43799 + if (err)
43800 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
43801 +}
43802 +
43803 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
43804 + t_Handle h_FmPort, t_Handle h_Manip,
43805 + t_Handle h_Ad, bool validate, int level,
43806 + t_Handle h_FmTree)
43807 +{
43808 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43809 + t_Error err = E_OK;
43810 +
43811 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
43812 +
43813 + UNUSED(level);
43814 + UNUSED(h_FmTree);
43815 +
43816 + switch (p_Manip->opcode)
43817 + {
43818 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43819 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43820 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
43821 + p_Manip,
43822 + h_Ad,
43823 + validate);
43824 + break;
43825 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43826 + if (!p_Manip->h_Frag)
43827 + break;
43828 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43829 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
43830 + break;
43831 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43832 + if (p_Manip->h_Frag)
43833 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
43834 + break;
43835 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43836 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
43837 + break;
43838 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43839 + case (HMAN_OC_IP_REASSEMBLY):
43840 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
43841 + validate);
43842 + break;
43843 + case (HMAN_OC_IP_FRAGMENTATION):
43844 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
43845 + h_Ad, validate);
43846 + break;
43847 +#if (DPAA_VERSION >= 11)
43848 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43849 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
43850 + h_Ad, validate);
43851 + break;
43852 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43853 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
43854 + validate);
43855 + break;
43856 +#endif /* (DPAA_VERSION >= 11) */
43857 + default:
43858 + return E_OK;
43859 + }
43860 +
43861 + return err;
43862 +}
43863 +
43864 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
43865 + bool validate, int level,
43866 + t_Handle h_FmTree)
43867 +{
43868 +
43869 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43870 + t_Error err = E_OK;
43871 +
43872 + UNUSED(level);
43873 +
43874 + switch (p_Manip->opcode)
43875 + {
43876 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43877 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43878 + RETURN_ERROR(
43879 + MAJOR,
43880 + E_INVALID_STATE,
43881 + ("modify node with this type of manipulation is not suppported"));
43882 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43883 +
43884 + if (p_Manip->h_Frag)
43885 + {
43886 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
43887 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
43888 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
43889 + RETURN_ERROR(
43890 + MAJOR,
43891 + E_INVALID_STATE,
43892 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
43893 + }
43894 + break;
43895 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43896 + if (p_Manip->h_Frag)
43897 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
43898 + break;
43899 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43900 + default:
43901 + return E_OK;
43902 + }
43903 +
43904 + return err;
43905 +}
43906 +
43907 +/*****************************************************************************/
43908 +/* Inter-module API routines */
43909 +/*****************************************************************************/
43910 +
43911 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
43912 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
43913 + bool validate, int level, t_Handle h_FmTree,
43914 + bool modify)
43915 +{
43916 + t_Error err;
43917 +
43918 + if (!modify)
43919 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
43920 + h_Ad, validate, level, h_FmTree);
43921 + else
43922 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
43923 +
43924 + return err;
43925 +}
43926 +
43927 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
43928 +{
43929 +
43930 + uint32_t intFlags;
43931 +
43932 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
43933 + if (add)
43934 + ((t_FmPcdManip *)h_Manip)->owner++;
43935 + else
43936 + {
43937 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
43938 + ((t_FmPcdManip *)h_Manip)->owner--;
43939 + }
43940 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
43941 +}
43942 +
43943 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
43944 +{
43945 + ASSERT_COND(h_Manip);
43946 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
43947 +}
43948 +
43949 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
43950 +{
43951 + ASSERT_COND(h_Manip);
43952 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
43953 +}
43954 +
43955 +t_Error FmPcdManipCheckParamsForCcNextEngine(
43956 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
43957 + uint32_t *requiredAction)
43958 +{
43959 + t_FmPcdManip *p_Manip;
43960 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43961 + t_Error err = E_OK;
43962 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
43963 + bool pointFromCc = TRUE;
43964 +
43965 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
43966 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
43967 + E_NULL_POINTER);
43968 +
43969 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
43970 + *requiredAction = 0;
43971 +
43972 + while (p_Manip)
43973 + {
43974 + switch (p_Manip->opcode)
43975 + {
43976 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43977 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43978 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
43979 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
43980 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
43981 + p_Manip->cnia = TRUE;
43982 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43983 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
43984 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
43985 + p_Manip->ownerTmp++;
43986 + break;
43987 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43988 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
43989 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
43990 + RETURN_ERROR(
43991 + MAJOR,
43992 + E_INVALID_STATE,
43993 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
43994 + p_Manip->ownerTmp++;
43995 + break;
43996 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43997 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
43998 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
43999 + != CC_PC_GENERIC_IC_HASH_INDEXED))
44000 + 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"));
44001 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
44002 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
44003 + if (err)
44004 + RETURN_ERROR(MAJOR, err, NO_MSG);
44005 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
44006 + break;
44007 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44008 + case (HMAN_OC_IP_FRAGMENTATION):
44009 + case (HMAN_OC_IP_REASSEMBLY):
44010 +#if (DPAA_VERSION >= 11)
44011 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44012 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44013 +#endif /* (DPAA_VERSION >= 11) */
44014 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
44015 + RETURN_ERROR(
44016 + MAJOR,
44017 + E_INVALID_STATE,
44018 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
44019 + p_Manip->ownerTmp++;
44020 + break;
44021 + case (HMAN_OC_IPSEC_MANIP):
44022 +#if (DPAA_VERSION >= 11)
44023 + case (HMAN_OC_CAPWAP_MANIP):
44024 +#endif /* (DPAA_VERSION >= 11) */
44025 + p_Manip->ownerTmp++;
44026 + break;
44027 + case (HMAN_OC):
44028 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
44029 + && MANIP_IS_CASCADED(p_Manip))
44030 + RETURN_ERROR(
44031 + MINOR,
44032 + E_INVALID_STATE,
44033 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
44034 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
44035 + RETURN_ERROR(
44036 + MAJOR,
44037 + E_INVALID_STATE,
44038 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
44039 + break;
44040 + default:
44041 + RETURN_ERROR(
44042 + MAJOR, E_INVALID_STATE,
44043 + ("invalid type of header manipulation for this state"));
44044 + }
44045 + p_Manip = p_Manip->h_NextManip;
44046 + pointFromCc = FALSE;
44047 + }
44048 + return E_OK;
44049 +}
44050 +
44051 +
44052 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
44053 + t_Handle h_FmPcdCcNode)
44054 +{
44055 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44056 + t_Error err = E_OK;
44057 +
44058 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
44059 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
44060 +
44061 + switch (p_Manip->opcode)
44062 + {
44063 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44064 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44065 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
44066 + RETURN_ERROR(
44067 + MAJOR,
44068 + E_INVALID_VALUE,
44069 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
44070 + break;
44071 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44072 + if (p_Manip->h_Frag)
44073 + {
44074 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
44075 + RETURN_ERROR(
44076 + MAJOR,
44077 + E_INVALID_VALUE,
44078 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
44079 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
44080 + if (err)
44081 + RETURN_ERROR(MAJOR, err, NO_MSG);
44082 + }
44083 + break;
44084 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44085 + default:
44086 + break;
44087 + }
44088 +
44089 + return err;
44090 +}
44091 +
44092 +void FmPcdManipUpdateAdResultForCc(
44093 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
44094 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
44095 +{
44096 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44097 +
44098 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
44099 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
44100 +
44101 + ASSERT_COND(p_Manip);
44102 + ASSERT_COND(p_CcNextEngineParams);
44103 + ASSERT_COND(p_Ad);
44104 + ASSERT_COND(p_AdNewPtr);
44105 +
44106 + FmPcdManipUpdateOwner(h_Manip, TRUE);
44107 +
44108 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
44109 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
44110 + switch (p_Manip->opcode)
44111 + {
44112 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44113 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
44114 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44115 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44116 + *p_AdNewPtr = p_Manip->h_Ad;
44117 + break;
44118 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44119 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44120 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
44121 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
44122 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
44123 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
44124 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
44125 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
44126 + *p_AdNewPtr = NULL;
44127 + break;
44128 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44129 + case (HMAN_OC_IPSEC_MANIP):
44130 +#if (DPAA_VERSION >= 11)
44131 + case (HMAN_OC_CAPWAP_MANIP):
44132 +#endif /* (DPAA_VERSION >= 11) */
44133 + *p_AdNewPtr = p_Manip->h_Ad;
44134 + break;
44135 + case (HMAN_OC_IP_FRAGMENTATION):
44136 +#if (DPAA_VERSION >= 11)
44137 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44138 +#endif /* (DPAA_VERSION >= 11) */
44139 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
44140 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
44141 + {
44142 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
44143 + sizeof(t_AdOfTypeContLookup));
44144 +#if (DPAA_VERSION >= 11)
44145 + WRITE_UINT32(
44146 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
44147 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
44148 +#endif /* (DPAA_VERSION >= 11) */
44149 + *p_AdNewPtr = NULL;
44150 + }
44151 + else
44152 + *p_AdNewPtr = p_Manip->h_Ad;
44153 + break;
44154 + case (HMAN_OC_IP_REASSEMBLY):
44155 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
44156 + {
44157 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
44158 + {
44159 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
44160 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
44161 + FmPcdManipUpdateOwner(h_Manip, FALSE);
44162 + }
44163 + else
44164 + {
44165 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
44166 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
44167 + }
44168 + }
44169 + else
44170 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
44171 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
44172 + sizeof(t_AdOfTypeContLookup));
44173 + *p_AdNewPtr = NULL;
44174 + break;
44175 +#if (DPAA_VERSION >= 11)
44176 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44177 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
44178 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
44179 + sizeof(t_AdOfTypeContLookup));
44180 + *p_AdNewPtr = NULL;
44181 + break;
44182 +#endif /* (DPAA_VERSION >= 11) */
44183 + case (HMAN_OC):
44184 + /* Allocate and initialize HMTD */
44185 + *p_AdNewPtr = p_Manip->h_Ad;
44186 + break;
44187 + default:
44188 + break;
44189 + }
44190 +}
44191 +
44192 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
44193 + t_Handle *p_AdNewPtr,
44194 + uint32_t adTableOffset)
44195 +{
44196 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44197 +
44198 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
44199 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
44200 + ASSERT_COND(p_Manip);
44201 +
44202 + FmPcdManipUpdateOwner(h_Manip, TRUE);
44203 +
44204 + switch (p_Manip->opcode)
44205 + {
44206 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44207 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44208 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
44209 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
44210 + WRITE_UINT32(
44211 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
44212 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
44213 + WRITE_UINT32(
44214 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
44215 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
44216 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
44217 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
44218 + WRITE_UINT32(
44219 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
44220 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
44221 + *p_AdNewPtr = NULL;
44222 + break;
44223 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44224 + case (HMAN_OC):
44225 + /* Initialize HMTD within the match table*/
44226 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
44227 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
44228 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
44229 + /* update NADEN to be "1"*/
44230 + WRITE_UINT16(
44231 + ((t_Hmtd *)p_Ad)->cfg,
44232 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
44233 + /* update next action descriptor */
44234 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
44235 + (uint16_t)(adTableOffset >> 4));
44236 + /* mark that Manip's HMTD is not used */
44237 + *p_AdNewPtr = NULL;
44238 + break;
44239 +
44240 + default:
44241 + break;
44242 + }
44243 +}
44244 +
44245 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
44246 + t_Handle h_CcTree, t_Handle h_Manip,
44247 + bool isIpv4, uint8_t groupId)
44248 +{
44249 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44250 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
44251 + t_Handle h_Scheme;
44252 +
44253 + ASSERT_COND(p_FmPcd);
44254 + ASSERT_COND(h_NetEnv);
44255 + ASSERT_COND(p_Manip);
44256 +
44257 + /* scheme was already build, no need to check for IPv6 */
44258 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
44259 + return E_OK;
44260 +
44261 + if (isIpv4) {
44262 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
44263 + if (h_Scheme) {
44264 + /* scheme was found */
44265 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
44266 + return E_OK;
44267 + }
44268 + } else {
44269 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
44270 + if (h_Scheme) {
44271 + /* scheme was found */
44272 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
44273 + return E_OK;
44274 + }
44275 + }
44276 +
44277 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
44278 + if (!p_SchemeParams)
44279 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
44280 + ("Memory allocation failed for scheme"));
44281 +
44282 + /* Configures the IPv4 or IPv6 scheme*/
44283 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
44284 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
44285 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
44286 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
44287 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
44288 + p_SchemeParams->schemeCounter.update = TRUE;
44289 +#if (DPAA_VERSION >= 11)
44290 + p_SchemeParams->alwaysDirect = TRUE;
44291 + p_SchemeParams->bypassFqidGeneration = TRUE;
44292 +#else
44293 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
44294 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
44295 +#endif /* (DPAA_VERSION >= 11) */
44296 +
44297 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
44298 +
44299 + /* Sets the new scheme */
44300 + if (isIpv4)
44301 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
44302 + p_FmPcd, p_SchemeParams);
44303 + else
44304 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
44305 + p_FmPcd, p_SchemeParams);
44306 +
44307 + XX_Free(p_SchemeParams);
44308 +
44309 + return E_OK;
44310 +}
44311 +
44312 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
44313 +{
44314 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44315 +
44316 + ASSERT_COND(p_Manip);
44317 +
44318 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
44319 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
44320 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
44321 +
44322 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
44323 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
44324 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
44325 +
44326 + return E_OK;
44327 +}
44328 +
44329 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
44330 +{
44331 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44332 +
44333 + ASSERT_COND(p_Manip);
44334 +
44335 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
44336 +}
44337 +
44338 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
44339 + t_Handle h_CcTree, t_Handle h_Manip,
44340 + uint8_t groupId)
44341 +{
44342 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44343 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
44344 +
44345 + ASSERT_COND(p_FmPcd);
44346 + ASSERT_COND(h_NetEnv);
44347 + ASSERT_COND(p_Manip);
44348 +
44349 + /* scheme was already build, no need to check for IPv6 */
44350 + if (p_Manip->reassmParams.capwap.h_Scheme)
44351 + return E_OK;
44352 +
44353 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
44354 + if (!p_SchemeParams)
44355 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
44356 + ("Memory allocation failed for scheme"));
44357 +
44358 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
44359 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
44360 + p_SchemeParams->id.relativeSchemeId =
44361 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
44362 + p_SchemeParams->schemeCounter.update = TRUE;
44363 + p_SchemeParams->bypassFqidGeneration = TRUE;
44364 +
44365 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
44366 +
44367 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
44368 + p_SchemeParams);
44369 +
44370 + XX_Free(p_SchemeParams);
44371 +
44372 + return E_OK;
44373 +}
44374 +
44375 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
44376 +{
44377 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44378 +
44379 + ASSERT_COND(p_Manip);
44380 +
44381 + if (p_Manip->reassmParams.capwap.h_Scheme)
44382 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
44383 +
44384 + return E_OK;
44385 +}
44386 +
44387 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44388 +t_Handle FmPcdManipApplSpecificBuild(void)
44389 +{
44390 + t_FmPcdManip *p_Manip;
44391 +
44392 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
44393 + if (!p_Manip)
44394 + {
44395 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
44396 + return NULL;
44397 + }
44398 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
44399 +
44400 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
44401 + p_Manip->muramAllocate = FALSE;
44402 +
44403 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
44404 + if (!p_Manip->h_Ad)
44405 + {
44406 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
44407 + XX_Free(p_Manip);
44408 + return NULL;
44409 + }
44410 +
44411 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
44412 +
44413 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
44414 + /*Application specific = type of flowId index, move internal frame header from data to IC,
44415 + SEC errors check*/
44416 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
44417 + {
44418 + XX_Free(p_Manip->h_Ad);
44419 + XX_Free(p_Manip);
44420 + return NULL;
44421 + }
44422 + return p_Manip;
44423 +}
44424 +
44425 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
44426 +{
44427 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44428 + ASSERT_COND(h_Manip);
44429 +
44430 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
44431 +}
44432 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44433 +/*********************** End of inter-module routines ************************/
44434 +
44435 +/****************************************/
44436 +/* API Init unit functions */
44437 +/****************************************/
44438 +
44439 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
44440 + t_FmPcdManipParams *p_ManipParams)
44441 +{
44442 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
44443 + t_FmPcdManip *p_Manip;
44444 + t_Error err;
44445 +
44446 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
44447 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
44448 +
44449 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
44450 + if (!p_Manip)
44451 + return NULL;
44452 +
44453 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
44454 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
44455 + || (p_Manip->opcode == HMAN_OC)
44456 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
44457 +#if (DPAA_VERSION >= 11)
44458 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
44459 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
44460 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
44461 +#endif /* (DPAA_VERSION >= 11) */
44462 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
44463 + {
44464 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
44465 + XX_Free(p_Manip);
44466 + return NULL;
44467 + }
44468 + p_Manip->h_Spinlock = XX_InitSpinlock();
44469 + if (!p_Manip->h_Spinlock)
44470 + {
44471 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44472 + ReleaseManipHandler(p_Manip, p_FmPcd);
44473 + XX_Free(p_Manip);
44474 + return NULL;
44475 + }INIT_LIST(&p_Manip->nodesLst);
44476 +
44477 + switch (p_Manip->opcode)
44478 + {
44479 + case (HMAN_OC_IP_REASSEMBLY):
44480 + /* IpReassembly */
44481 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
44482 + break;
44483 + case (HMAN_OC_IP_FRAGMENTATION):
44484 + /* IpFragmentation */
44485 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
44486 + if (err)
44487 + break;
44488 + err = IPManip(p_Manip);
44489 + break;
44490 + case (HMAN_OC_IPSEC_MANIP):
44491 + err = IPSecManip(p_ManipParams, p_Manip);
44492 + break;
44493 +#if (DPAA_VERSION >= 11)
44494 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44495 + /* CapwapReassembly */
44496 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
44497 + break;
44498 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44499 + /* CapwapFragmentation */
44500 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
44501 + p_Manip);
44502 + break;
44503 + case (HMAN_OC_CAPWAP_MANIP):
44504 + err = CapwapManip(p_ManipParams, p_Manip);
44505 + break;
44506 +#endif /* (DPAA_VERSION >= 11) */
44507 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44508 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
44509 + /* HmanType1 */
44510 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
44511 + break;
44512 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44513 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
44514 + p_Manip,
44515 + p_FmPcd,
44516 + p_ManipParams->fragOrReasmParams.sgBpid);
44517 + if (err)
44518 + {
44519 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44520 + ReleaseManipHandler(p_Manip, p_FmPcd);
44521 + XX_Free(p_Manip);
44522 + return NULL;
44523 + }
44524 + if (p_Manip->insrt)
44525 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
44526 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44527 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
44528 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
44529 + break;
44530 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44531 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
44532 + p_Manip,
44533 + p_FmPcd,
44534 + p_ManipParams->fragOrReasmParams.sgBpid);
44535 + if (err)
44536 + {
44537 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44538 + ReleaseManipHandler(p_Manip, p_FmPcd);
44539 + XX_Free(p_Manip);
44540 + return NULL;
44541 + }
44542 + if (p_Manip->rmv)
44543 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
44544 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44545 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
44546 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
44547 + break;
44548 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44549 + /*Application Specific type 1*/
44550 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
44551 + break;
44552 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44553 + case (HMAN_OC):
44554 + /* New Manip */
44555 + err = CreateManipActionNew(p_Manip, p_ManipParams);
44556 + break;
44557 + default:
44558 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44559 + ReleaseManipHandler(p_Manip, p_FmPcd);
44560 + XX_Free(p_Manip);
44561 + return NULL;
44562 + }
44563 +
44564 + if (err)
44565 + {
44566 + REPORT_ERROR(MAJOR, err, NO_MSG);
44567 + ReleaseManipHandler(p_Manip, p_FmPcd);
44568 + XX_Free(p_Manip);
44569 + return NULL;
44570 + }
44571 +
44572 + if (p_ManipParams->h_NextManip)
44573 + {
44574 + /* in the check routine we've verified that h_NextManip has no owners
44575 + * and that only supported types are allowed. */
44576 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
44577 + /* save a "prev" pointer in h_NextManip */
44578 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
44579 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
44580 + }
44581 +
44582 + return p_Manip;
44583 +}
44584 +
44585 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
44586 + t_FmPcdManipParams *p_ManipParams)
44587 +{
44588 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
44589 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
44590 + t_Error err;
44591 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
44592 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
44593 + t_CcNodeInformation *p_CcNodeInfo;
44594 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
44595 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
44596 +
44597 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
44598 +
44599 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
44600 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
44601 + RETURN_ERROR(
44602 + MINOR,
44603 + E_NOT_SUPPORTED,
44604 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
44605 +
44606 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
44607 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
44608 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
44609 + sizeof(p_Manip->manipParams));
44610 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
44611 +
44612 + /* The replacement of the HdrManip depends on the node type.*/
44613 + /*
44614 + * (1) If this is an independent node, all its owners should be updated.
44615 + *
44616 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
44617 + * it has a "next" and it has a "cascaded" indication), the next
44618 + * node remains unchanged, and the behavior is as in (1).
44619 + *
44620 + * (3) If it is not the head, but a part of a cascaded chain, in can be
44621 + * also replaced as a regular node with just one owner.
44622 + *
44623 + * (4) If it is a part of a chain implemented as a unified table, the
44624 + * whole table is replaced and the owners of the head node must be updated.
44625 + *
44626 + */
44627 + /* lock shadow */
44628 + if (!p_FmPcd->p_CcShadow)
44629 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
44630 +
44631 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
44632 + return ERROR_CODE(E_BUSY);
44633 +
44634 + /* this routine creates a new manip action in the CC Shadow. */
44635 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
44636 + if (err)
44637 + RETURN_ERROR(MINOR, err, NO_MSG);
44638 +
44639 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
44640 + * replace only HMTD and no lcok is required. Otherwise
44641 + * lock the whole PCD
44642 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
44643 + if (!FmPcdLockTryLockAll(p_FmPcd))
44644 + {
44645 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
44646 + return ERROR_CODE(E_BUSY);
44647 + }
44648 +
44649 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
44650 +
44651 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
44652 + e_MANIP_HANDLER_TABLE_OWNER);
44653 + ASSERT_COND(p_FirstManip);
44654 +
44655 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
44656 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
44657 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
44658 +
44659 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
44660 + ASSERT_COND(p_Hmtd);
44661 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
44662 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
44663 +
44664 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
44665 + {
44666 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
44667 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
44668 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
44669 + }
44670 +
44671 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
44672 + ASSERT_COND(p_WholeHmct);
44673 +
44674 + /* re-build the HMCT n the original location */
44675 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
44676 + if (err)
44677 + {
44678 + RELEASE_LOCK(p_FmPcd->shadowLock);
44679 + RETURN_ERROR(MINOR, err, NO_MSG);
44680 + }
44681 +
44682 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
44683 + ASSERT_COND(p_Hmtd);
44684 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
44685 + ((t_FmPcd*)p_Manip->h_FmPcd));
44686 +
44687 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
44688 + * For each p_Hmct (from list+fixed):
44689 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
44690 + {
44691 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
44692 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
44693 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
44694 + }
44695 +
44696 +
44697 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
44698 +
44699 + FmPcdLockUnlockAll(p_FmPcd);
44700 +
44701 + /* unlock shadow */
44702 + RELEASE_LOCK(p_FmPcd->shadowLock);
44703 +
44704 + return E_OK;
44705 +}
44706 +
44707 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
44708 +{
44709 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
44710 +
44711 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
44712 +
44713 + if (p_Manip->owner)
44714 + RETURN_ERROR(
44715 + MAJOR,
44716 + E_INVALID_STATE,
44717 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
44718 +
44719 + if (p_Manip->h_NextManip)
44720 + {
44721 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
44722 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
44723 + }
44724 +
44725 + if (p_Manip->p_Hmct
44726 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
44727 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
44728 + p_Manip->p_Hmct);
44729 +
44730 + if (p_Manip->h_Spinlock)
44731 + {
44732 + XX_FreeSpinlock(p_Manip->h_Spinlock);
44733 + p_Manip->h_Spinlock = NULL;
44734 + }
44735 +
44736 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
44737 +
44738 + XX_Free(h_ManipNode);
44739 +
44740 + return E_OK;
44741 +}
44742 +
44743 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
44744 + t_FmPcdManipStats *p_FmPcdManipStats)
44745 +{
44746 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
44747 +
44748 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
44749 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
44750 +
44751 + switch (p_Manip->opcode)
44752 + {
44753 + case (HMAN_OC_IP_REASSEMBLY):
44754 + return IpReassemblyStats(p_Manip,
44755 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
44756 + case (HMAN_OC_IP_FRAGMENTATION):
44757 + return IpFragmentationStats(p_Manip,
44758 + &p_FmPcdManipStats->u.frag.u.ipFrag);
44759 +#if (DPAA_VERSION >= 11)
44760 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44761 + return CapwapReassemblyStats(
44762 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
44763 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44764 + return CapwapFragmentationStats(
44765 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
44766 +#endif /* (DPAA_VERSION >= 11) */
44767 + default:
44768 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
44769 + ("no statistics to this type of manip"));
44770 + }
44771 +
44772 + return E_OK;
44773 +}
44774 +
44775 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44776 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
44777 +{
44778 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
44779 + t_FmPcdManip *p_Manip;
44780 + t_Error err;
44781 +
44782 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
44783 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
44784 +
44785 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
44786 + if (!p_Manip)
44787 + return NULL;
44788 +
44789 + switch (p_Manip->opcode)
44790 + {
44791 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44792 + /* Indexed statistics */
44793 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
44794 + break;
44795 + default:
44796 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
44797 + ReleaseManipHandler(p_Manip, p_FmPcd);
44798 + XX_Free(p_Manip);
44799 + return NULL;
44800 + }
44801 +
44802 + if (err)
44803 + {
44804 + REPORT_ERROR(MAJOR, err, NO_MSG);
44805 + ReleaseManipHandler(p_Manip, p_FmPcd);
44806 + XX_Free(p_Manip);
44807 + return NULL;
44808 + }
44809 +
44810 + return p_Manip;
44811 +}
44812 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44813 --- /dev/null
44814 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
44815 @@ -0,0 +1,555 @@
44816 +/*
44817 + * Copyright 2008-2012 Freescale Semiconductor Inc.
44818 + *
44819 + * Redistribution and use in source and binary forms, with or without
44820 + * modification, are permitted provided that the following conditions are met:
44821 + * * Redistributions of source code must retain the above copyright
44822 + * notice, this list of conditions and the following disclaimer.
44823 + * * Redistributions in binary form must reproduce the above copyright
44824 + * notice, this list of conditions and the following disclaimer in the
44825 + * documentation and/or other materials provided with the distribution.
44826 + * * Neither the name of Freescale Semiconductor nor the
44827 + * names of its contributors may be used to endorse or promote products
44828 + * derived from this software without specific prior written permission.
44829 + *
44830 + *
44831 + * ALTERNATIVELY, this software may be distributed under the terms of the
44832 + * GNU General Public License ("GPL") as published by the Free Software
44833 + * Foundation, either version 2 of that License or (at your option) any
44834 + * later version.
44835 + *
44836 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
44837 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44838 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44839 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
44840 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44841 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44842 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44843 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44844 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44845 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44846 + */
44847 +
44848 +
44849 +/******************************************************************************
44850 + @File fm_manip.h
44851 +
44852 + @Description FM PCD manip...
44853 +*//***************************************************************************/
44854 +#ifndef __FM_MANIP_H
44855 +#define __FM_MANIP_H
44856 +
44857 +#include "std_ext.h"
44858 +#include "error_ext.h"
44859 +#include "list_ext.h"
44860 +
44861 +#include "fm_cc.h"
44862 +
44863 +
44864 +/***********************************************************************/
44865 +/* Header manipulations defines */
44866 +/***********************************************************************/
44867 +
44868 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
44869 +
44870 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44871 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
44872 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
44873 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
44874 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
44875 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
44876 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
44877 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
44878 +#else
44879 +#define HMAN_OC_CAPWAP_MANIP 0x2F
44880 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
44881 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
44882 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
44883 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44884 +#define HMAN_OC_IP_MANIP 0x34
44885 +#define HMAN_OC_IP_FRAGMENTATION 0x74
44886 +#define HMAN_OC_IP_REASSEMBLY 0xB4
44887 +#define HMAN_OC_IPSEC_MANIP 0xF4
44888 +#define HMAN_OC 0x35
44889 +
44890 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44891 +#define HMAN_RMV_HDR 0x80000000
44892 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
44893 +
44894 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
44895 +#define UDP_CHECKSUM_FIELD_SIZE 2
44896 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
44897 +
44898 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
44899 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
44900 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
44901 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
44902 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
44903 +
44904 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
44905 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
44906 +
44907 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
44908 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
44909 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
44910 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
44911 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
44912 +
44913 +
44914 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
44915 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
44916 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
44917 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
44918 +
44919 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
44920 +
44921 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
44922 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
44923 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
44924 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44925 +
44926 +#if (DPAA_VERSION >= 11)
44927 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
44928 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
44929 +
44930 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
44931 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
44932 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
44933 +
44934 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
44935 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
44936 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
44937 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
44938 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
44939 +#endif /* (DPAA_VERSION >= 11) */
44940 +
44941 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
44942 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
44943 +
44944 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
44945 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
44946 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
44947 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
44948 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
44949 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
44950 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
44951 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
44952 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
44953 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
44954 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
44955 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
44956 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
44957 +
44958 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
44959 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
44960 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
44961 +
44962 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
44963 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
44964 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
44965 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
44966 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
44967 +
44968 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
44969 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
44970 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
44971 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
44972 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
44973 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
44974 +
44975 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
44976 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
44977 +
44978 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
44979 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
44980 +
44981 +#define e_FM_MANIP_IP_INDX 1
44982 +
44983 +#define HMCD_OPCODE_GENERIC_RMV 0x01
44984 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
44985 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
44986 +#define HMCD_OPCODE_L2_RMV 0x08
44987 +#define HMCD_OPCODE_L2_INSRT 0x09
44988 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
44989 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
44990 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
44991 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
44992 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
44993 +#define HMCD_OPCODE_REPLACE_IP 0x12
44994 +#define HMCD_OPCODE_RMV_TILL 0x15
44995 +#define HMCD_OPCODE_UDP_INSRT 0x16
44996 +#define HMCD_OPCODE_IP_INSRT 0x17
44997 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
44998 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
44999 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
45000 +
45001 +#define HMCD_LAST 0x00800000
45002 +
45003 +#define HMCD_DSCP_VALUES 64
45004 +
45005 +#define HMCD_BASIC_SIZE 4
45006 +#define HMCD_PTR_SIZE 4
45007 +#define HMCD_PARAM_SIZE 4
45008 +#define HMCD_IPV4_ADDR_SIZE 4
45009 +#define HMCD_IPV6_ADDR_SIZE 0x10
45010 +#define HMCD_L4_HDR_SIZE 8
45011 +
45012 +#define HMCD_CAPWAP_INSRT 0x00010000
45013 +#define HMCD_INSRT_UDP_LITE 0x00010000
45014 +#define HMCD_IP_ID_MASK 0x0000FFFF
45015 +#define HMCD_IP_SIZE_MASK 0x0000FF00
45016 +#define HMCD_IP_SIZE_SHIFT 8
45017 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
45018 +#define HMCD_IP_OR_QOS 0x00010000
45019 +#define HMCD_IP_L4_CS_CALC 0x00040000
45020 +#define HMCD_IP_DF_MODE 0x00400000
45021 +
45022 +
45023 +#define HMCD_OC_SHIFT 24
45024 +
45025 +#define HMCD_RMV_OFFSET_SHIFT 0
45026 +#define HMCD_RMV_SIZE_SHIFT 8
45027 +
45028 +#define HMCD_INSRT_OFFSET_SHIFT 0
45029 +#define HMCD_INSRT_SIZE_SHIFT 8
45030 +
45031 +#define HMTD_CFG_TYPE 0x4000
45032 +#define HMTD_CFG_EXT_HMCT 0x0080
45033 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
45034 +#define HMTD_CFG_NEXT_AD_EN 0x0020
45035 +
45036 +#define HMCD_RMV_L2_ETHERNET 0
45037 +#define HMCD_RMV_L2_STACKED_QTAGS 1
45038 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
45039 +#define HMCD_RMV_L2_MPLS 3
45040 +#define HMCD_RMV_L2_PPPOE 4
45041 +
45042 +#define HMCD_INSRT_L2_MPLS 0
45043 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
45044 +#define HMCD_INSRT_L2_PPPOE 2
45045 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
45046 +
45047 +#define HMCD_L2_MODE_SHIFT 16
45048 +
45049 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
45050 +#define HMCD_VLAN_PRI_UPDATE 0
45051 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
45052 +
45053 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
45054 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
45055 +#define HMCD_IPV4_UPDATE_DST 0x00000020
45056 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
45057 +#define HMCD_IPV4_UPDATE_ID 0x00000080
45058 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
45059 +
45060 +#define HMCD_IPV6_UPDATE_HL 0x00000001
45061 +#define HMCD_IPV6_UPDATE_TC 0x00000002
45062 +#define HMCD_IPV6_UPDATE_DST 0x00000040
45063 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
45064 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
45065 +
45066 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
45067 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
45068 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
45069 +
45070 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
45071 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
45072 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
45073 +#define HMCD_IP_REPLACE_ID 0x00400000
45074 +
45075 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
45076 +
45077 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
45078 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
45079 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
45080 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
45081 +
45082 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
45083 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
45084 +
45085 +#define DSCP_TO_VLAN_TABLE_SIZE 32
45086 +
45087 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
45088 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
45089 +
45090 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
45091 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
45092 +
45093 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
45094 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
45095 +
45096 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
45097 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
45098 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
45099 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
45100 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
45101 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
45102 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
45103 +#define MANIP_FREE_HMTD(h_Manip) \
45104 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
45105 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
45106 + else \
45107 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
45108 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
45109 + }
45110 +/* position regarding Manip SW structure */
45111 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
45112 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
45113 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
45114 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
45115 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
45116 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
45117 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
45118 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
45119 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
45120 +
45121 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
45122 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
45123 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
45124 +
45125 +typedef enum e_ManipUnifiedPosition {
45126 + e_MANIP_UNIFIED_NONE = 0,
45127 + e_MANIP_UNIFIED_FIRST,
45128 + e_MANIP_UNIFIED_MID,
45129 + e_MANIP_UNIFIED_LAST
45130 +} e_ManipUnifiedPosition;
45131 +
45132 +typedef enum e_ManipInfo {
45133 + e_MANIP_HMTD,
45134 + e_MANIP_HMCT,
45135 + e_MANIP_HANDLER_TABLE_OWNER
45136 +}e_ManipInfo;
45137 +/***********************************************************************/
45138 +/* Memory map */
45139 +/***********************************************************************/
45140 +#if defined(__MWERKS__) && !defined(__GNUC__)
45141 +#pragma pack(push,1)
45142 +#endif /* defined(__MWERKS__) && ... */
45143 +
45144 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45145 +typedef struct t_CapwapReasmPram {
45146 + volatile uint32_t mode;
45147 + volatile uint32_t autoLearnHashTblPtr;
45148 + volatile uint32_t intStatsTblPtr;
45149 + volatile uint32_t reasmFrmDescPoolTblPtr;
45150 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
45151 + volatile uint32_t timeOutTblPtr;
45152 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
45153 + volatile uint32_t risc23SetIndexes;
45154 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
45155 + volatile uint32_t extendedStatsTblPtr;
45156 + volatile uint32_t expirationDelay;
45157 + volatile uint32_t totalProcessedFragCounter;
45158 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
45159 + volatile uint32_t totalDuplicatedFragCounter;
45160 + volatile uint32_t totalMalformdFragCounter;
45161 + volatile uint32_t totalTimeOutCounter;
45162 + volatile uint32_t totalSetBusyCounter;
45163 + volatile uint32_t totalRfdPoolBusyCounter;
45164 + volatile uint32_t totalDiscardedFragsCounter;
45165 + volatile uint32_t totalMoreThan16FramesCounter;
45166 + volatile uint32_t internalBufferBusy;
45167 + volatile uint32_t externalBufferBusy;
45168 + volatile uint32_t reserved1[4];
45169 +} t_CapwapReasmPram;
45170 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45171 +
45172 +typedef _Packed struct t_ReassTbl {
45173 + volatile uint16_t waysNumAndSetSize;
45174 + volatile uint16_t autoLearnHashKeyMask;
45175 + volatile uint32_t reassCommonPrmTblPtr;
45176 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
45177 + volatile uint32_t autoLearnHashTblPtrLow;
45178 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
45179 + volatile uint32_t autoLearnSetLockTblPtrLow;
45180 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
45181 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
45182 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
45183 + volatile uint32_t totalValidFragmentCounter;
45184 + volatile uint32_t totalProcessedFragCounter;
45185 + volatile uint32_t totalMalformdFragCounter;
45186 + volatile uint32_t totalSetBusyCounter;
45187 + volatile uint32_t totalDiscardedFragsCounter;
45188 + volatile uint32_t totalMoreThan16FramesCounter;
45189 + volatile uint32_t reserved2[2];
45190 +} _PackedType t_ReassTbl;
45191 +
45192 +typedef struct t_ReassCommonTbl {
45193 + volatile uint32_t timeoutModeAndFqid;
45194 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
45195 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
45196 + volatile uint32_t reassFrmDescPoolPtrLow;
45197 + volatile uint32_t timeOutTblPtr;
45198 + volatile uint32_t expirationDelay;
45199 + volatile uint32_t internalBufferManagement;
45200 + volatile uint32_t reserved2;
45201 + volatile uint32_t totalTimeOutCounter;
45202 + volatile uint32_t totalRfdPoolBusyCounter;
45203 + volatile uint32_t totalInternalBufferBusy;
45204 + volatile uint32_t totalExternalBufferBusy;
45205 + volatile uint32_t totalSgFragmentCounter;
45206 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
45207 + volatile uint32_t totalNCSPCounter;
45208 + volatile uint32_t discardMask;
45209 +} t_ReassCommonTbl;
45210 +
45211 +typedef _Packed struct t_Hmtd {
45212 + volatile uint16_t cfg;
45213 + volatile uint8_t eliodnOffset;
45214 + volatile uint8_t extHmcdBasePtrHi;
45215 + volatile uint32_t hmcdBasePtr;
45216 + volatile uint16_t nextAdIdx;
45217 + volatile uint8_t res1;
45218 + volatile uint8_t opCode;
45219 + volatile uint32_t res2;
45220 +} _PackedType t_Hmtd;
45221 +
45222 +#if defined(__MWERKS__) && !defined(__GNUC__)
45223 +#pragma pack(pop)
45224 +#endif /* defined(__MWERKS__) && ... */
45225 +
45226 +
45227 +/***********************************************************************/
45228 +/* Driver's internal structures */
45229 +/***********************************************************************/
45230 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45231 +typedef struct
45232 +{
45233 + t_Handle p_AutoLearnHashTbl;
45234 + t_Handle p_ReassmFrmDescrPoolTbl;
45235 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
45236 + t_Handle p_TimeOutTbl;
45237 + uint16_t maxNumFramesInProcess;
45238 + uint8_t numOfTasks;
45239 + //uint8_t poolId;
45240 + uint8_t prOffset;
45241 + uint16_t dataOffset;
45242 + uint8_t sgBpid;
45243 + uint8_t hwPortId;
45244 + uint32_t fqidForTimeOutFrames;
45245 + uint32_t timeoutRoutineRequestTime;
45246 + uint32_t bitFor1Micro;
45247 +} t_CapwapFragParams;
45248 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45249 +
45250 +typedef struct
45251 +{
45252 + t_AdOfTypeContLookup *p_Frag;
45253 +#if (DPAA_VERSION == 10)
45254 + uint8_t scratchBpid;
45255 +#endif /* (DPAA_VERSION == 10) */
45256 +} t_FragParams;
45257 +
45258 +typedef struct t_ReassmParams
45259 +{
45260 + e_NetHeaderType hdr; /* Header selection */
45261 + t_ReassCommonTbl *p_ReassCommonTbl;
45262 + uintptr_t reassFrmDescrIndxPoolTblAddr;
45263 + uintptr_t reassFrmDescrPoolTblAddr;
45264 + uintptr_t timeOutTblAddr;
45265 + uintptr_t internalBufferPoolManagementIndexAddr;
45266 + uintptr_t internalBufferPoolAddr;
45267 + uint32_t maxNumFramesInProcess;
45268 + uint8_t sgBpid;
45269 + uint8_t dataMemId;
45270 + uint16_t dataLiodnOffset;
45271 + uint32_t fqidForTimeOutFrames;
45272 + e_FmPcdManipReassemTimeOutMode timeOutMode;
45273 + uint32_t timeoutThresholdForReassmProcess;
45274 + union {
45275 + struct {
45276 + t_Handle h_Ipv4Ad;
45277 + t_Handle h_Ipv6Ad;
45278 + bool ipv6Assigned;
45279 + t_ReassTbl *p_Ipv4ReassTbl;
45280 + t_ReassTbl *p_Ipv6ReassTbl;
45281 + uintptr_t ipv4AutoLearnHashTblAddr;
45282 + uintptr_t ipv6AutoLearnHashTblAddr;
45283 + uintptr_t ipv4AutoLearnSetLockTblAddr;
45284 + uintptr_t ipv6AutoLearnSetLockTblAddr;
45285 + uint16_t minFragSize[2];
45286 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
45287 + uint8_t relativeSchemeId[2];
45288 + t_Handle h_Ipv4Scheme;
45289 + t_Handle h_Ipv6Scheme;
45290 + uint32_t nonConsistentSpFqid;
45291 + } ip;
45292 + struct {
45293 + t_Handle h_Ad;
45294 + t_ReassTbl *p_ReassTbl;
45295 + uintptr_t autoLearnHashTblAddr;
45296 + uintptr_t autoLearnSetLockTblAddr;
45297 + uint16_t maxRessembledsSize;
45298 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
45299 + uint8_t relativeSchemeId;
45300 + t_Handle h_Scheme;
45301 + } capwap;
45302 + };
45303 +} t_ReassmParams;
45304 +
45305 +typedef struct{
45306 + e_FmPcdManipType type;
45307 + t_FmPcdManipParams manipParams;
45308 + bool muramAllocate;
45309 + t_Handle h_Ad;
45310 + uint32_t opcode;
45311 + bool rmv;
45312 + bool insrt;
45313 + t_Handle h_NextManip;
45314 + t_Handle h_PrevManip;
45315 + e_FmPcdManipType nextManipType;
45316 + /* HdrManip parameters*/
45317 + uint8_t *p_Hmct;
45318 + uint8_t *p_Data;
45319 + bool dontParseAfterManip;
45320 + bool fieldUpdate;
45321 + bool custom;
45322 + uint16_t tableSize;
45323 + uint8_t dataSize;
45324 + bool cascaded;
45325 + e_ManipUnifiedPosition unifiedPosition;
45326 + /* end HdrManip */
45327 + uint8_t *p_Template;
45328 + uint16_t owner;
45329 + uint32_t updateParams;
45330 + uint32_t shadowUpdateParams;
45331 + bool frag;
45332 + bool reassm;
45333 + uint16_t sizeForFragmentation;
45334 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45335 + t_Handle h_Frag;
45336 + t_CapwapFragParams capwapFragParams;
45337 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45338 + union {
45339 + t_ReassmParams reassmParams;
45340 + t_FragParams fragParams;
45341 + };
45342 + uint8_t icOffset;
45343 + uint16_t ownerTmp;
45344 + bool cnia;
45345 + t_Handle p_StatsTbl;
45346 + t_Handle h_FmPcd;
45347 + t_List nodesLst;
45348 + t_Handle h_Spinlock;
45349 +} t_FmPcdManip;
45350 +
45351 +typedef struct t_FmPcdCcSavedManipParams
45352 +{
45353 + union
45354 + {
45355 + struct
45356 + {
45357 + uint16_t dataOffset;
45358 + //uint8_t poolId;
45359 + }capwapParams;
45360 + struct
45361 + {
45362 + uint16_t dataOffset;
45363 + uint8_t poolId;
45364 + }ipParams;
45365 + };
45366 +
45367 +} t_FmPcdCcSavedManipParams;
45368 +
45369 +
45370 +#endif /* __FM_MANIP_H */
45371 --- /dev/null
45372 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
45373 @@ -0,0 +1,2095 @@
45374 +/*
45375 + * Copyright 2008-2012 Freescale Semiconductor Inc.
45376 + *
45377 + * Redistribution and use in source and binary forms, with or without
45378 + * modification, are permitted provided that the following conditions are met:
45379 + * * Redistributions of source code must retain the above copyright
45380 + * notice, this list of conditions and the following disclaimer.
45381 + * * Redistributions in binary form must reproduce the above copyright
45382 + * notice, this list of conditions and the following disclaimer in the
45383 + * documentation and/or other materials provided with the distribution.
45384 + * * Neither the name of Freescale Semiconductor nor the
45385 + * names of its contributors may be used to endorse or promote products
45386 + * derived from this software without specific prior written permission.
45387 + *
45388 + *
45389 + * ALTERNATIVELY, this software may be distributed under the terms of the
45390 + * GNU General Public License ("GPL") as published by the Free Software
45391 + * Foundation, either version 2 of that License or (at your option) any
45392 + * later version.
45393 + *
45394 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
45395 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45396 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45397 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
45398 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45399 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45400 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45401 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45402 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45403 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45404 + */
45405 +
45406 +
45407 +/******************************************************************************
45408 + @File fm_pcd.c
45409 +
45410 + @Description FM PCD ...
45411 +*//***************************************************************************/
45412 +#include "std_ext.h"
45413 +#include "error_ext.h"
45414 +#include "string_ext.h"
45415 +#include "xx_ext.h"
45416 +#include "sprint_ext.h"
45417 +#include "debug_ext.h"
45418 +#include "net_ext.h"
45419 +#include "fm_ext.h"
45420 +#include "fm_pcd_ext.h"
45421 +
45422 +#include "fm_common.h"
45423 +#include "fm_pcd.h"
45424 +#include "fm_pcd_ipc.h"
45425 +#include "fm_hc.h"
45426 +#include "fm_muram_ext.h"
45427 +
45428 +
45429 +/****************************************/
45430 +/* static functions */
45431 +/****************************************/
45432 +
45433 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
45434 +{
45435 + if (!p_FmPcd->h_Fm)
45436 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
45437 +
45438 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
45439 + {
45440 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
45441 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
45442 +
45443 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
45444 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
45445 +
45446 + if (!p_FmPcd->f_Exception)
45447 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
45448 +
45449 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
45450 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
45451 +
45452 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
45453 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
45454 + }
45455 +
45456 + return E_OK;
45457 +}
45458 +
45459 +static volatile bool blockingFlag = FALSE;
45460 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
45461 + uint8_t *p_Msg,
45462 + uint8_t *p_Reply,
45463 + uint32_t replyLength,
45464 + t_Error status)
45465 +{
45466 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
45467 + blockingFlag = FALSE;
45468 +}
45469 +
45470 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
45471 + uint8_t *p_Msg,
45472 + uint32_t msgLength,
45473 + uint8_t *p_Reply,
45474 + uint32_t *p_ReplyLength)
45475 +{
45476 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45477 + t_Error err = E_OK;
45478 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
45479 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
45480 +
45481 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45482 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
45483 +
45484 +#ifdef DISABLE_SANITY_CHECKS
45485 + UNUSED(msgLength);
45486 +#endif /* DISABLE_SANITY_CHECKS */
45487 +
45488 + ASSERT_COND(p_Msg);
45489 +
45490 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
45491 + *p_ReplyLength = 0;
45492 +
45493 + switch (p_IpcMsg->msgId)
45494 + {
45495 + case (FM_PCD_MASTER_IS_ALIVE):
45496 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
45497 + p_IpcReply->error = E_OK;
45498 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
45499 + break;
45500 + case (FM_PCD_MASTER_IS_ENABLED):
45501 + /* count partitions registrations */
45502 + if (p_FmPcd->enabled)
45503 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
45504 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
45505 + p_IpcReply->error = E_OK;
45506 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
45507 + break;
45508 + case (FM_PCD_GUEST_DISABLE):
45509 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
45510 + {
45511 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
45512 + p_IpcReply->error = E_OK;
45513 + }
45514 + else
45515 + {
45516 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
45517 + p_IpcReply->error = E_INVALID_STATE;
45518 + }
45519 + *p_ReplyLength = sizeof(uint32_t);
45520 + break;
45521 + case (FM_PCD_GET_COUNTER):
45522 + {
45523 + e_FmPcdCounters inCounter;
45524 + uint32_t outCounter;
45525 +
45526 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
45527 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
45528 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
45529 + p_IpcReply->error = E_OK;
45530 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
45531 + break;
45532 + }
45533 + case (FM_PCD_ALLOC_KG_SCHEMES):
45534 + {
45535 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
45536 +
45537 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
45538 + err = FmPcdKgAllocSchemes(h_FmPcd,
45539 + ipcSchemesParams.numOfSchemes,
45540 + ipcSchemesParams.guestId,
45541 + p_IpcReply->replyBody);
45542 + p_IpcReply->error = err;
45543 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
45544 + break;
45545 + }
45546 + case (FM_PCD_FREE_KG_SCHEMES):
45547 + {
45548 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
45549 +
45550 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
45551 + err = FmPcdKgFreeSchemes(h_FmPcd,
45552 + ipcSchemesParams.numOfSchemes,
45553 + ipcSchemesParams.guestId,
45554 + ipcSchemesParams.schemesIds);
45555 + p_IpcReply->error = err;
45556 + *p_ReplyLength = sizeof(uint32_t);
45557 + break;
45558 + }
45559 + case (FM_PCD_ALLOC_KG_CLSPLAN):
45560 + {
45561 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
45562 +
45563 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
45564 + err = KgAllocClsPlanEntries(h_FmPcd,
45565 + ipcKgClsPlanParams.numOfClsPlanEntries,
45566 + ipcKgClsPlanParams.guestId,
45567 + p_IpcReply->replyBody);
45568 + p_IpcReply->error = err;
45569 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
45570 + break;
45571 + }
45572 + case (FM_PCD_FREE_KG_CLSPLAN):
45573 + {
45574 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
45575 +
45576 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
45577 + KgFreeClsPlanEntries(h_FmPcd,
45578 + ipcKgClsPlanParams.numOfClsPlanEntries,
45579 + ipcKgClsPlanParams.guestId,
45580 + ipcKgClsPlanParams.clsPlanBase);
45581 + *p_ReplyLength = sizeof(uint32_t);
45582 + break;
45583 + }
45584 + case (FM_PCD_ALLOC_PROFILES):
45585 + {
45586 + t_FmIpcResourceAllocParams ipcAllocParams;
45587 + uint16_t base;
45588 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45589 + base = PlcrAllocProfilesForPartition(h_FmPcd,
45590 + ipcAllocParams.base,
45591 + ipcAllocParams.num,
45592 + ipcAllocParams.guestId);
45593 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
45594 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
45595 + break;
45596 + }
45597 + case (FM_PCD_FREE_PROFILES):
45598 + {
45599 + t_FmIpcResourceAllocParams ipcAllocParams;
45600 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45601 + PlcrFreeProfilesForPartition(h_FmPcd,
45602 + ipcAllocParams.base,
45603 + ipcAllocParams.num,
45604 + ipcAllocParams.guestId);
45605 + break;
45606 + }
45607 + case (FM_PCD_SET_PORT_PROFILES):
45608 + {
45609 + t_FmIpcResourceAllocParams ipcAllocParams;
45610 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45611 + PlcrSetPortProfiles(h_FmPcd,
45612 + ipcAllocParams.guestId,
45613 + ipcAllocParams.num,
45614 + ipcAllocParams.base);
45615 + break;
45616 + }
45617 + case (FM_PCD_CLEAR_PORT_PROFILES):
45618 + {
45619 + t_FmIpcResourceAllocParams ipcAllocParams;
45620 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45621 + PlcrClearPortProfiles(h_FmPcd,
45622 + ipcAllocParams.guestId);
45623 + break;
45624 + }
45625 + case (FM_PCD_GET_SW_PRS_OFFSET):
45626 + {
45627 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
45628 + uint32_t swPrsOffset;
45629 +
45630 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
45631 + swPrsOffset =
45632 + FmPcdGetSwPrsOffset(h_FmPcd,
45633 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
45634 + ipcSwPrsLable.indexPerHdr);
45635 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
45636 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
45637 + break;
45638 + }
45639 + case (FM_PCD_PRS_INC_PORT_STATS):
45640 + {
45641 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
45642 +
45643 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
45644 + PrsIncludePortInStatistics(h_FmPcd,
45645 + ipcPrsIncludePort.hardwarePortId,
45646 + ipcPrsIncludePort.include);
45647 + break;
45648 + }
45649 + default:
45650 + *p_ReplyLength = 0;
45651 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
45652 + }
45653 + return E_OK;
45654 +}
45655 +
45656 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
45657 +{
45658 + ASSERT_COND(h_NetEnv);
45659 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
45660 +}
45661 +
45662 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
45663 +{
45664 + ASSERT_COND(h_NetEnv);
45665 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
45666 +}
45667 +
45668 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
45669 +{
45670 + uint32_t intFlags;
45671 +
45672 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
45673 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
45674 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
45675 +}
45676 +
45677 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
45678 +{
45679 + t_FmPcdLock *p_Lock = NULL;
45680 + uint32_t intFlags;
45681 +
45682 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
45683 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
45684 + {
45685 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
45686 + LIST_DelAndInit(&p_Lock->node);
45687 + }
45688 + if (p_FmPcd->h_Spinlock)
45689 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
45690 +
45691 + return p_Lock;
45692 +}
45693 +
45694 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
45695 +{
45696 + uint32_t intFlags;
45697 +
45698 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
45699 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
45700 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
45701 +}
45702 +
45703 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
45704 +{
45705 + t_FmPcdLock *p_Lock;
45706 + int i;
45707 +
45708 + for (i=0; i<10; i++)
45709 + {
45710 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
45711 + if (!p_Lock)
45712 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
45713 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
45714 + INIT_LIST(&p_Lock->node);
45715 + p_Lock->h_Spinlock = XX_InitSpinlock();
45716 + if (!p_Lock->h_Spinlock)
45717 + {
45718 + XX_Free(p_Lock);
45719 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
45720 + }
45721 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
45722 + }
45723 +
45724 + return E_OK;
45725 +}
45726 +
45727 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
45728 +{
45729 + t_FmPcdLock *p_Lock;
45730 +
45731 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
45732 + while (p_Lock)
45733 + {
45734 + XX_FreeSpinlock(p_Lock->h_Spinlock);
45735 + XX_Free(p_Lock);
45736 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
45737 + }
45738 +}
45739 +
45740 +
45741 +
45742 +/*****************************************************************************/
45743 +/* Inter-module API routines */
45744 +/*****************************************************************************/
45745 +
45746 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
45747 +{
45748 + ASSERT_COND(p_FmPcd);
45749 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
45750 +}
45751 +
45752 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
45753 +{
45754 + uint8_t netEnvId = p_GrpParams->netEnvId;
45755 + int i, k, j;
45756 +
45757 + ASSERT_COND(p_FmPcd);
45758 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
45759 + {
45760 + p_GrpParams->grpExists = TRUE;
45761 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
45762 + return E_OK;
45763 + }
45764 +
45765 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
45766 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
45767 + {
45768 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
45769 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
45770 + {
45771 + /* if an option exists, add it to the opts list */
45772 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
45773 + {
45774 + /* check if this option already exists, add if it doesn't */
45775 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
45776 + {
45777 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
45778 + break;
45779 + }
45780 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
45781 + if (j == p_GrpParams->numOfOptions)
45782 + {
45783 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
45784 + p_GrpParams->numOfOptions++;
45785 + }
45786 + }
45787 + }
45788 + }
45789 +
45790 + if (p_GrpParams->numOfOptions == 0)
45791 + {
45792 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
45793 + {
45794 + p_GrpParams->grpExists = TRUE;
45795 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
45796 + }
45797 + }
45798 +
45799 + return E_OK;
45800 +
45801 +}
45802 +
45803 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
45804 +{
45805 + uint8_t j,k;
45806 +
45807 + *p_Vector = 0;
45808 +
45809 + ASSERT_COND(p_FmPcd);
45810 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
45811 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
45812 + {
45813 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
45814 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
45815 + {
45816 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
45817 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
45818 + }
45819 + }
45820 +
45821 + if (!*p_Vector)
45822 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
45823 + else
45824 + return E_OK;
45825 +}
45826 +
45827 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
45828 +{
45829 + int i;
45830 +
45831 + ASSERT_COND(p_FmPcd);
45832 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
45833 +
45834 + p_Params->vector = 0;
45835 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
45836 + {
45837 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
45838 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
45839 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
45840 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
45841 + }
45842 +
45843 + return E_OK;
45844 +}
45845 +
45846 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
45847 +{
45848 + int i=0, k;
45849 +
45850 + ASSERT_COND(p_FmPcd);
45851 + /* check whether a given unit may be used by non-clsPlan users. */
45852 + /* first, recognize the unit by its vector */
45853 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
45854 + {
45855 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
45856 + {
45857 + for (k=0;
45858 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
45859 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
45860 + k++)
45861 + /* check that no option exists */
45862 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
45863 + return FALSE;
45864 + break;
45865 + }
45866 + i++;
45867 + }
45868 + /* assert that a unit was found to mach the vector */
45869 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
45870 +
45871 + return TRUE;
45872 +}
45873 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
45874 +{
45875 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45876 + int i, k;
45877 +
45878 + ASSERT_COND(p_FmPcd);
45879 +
45880 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
45881 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
45882 + {
45883 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
45884 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
45885 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
45886 + return TRUE;
45887 + }
45888 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
45889 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
45890 + {
45891 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
45892 + return TRUE;
45893 + }
45894 +
45895 + return FALSE;
45896 +}
45897 +
45898 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
45899 +{
45900 + uint8_t i, k;
45901 +
45902 + ASSERT_COND(p_FmPcd);
45903 +
45904 + if (interchangeable)
45905 + {
45906 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
45907 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45908 + {
45909 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
45910 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45911 + {
45912 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
45913 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
45914 +
45915 + return i;
45916 + }
45917 + }
45918 + }
45919 + else
45920 + {
45921 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
45922 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45923 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
45924 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
45925 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
45926 + return i;
45927 +
45928 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
45929 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
45930 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
45931 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
45932 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
45933 + }
45934 +
45935 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
45936 +}
45937 +
45938 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
45939 +{
45940 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45941 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
45942 + uint8_t result;
45943 + t_Error err = E_OK;
45944 +
45945 + ASSERT_COND(p_FmPcd);
45946 + ASSERT_COND(h_ReasmCommonPramTbl);
45947 +
45948 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
45949 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
45950 +
45951 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
45952 + RETURN_ERROR(MAJOR, err, NO_MSG);
45953 +
45954 + switch (result)
45955 + {
45956 + case (0):
45957 + return E_OK;
45958 + case (1):
45959 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
45960 + case (2):
45961 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
45962 + case (3):
45963 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
45964 + default:
45965 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
45966 + }
45967 +
45968 + return E_OK;
45969 +}
45970 +
45971 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
45972 +{
45973 + int i;
45974 +
45975 + ASSERT_COND(p_FmPcd);
45976 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
45977 +
45978 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
45979 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
45980 + {
45981 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
45982 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
45983 + }
45984 +
45985 + return HEADER_TYPE_NONE;
45986 +}
45987 +
45988 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
45989 +{
45990 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45991 + uint16_t swPortIndex = 0;
45992 +
45993 + ASSERT_COND(h_FmPcd);
45994 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
45995 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
45996 +}
45997 +
45998 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
45999 +{
46000 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46001 +
46002 + ASSERT_COND(h_FmPcd);
46003 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
46004 +}
46005 +
46006 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
46007 +{
46008 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46009 +
46010 + ASSERT_COND(h_FmPcd);
46011 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
46012 +}
46013 +
46014 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
46015 +{
46016 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
46017 +}
46018 +
46019 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
46020 +{
46021 + uint32_t intFlags;
46022 +
46023 + ASSERT_COND(h_FmPcd);
46024 +
46025 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
46026 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
46027 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
46028 +}
46029 +
46030 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
46031 +{
46032 + uint32_t intFlags;
46033 +
46034 + ASSERT_COND(h_FmPcd);
46035 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
46036 +
46037 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
46038 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
46039 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
46040 +}
46041 +
46042 +uint32_t FmPcdLock(t_Handle h_FmPcd)
46043 +{
46044 + ASSERT_COND(h_FmPcd);
46045 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
46046 +}
46047 +
46048 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
46049 +{
46050 + ASSERT_COND(h_FmPcd);
46051 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
46052 +}
46053 +
46054 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
46055 +{
46056 + t_FmPcdLock *p_Lock;
46057 + ASSERT_COND(h_FmPcd);
46058 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
46059 + if (!p_Lock)
46060 + {
46061 + FillFreeLocksLst(h_FmPcd);
46062 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
46063 + }
46064 +
46065 + if (p_Lock)
46066 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
46067 + return p_Lock;
46068 +}
46069 +
46070 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
46071 +{
46072 + uint32_t intFlags;
46073 + ASSERT_COND(h_FmPcd);
46074 + intFlags = FmPcdLock(h_FmPcd);
46075 + LIST_DelAndInit(&p_Lock->node);
46076 + FmPcdUnlock(h_FmPcd, intFlags);
46077 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
46078 +}
46079 +
46080 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
46081 +{
46082 + uint32_t intFlags;
46083 + t_List *p_Pos, *p_SavedPos=NULL;
46084 +
46085 + ASSERT_COND(h_FmPcd);
46086 + intFlags = FmPcdLock(h_FmPcd);
46087 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
46088 + {
46089 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
46090 + if (!FmPcdLockTryLock(p_Lock))
46091 + {
46092 + p_SavedPos = p_Pos;
46093 + break;
46094 + }
46095 + }
46096 + if (p_SavedPos)
46097 + {
46098 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
46099 + {
46100 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
46101 + if (p_Pos == p_SavedPos)
46102 + break;
46103 + FmPcdLockUnlock(p_Lock);
46104 + }
46105 + }
46106 + FmPcdUnlock(h_FmPcd, intFlags);
46107 +
46108 + CORE_MemoryBarrier();
46109 +
46110 + if (p_SavedPos)
46111 + return FALSE;
46112 +
46113 + return TRUE;
46114 +}
46115 +
46116 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
46117 +{
46118 + uint32_t intFlags;
46119 + t_List *p_Pos;
46120 +
46121 + ASSERT_COND(h_FmPcd);
46122 + intFlags = FmPcdLock(h_FmPcd);
46123 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
46124 + {
46125 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
46126 + p_Lock->flag = FALSE;
46127 + }
46128 + FmPcdUnlock(h_FmPcd, intFlags);
46129 +
46130 + CORE_MemoryBarrier();
46131 +}
46132 +
46133 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
46134 +{
46135 + ASSERT_COND(h_FmPcd);
46136 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
46137 +
46138 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
46139 +}
46140 +
46141 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
46142 +{
46143 + ASSERT_COND(h_FmPcd);
46144 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
46145 +}
46146 +
46147 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
46148 +{
46149 + ASSERT_COND(h_FmPcd);
46150 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
46151 +}
46152 +/*********************** End of inter-module routines ************************/
46153 +
46154 +
46155 +/****************************************/
46156 +/* API Init unit functions */
46157 +/****************************************/
46158 +
46159 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
46160 +{
46161 + t_FmPcd *p_FmPcd = NULL;
46162 + t_FmPhysAddr physicalMuramBase;
46163 + uint8_t i;
46164 +
46165 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
46166 +
46167 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
46168 + if (!p_FmPcd)
46169 + {
46170 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
46171 + return NULL;
46172 + }
46173 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
46174 +
46175 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
46176 + if (!p_FmPcd->p_FmPcdDriverParam)
46177 + {
46178 + XX_Free(p_FmPcd);
46179 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
46180 + return NULL;
46181 + }
46182 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
46183 +
46184 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
46185 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
46186 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
46187 + if (p_FmPcd->h_FmMuram)
46188 + {
46189 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
46190 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
46191 + }
46192 +
46193 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
46194 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
46195 +
46196 + if (p_FmPcdParams->useHostCommand)
46197 + {
46198 + t_FmHcParams hcParams;
46199 +
46200 + memset(&hcParams, 0, sizeof(hcParams));
46201 + hcParams.h_Fm = p_FmPcd->h_Fm;
46202 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
46203 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
46204 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
46205 + if (!p_FmPcd->h_Hc)
46206 + {
46207 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
46208 + FM_PCD_Free(p_FmPcd);
46209 + return NULL;
46210 + }
46211 + }
46212 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
46213 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
46214 +
46215 + if (p_FmPcdParams->kgSupport)
46216 + {
46217 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
46218 + if (!p_FmPcd->p_FmPcdKg)
46219 + {
46220 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
46221 + FM_PCD_Free(p_FmPcd);
46222 + return NULL;
46223 + }
46224 + }
46225 +
46226 + if (p_FmPcdParams->plcrSupport)
46227 + {
46228 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
46229 + if (!p_FmPcd->p_FmPcdPlcr)
46230 + {
46231 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
46232 + FM_PCD_Free(p_FmPcd);
46233 + return NULL;
46234 + }
46235 + }
46236 +
46237 + if (p_FmPcdParams->prsSupport)
46238 + {
46239 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
46240 + if (!p_FmPcd->p_FmPcdPrs)
46241 + {
46242 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
46243 + FM_PCD_Free(p_FmPcd);
46244 + return NULL;
46245 + }
46246 + }
46247 +
46248 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
46249 + if (!p_FmPcd->h_Spinlock)
46250 + {
46251 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
46252 + FM_PCD_Free(p_FmPcd);
46253 + return NULL;
46254 + }
46255 + INIT_LIST(&p_FmPcd->freeLocksLst);
46256 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
46257 +
46258 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
46259 +
46260 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
46261 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
46262 + p_FmPcd->h_App = p_FmPcdParams->h_App;
46263 +
46264 + p_FmPcd->p_CcShadow = NULL;
46265 + p_FmPcd->ccShadowSize = 0;
46266 + p_FmPcd->ccShadowAlign = 0;
46267 +
46268 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
46269 + if (!p_FmPcd->h_ShadowSpinlock)
46270 + {
46271 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
46272 + FM_PCD_Free(p_FmPcd);
46273 + return NULL;
46274 + }
46275 +
46276 + return p_FmPcd;
46277 +}
46278 +
46279 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
46280 +{
46281 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46282 + t_Error err = E_OK;
46283 + t_FmPcdIpcMsg msg;
46284 +
46285 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46286 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
46287 +
46288 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
46289 +
46290 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
46291 + {
46292 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
46293 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
46294 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
46295 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
46296 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
46297 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
46298 +
46299 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
46300 + if (p_FmPcd->h_IpcSession)
46301 + {
46302 + t_FmPcdIpcReply reply;
46303 + uint32_t replyLength;
46304 + uint8_t isMasterAlive = 0;
46305 +
46306 + memset(&msg, 0, sizeof(msg));
46307 + memset(&reply, 0, sizeof(reply));
46308 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
46309 + msg.msgBody[0] = p_FmPcd->guestId;
46310 + blockingFlag = TRUE;
46311 +
46312 + do
46313 + {
46314 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
46315 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
46316 + (uint8_t*)&msg,
46317 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
46318 + (uint8_t*)&reply,
46319 + &replyLength,
46320 + IpcMsgCompletionCB,
46321 + h_FmPcd)) != E_OK)
46322 + REPORT_ERROR(MAJOR, err, NO_MSG);
46323 + while (blockingFlag) ;
46324 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
46325 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
46326 + isMasterAlive = *(uint8_t*)(reply.replyBody);
46327 + } while (!isMasterAlive);
46328 + }
46329 + }
46330 +
46331 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
46332 +
46333 + if (p_FmPcd->p_FmPcdKg)
46334 + {
46335 + err = KgInit(p_FmPcd);
46336 + if (err)
46337 + RETURN_ERROR(MAJOR, err, NO_MSG);
46338 + }
46339 +
46340 + if (p_FmPcd->p_FmPcdPlcr)
46341 + {
46342 + err = PlcrInit(p_FmPcd);
46343 + if (err)
46344 + RETURN_ERROR(MAJOR, err, NO_MSG);
46345 + }
46346 +
46347 + if (p_FmPcd->p_FmPcdPrs)
46348 + {
46349 + err = PrsInit(p_FmPcd);
46350 + if (err)
46351 + RETURN_ERROR(MAJOR, err, NO_MSG);
46352 + }
46353 +
46354 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
46355 + {
46356 + /* register to inter-core messaging mechanism */
46357 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
46358 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
46359 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
46360 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
46361 + if (err)
46362 + RETURN_ERROR(MAJOR, err, NO_MSG);
46363 + }
46364 +
46365 + /* IPv6 Frame-Id used for fragmentation */
46366 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
46367 + if (!p_FmPcd->ipv6FrameIdAddr)
46368 + {
46369 + FM_PCD_Free(p_FmPcd);
46370 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
46371 + }
46372 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
46373 +
46374 + /* CAPWAP Frame-Id used for fragmentation */
46375 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
46376 + if (!p_FmPcd->capwapFrameIdAddr)
46377 + {
46378 + FM_PCD_Free(p_FmPcd);
46379 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
46380 + }
46381 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
46382 +
46383 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
46384 + p_FmPcd->p_FmPcdDriverParam = NULL;
46385 +
46386 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
46387 +
46388 + return E_OK;
46389 +}
46390 +
46391 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
46392 +{
46393 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
46394 + t_Error err = E_OK;
46395 +
46396 + if (p_FmPcd->ipv6FrameIdAddr)
46397 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
46398 +
46399 + if (p_FmPcd->capwapFrameIdAddr)
46400 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
46401 +
46402 + if (p_FmPcd->enabled)
46403 + FM_PCD_Disable(p_FmPcd);
46404 +
46405 + if (p_FmPcd->p_FmPcdDriverParam)
46406 + {
46407 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
46408 + p_FmPcd->p_FmPcdDriverParam = NULL;
46409 + }
46410 +
46411 + if (p_FmPcd->p_FmPcdKg)
46412 + {
46413 + if ((err = KgFree(p_FmPcd)) != E_OK)
46414 + RETURN_ERROR(MINOR, err, NO_MSG);
46415 + XX_Free(p_FmPcd->p_FmPcdKg);
46416 + p_FmPcd->p_FmPcdKg = NULL;
46417 + }
46418 +
46419 + if (p_FmPcd->p_FmPcdPlcr)
46420 + {
46421 + PlcrFree(p_FmPcd);
46422 + XX_Free(p_FmPcd->p_FmPcdPlcr);
46423 + p_FmPcd->p_FmPcdPlcr = NULL;
46424 + }
46425 +
46426 + if (p_FmPcd->p_FmPcdPrs)
46427 + {
46428 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
46429 + PrsFree(p_FmPcd);
46430 + XX_Free(p_FmPcd->p_FmPcdPrs);
46431 + p_FmPcd->p_FmPcdPrs = NULL;
46432 + }
46433 +
46434 + if (p_FmPcd->h_Hc)
46435 + {
46436 + FmHcFree(p_FmPcd->h_Hc);
46437 + p_FmPcd->h_Hc = NULL;
46438 + }
46439 +
46440 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
46441 +
46442 + FmUnregisterPcd(p_FmPcd->h_Fm);
46443 +
46444 + ReleaseFreeLocksLst(p_FmPcd);
46445 +
46446 + if (p_FmPcd->h_Spinlock)
46447 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
46448 +
46449 + if (p_FmPcd->h_ShadowSpinlock)
46450 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
46451 +
46452 + XX_Free(p_FmPcd);
46453 +
46454 + return E_OK;
46455 +}
46456 +
46457 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
46458 +{
46459 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46460 + uint32_t bitMask = 0;
46461 +
46462 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46463 +
46464 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
46465 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
46466 +
46467 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
46468 + if (bitMask)
46469 + {
46470 + if (enable)
46471 + p_FmPcd->exceptions |= bitMask;
46472 + else
46473 + p_FmPcd->exceptions &= ~bitMask;
46474 + }
46475 + else
46476 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
46477 +
46478 + return E_OK;
46479 +}
46480 +
46481 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
46482 +{
46483 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46484 +
46485 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46486 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
46487 +
46488 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
46489 +}
46490 +
46491 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
46492 +{
46493 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46494 + t_Error err = E_OK;
46495 +
46496 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
46497 +
46498 + if (p_FmPcd->enabled)
46499 + return E_OK;
46500 +
46501 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
46502 + p_FmPcd->h_IpcSession)
46503 + {
46504 + uint8_t enabled;
46505 + t_FmPcdIpcMsg msg;
46506 + t_FmPcdIpcReply reply;
46507 + uint32_t replyLength;
46508 +
46509 + memset(&reply, 0, sizeof(reply));
46510 + memset(&msg, 0, sizeof(msg));
46511 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
46512 + replyLength = sizeof(uint32_t) + sizeof(enabled);
46513 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
46514 + (uint8_t*)&msg,
46515 + sizeof(msg.msgId),
46516 + (uint8_t*)&reply,
46517 + &replyLength,
46518 + NULL,
46519 + NULL)) != E_OK)
46520 + RETURN_ERROR(MAJOR, err, NO_MSG);
46521 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
46522 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
46523 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
46524 + if (!p_FmPcd->enabled)
46525 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
46526 +
46527 + return E_OK;
46528 + }
46529 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
46530 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
46531 + ("running in guest-mode without IPC!"));
46532 +
46533 + if (p_FmPcd->p_FmPcdKg)
46534 + KgEnable(p_FmPcd);
46535 +
46536 + if (p_FmPcd->p_FmPcdPlcr)
46537 + PlcrEnable(p_FmPcd);
46538 +
46539 + if (p_FmPcd->p_FmPcdPrs)
46540 + PrsEnable(p_FmPcd);
46541 +
46542 + p_FmPcd->enabled = TRUE;
46543 +
46544 + return E_OK;
46545 +}
46546 +
46547 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
46548 +{
46549 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46550 + t_Error err = E_OK;
46551 +
46552 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
46553 +
46554 + if (!p_FmPcd->enabled)
46555 + return E_OK;
46556 +
46557 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
46558 + p_FmPcd->h_IpcSession)
46559 + {
46560 + t_FmPcdIpcMsg msg;
46561 + t_FmPcdIpcReply reply;
46562 + uint32_t replyLength;
46563 +
46564 + memset(&reply, 0, sizeof(reply));
46565 + memset(&msg, 0, sizeof(msg));
46566 + msg.msgId = FM_PCD_GUEST_DISABLE;
46567 + replyLength = sizeof(uint32_t);
46568 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
46569 + (uint8_t*)&msg,
46570 + sizeof(msg.msgId),
46571 + (uint8_t*)&reply,
46572 + &replyLength,
46573 + NULL,
46574 + NULL)) != E_OK)
46575 + RETURN_ERROR(MAJOR, err, NO_MSG);
46576 + if (replyLength != sizeof(uint32_t))
46577 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
46578 + if (reply.error == E_OK)
46579 + p_FmPcd->enabled = FALSE;
46580 +
46581 + return (t_Error)(reply.error);
46582 + }
46583 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
46584 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
46585 + ("running in guest-mode without IPC!"));
46586 +
46587 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
46588 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
46589 + ("Trying to disable a master partition PCD while"
46590 + "guest partitions are still enabled!"));
46591 +
46592 + if (p_FmPcd->p_FmPcdKg)
46593 + KgDisable(p_FmPcd);
46594 +
46595 + if (p_FmPcd->p_FmPcdPlcr)
46596 + PlcrDisable(p_FmPcd);
46597 +
46598 + if (p_FmPcd->p_FmPcdPrs)
46599 + PrsDisable(p_FmPcd);
46600 +
46601 + p_FmPcd->enabled = FALSE;
46602 +
46603 + return E_OK;
46604 +}
46605 +
46606 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
46607 +{
46608 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46609 + uint32_t intFlags, specialUnits = 0;
46610 + uint8_t bitId = 0;
46611 + uint8_t i, j, k;
46612 + uint8_t netEnvCurrId;
46613 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
46614 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
46615 + uint8_t hdrNum;
46616 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
46617 +
46618 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
46619 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
46620 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
46621 +
46622 + intFlags = FmPcdLock(p_FmPcd);
46623 +
46624 + /* find a new netEnv */
46625 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
46626 + if (!p_FmPcd->netEnvs[i].used)
46627 + break;
46628 +
46629 + if (i== FM_MAX_NUM_OF_PORTS)
46630 + {
46631 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
46632 + FmPcdUnlock(p_FmPcd, intFlags);
46633 + return NULL;
46634 + }
46635 +
46636 + p_FmPcd->netEnvs[i].used = TRUE;
46637 + FmPcdUnlock(p_FmPcd, intFlags);
46638 +
46639 + /* As anyone doesn't have handle of this netEnv yet, no need
46640 + to protect it with spinlocks */
46641 +
46642 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
46643 + if (!p_ModifiedNetEnvParams)
46644 + {
46645 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
46646 + return NULL;
46647 + }
46648 +
46649 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
46650 + p_NetEnvParams = p_ModifiedNetEnvParams;
46651 +
46652 + netEnvCurrId = (uint8_t)i;
46653 +
46654 + /* clear from previous use */
46655 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
46656 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
46657 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
46658 +
46659 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
46660 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
46661 +
46662 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
46663 +
46664 + /* check that header with opt is not interchanged with the same header */
46665 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
46666 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
46667 + {
46668 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
46669 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
46670 + {
46671 + /* if an option exists, check that other headers are not the same header
46672 + without option */
46673 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
46674 + {
46675 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
46676 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
46677 + {
46678 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
46679 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
46680 + {
46681 + REPORT_ERROR(MINOR, E_FULL,
46682 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
46683 + XX_Free(p_ModifiedNetEnvParams);
46684 + return NULL;
46685 + }
46686 + }
46687 + }
46688 + }
46689 + }
46690 +
46691 + /* Specific headers checking */
46692 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
46693 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
46694 + {
46695 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
46696 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
46697 + {
46698 + /* Some headers pairs may not be defined on different units as the parser
46699 + doesn't distinguish */
46700 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
46701 + /* check that header with opt is not interchanged with the same header */
46702 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
46703 + {
46704 + if (ipsecEspExists && (ipsecEspUnit != i))
46705 + {
46706 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
46707 + XX_Free(p_ModifiedNetEnvParams);
46708 + return NULL;
46709 + }
46710 + else
46711 + {
46712 + ipsecAhUnit = i;
46713 + ipsecAhExists = TRUE;
46714 + }
46715 + }
46716 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
46717 + {
46718 + if (ipsecAhExists && (ipsecAhUnit != i))
46719 + {
46720 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
46721 + XX_Free(p_ModifiedNetEnvParams);
46722 + return NULL;
46723 + }
46724 + else
46725 + {
46726 + ipsecEspUnit = i;
46727 + ipsecEspExists = TRUE;
46728 + }
46729 + }
46730 + /* ENCAP_ESP */
46731 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
46732 + {
46733 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
46734 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
46735 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
46736 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
46737 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
46738 + }
46739 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
46740 + /* UDP_LITE */
46741 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
46742 + {
46743 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
46744 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
46745 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
46746 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
46747 + }
46748 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
46749 +
46750 + /* IP FRAG */
46751 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
46752 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
46753 + {
46754 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
46755 + * IPv4 exists. If so we don't need to set an extra unit
46756 + * We consider as "having IPv4" any IPv4 without interchangable headers
46757 + * but including any options. */
46758 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
46759 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
46760 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
46761 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
46762 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
46763 +
46764 + /* check if IPv4 header exists by itself */
46765 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
46766 + {
46767 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
46768 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
46769 + }
46770 + }
46771 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
46772 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
46773 + {
46774 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
46775 + * IPv4 exists. If so we don't need to set an extra unit
46776 + * We consider as "having IPv6" any IPv6 without interchangable headers
46777 + * but including any options. */
46778 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
46779 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
46780 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
46781 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
46782 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
46783 +
46784 + /* check if IPv6 header exists by itself */
46785 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
46786 + {
46787 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
46788 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
46789 + }
46790 + }
46791 +#if (DPAA_VERSION >= 11)
46792 + /* CAPWAP FRAG */
46793 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
46794 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
46795 + {
46796 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
46797 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
46798 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
46799 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
46800 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
46801 + }
46802 +#endif /* (DPAA_VERSION >= 11) */
46803 + }
46804 + }
46805 +
46806 + /* if private header (shim), check that no other headers specified */
46807 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
46808 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
46809 + {
46810 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
46811 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
46812 + {
46813 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
46814 + XX_Free(p_ModifiedNetEnvParams);
46815 + return NULL;
46816 + }
46817 + }
46818 +
46819 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
46820 + {
46821 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
46822 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
46823 + {
46824 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
46825 + if (shim1Selected)
46826 + {
46827 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
46828 + XX_Free(p_ModifiedNetEnvParams);
46829 + return NULL;
46830 + }
46831 + shim1Selected = TRUE;
46832 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
46833 + break;
46834 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
46835 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
46836 + break;
46837 + default:
46838 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
46839 + }
46840 + else
46841 + {
46842 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
46843 +
46844 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
46845 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
46846 + }
46847 + }
46848 +
46849 + /* define a set of hardware parser LCV's according to the defined netenv */
46850 +
46851 + /* set an array of LCV's for each header in the netEnv */
46852 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
46853 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
46854 + {
46855 + /* private headers have no LCV in the hard parser */
46856 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
46857 + {
46858 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
46859 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
46860 + {
46861 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
46862 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
46863 + {
46864 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
46865 + XX_Free(p_ModifiedNetEnvParams);
46866 + return NULL;
46867 + }
46868 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
46869 + }
46870 + }
46871 + }
46872 + XX_Free(p_ModifiedNetEnvParams);
46873 +
46874 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
46875 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
46876 + {
46877 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
46878 + return NULL;
46879 + }
46880 + return &p_FmPcd->netEnvs[netEnvCurrId];
46881 +}
46882 +
46883 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
46884 +{
46885 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
46886 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
46887 + uint32_t intFlags;
46888 + uint8_t netEnvId = p_NetEnv->netEnvId;
46889 +
46890 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
46891 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
46892 +
46893 + /* check that no port is bound to this netEnv */
46894 + if (p_FmPcd->netEnvs[netEnvId].owners)
46895 + {
46896 + RETURN_ERROR(MINOR, E_INVALID_STATE,
46897 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
46898 + }
46899 +
46900 + intFlags = FmPcdLock(p_FmPcd);
46901 +
46902 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
46903 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
46904 +
46905 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
46906 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
46907 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
46908 +
46909 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
46910 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
46911 +
46912 + FmPcdUnlock(p_FmPcd, intFlags);
46913 + return E_OK;
46914 +}
46915 +
46916 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
46917 +{
46918 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46919 +
46920 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
46921 +
46922 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
46923 +}
46924 +
46925 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
46926 +{
46927 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46928 + t_FmCtrlCodeRevisionInfo revInfo;
46929 + t_Error err;
46930 +
46931 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46932 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
46933 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
46934 +
46935 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
46936 + {
46937 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
46938 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
46939 + }
46940 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
46941 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
46942 +
46943 + if (!p_FmPcd->h_Hc)
46944 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
46945 +
46946 + p_FmPcd->advancedOffloadSupport = TRUE;
46947 +
46948 + return E_OK;
46949 +}
46950 +
46951 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
46952 +{
46953 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46954 + uint32_t outCounter = 0;
46955 + t_Error err;
46956 +
46957 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
46958 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
46959 +
46960 + switch (counter)
46961 + {
46962 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
46963 + if (!p_FmPcd->p_FmPcdKg)
46964 + {
46965 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
46966 + return 0;
46967 + }
46968 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
46969 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
46970 + !p_FmPcd->h_IpcSession)
46971 + {
46972 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
46973 + ("running in guest-mode without neither IPC nor mapped register!"));
46974 + return 0;
46975 + }
46976 + break;
46977 +
46978 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
46979 + case (e_FM_PCD_PLCR_COUNTERS_RED):
46980 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
46981 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
46982 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
46983 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
46984 + if (!p_FmPcd->p_FmPcdPlcr)
46985 + {
46986 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
46987 + return 0;
46988 + }
46989 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
46990 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
46991 + !p_FmPcd->h_IpcSession)
46992 + {
46993 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
46994 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
46995 + return 0;
46996 + }
46997 +
46998 + /* check that counters are enabled */
46999 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
47000 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
47001 + {
47002 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
47003 + return 0;
47004 + }
47005 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
47006 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
47007 + break;
47008 +
47009 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47010 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47011 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47012 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47013 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47014 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47015 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47016 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47017 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47018 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47019 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47020 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47021 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47022 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47023 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47024 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47025 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47026 + if (!p_FmPcd->p_FmPcdPrs)
47027 + {
47028 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
47029 + return 0;
47030 + }
47031 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47032 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
47033 + !p_FmPcd->h_IpcSession)
47034 + {
47035 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
47036 + ("running in guest-mode without neither IPC nor mapped register!"));
47037 + return 0;
47038 + }
47039 + break;
47040 + default:
47041 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
47042 + return 0;
47043 + }
47044 +
47045 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47046 + p_FmPcd->h_IpcSession)
47047 + {
47048 + t_FmPcdIpcMsg msg;
47049 + t_FmPcdIpcReply reply;
47050 + uint32_t replyLength;
47051 +
47052 + memset(&msg, 0, sizeof(msg));
47053 + memset(&reply, 0, sizeof(reply));
47054 + msg.msgId = FM_PCD_GET_COUNTER;
47055 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
47056 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
47057 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47058 + (uint8_t*)&msg,
47059 + sizeof(msg.msgId) +sizeof(uint32_t),
47060 + (uint8_t*)&reply,
47061 + &replyLength,
47062 + NULL,
47063 + NULL)) != E_OK)
47064 + RETURN_ERROR(MAJOR, err, NO_MSG);
47065 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
47066 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
47067 +
47068 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
47069 + return outCounter;
47070 + }
47071 +
47072 + switch (counter)
47073 + {
47074 + /* Parser statistics */
47075 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47076 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
47077 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47078 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
47079 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47080 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
47081 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47082 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
47083 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47084 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
47085 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47086 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
47087 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47088 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
47089 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47090 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
47091 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47092 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
47093 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47094 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
47095 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47096 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
47097 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47098 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
47099 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47100 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
47101 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47102 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
47103 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47104 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
47105 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47106 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
47107 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47108 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
47109 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47110 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
47111 +
47112 + /* Policer statistics */
47113 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47114 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
47115 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47116 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
47117 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47118 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
47119 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47120 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
47121 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47122 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
47123 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47124 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
47125 + }
47126 + return 0;
47127 +}
47128 +
47129 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
47130 +{
47131 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47132 + uint32_t bitMask = 0, tmpReg;
47133 +
47134 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47135 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47136 +
47137 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47138 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
47139 +
47140 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
47141 +
47142 + if (bitMask)
47143 + {
47144 + if (enable)
47145 + p_FmPcd->exceptions |= bitMask;
47146 + else
47147 + p_FmPcd->exceptions &= ~bitMask;
47148 +
47149 + switch (exception)
47150 + {
47151 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
47152 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
47153 + if (!p_FmPcd->p_FmPcdKg)
47154 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
47155 + break;
47156 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
47157 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
47158 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
47159 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
47160 + if (!p_FmPcd->p_FmPcdPlcr)
47161 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
47162 + break;
47163 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
47164 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
47165 + if (!p_FmPcd->p_FmPcdPrs)
47166 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
47167 + break;
47168 + }
47169 +
47170 + switch (exception)
47171 + {
47172 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
47173 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
47174 + if (enable)
47175 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
47176 + else
47177 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
47178 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
47179 + break;
47180 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
47181 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
47182 + if (enable)
47183 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
47184 + else
47185 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
47186 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
47187 + break;
47188 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
47189 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
47190 + if (enable)
47191 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
47192 + else
47193 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
47194 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
47195 + break;
47196 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
47197 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
47198 + if (enable)
47199 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
47200 + else
47201 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
47202 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
47203 + break;
47204 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
47205 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47206 + if (enable)
47207 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
47208 + else
47209 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
47210 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
47211 + break;
47212 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
47213 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47214 + if (enable)
47215 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47216 + else
47217 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
47218 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
47219 + break;
47220 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
47221 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47222 + if (enable)
47223 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47224 + else
47225 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47226 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
47227 + break;
47228 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
47229 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47230 + if (enable)
47231 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47232 + else
47233 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47234 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
47235 + break;
47236 + }
47237 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
47238 + Driver may disable them automatically, depending on driver's status */
47239 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
47240 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
47241 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
47242 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
47243 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47244 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
47245 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
47246 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
47247 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
47248 + FmDisableRamsEcc(p_FmPcd->h_Fm);
47249 + }
47250 +
47251 + return E_OK;
47252 +}
47253 +
47254 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
47255 +{
47256 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47257 +
47258 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
47259 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47260 +
47261 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47262 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
47263 +
47264 + switch (exception)
47265 + {
47266 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
47267 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
47268 + if (!p_FmPcd->p_FmPcdKg)
47269 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
47270 + break;
47271 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
47272 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
47273 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
47274 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
47275 + if (!p_FmPcd->p_FmPcdPlcr)
47276 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
47277 + break;
47278 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
47279 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
47280 + if (!p_FmPcd->p_FmPcdPrs)
47281 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
47282 + break;
47283 + default:
47284 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
47285 + }
47286 + switch (exception)
47287 + {
47288 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
47289 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
47290 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47291 + break;
47292 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
47293 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
47294 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47295 + break;
47296 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
47297 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
47298 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47299 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
47300 + break;
47301 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
47302 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
47303 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47304 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
47305 + break;
47306 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
47307 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
47308 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47309 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
47310 + break;
47311 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
47312 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
47313 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47314 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
47315 + break;
47316 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
47317 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
47318 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47319 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
47320 + break;
47321 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
47322 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
47323 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47324 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
47325 + break;
47326 + }
47327 +
47328 + return E_OK;
47329 +}
47330 +
47331 +
47332 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
47333 +{
47334 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47335 +
47336 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
47337 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47338 +
47339 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47340 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
47341 +
47342 + switch (counter)
47343 + {
47344 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47345 + if (!p_FmPcd->p_FmPcdKg)
47346 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
47347 + break;
47348 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47349 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47350 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47351 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47352 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47353 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47354 + if (!p_FmPcd->p_FmPcdPlcr)
47355 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
47356 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
47357 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
47358 + break;
47359 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47360 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47361 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47362 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47363 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47364 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47365 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47366 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47367 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47368 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47369 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47370 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47371 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47372 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47373 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47374 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47375 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47376 + if (!p_FmPcd->p_FmPcdPrs)
47377 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
47378 + break;
47379 + default:
47380 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
47381 + }
47382 + switch (counter)
47383 + {
47384 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47385 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
47386 + break;
47387 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47388 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
47389 + break;
47390 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47391 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
47392 + break;
47393 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47394 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
47395 + break;
47396 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47397 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
47398 + break;
47399 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47400 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
47401 + break;
47402 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47403 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
47404 + break;
47405 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47406 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
47407 + break;
47408 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47409 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
47410 + break;
47411 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47412 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
47413 + break;
47414 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47415 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
47416 + break;
47417 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47418 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
47419 + break;
47420 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47421 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
47422 + break;
47423 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47424 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
47425 + break;
47426 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47427 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
47428 + break;
47429 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47430 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
47431 + break;
47432 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47433 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
47434 + break;
47435 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47436 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
47437 + break;
47438 +
47439 + /*Policer counters*/
47440 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47441 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
47442 + break;
47443 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47444 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
47445 + break;
47446 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47447 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
47448 + break;
47449 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47450 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
47451 + break;
47452 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47453 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
47454 + break;
47455 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47456 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
47457 + break;
47458 + }
47459 +
47460 + return E_OK;
47461 +}
47462 +
47463 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
47464 +{
47465 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47466 + return FmHcGetPort(p_FmPcd->h_Hc);
47467 +}
47468 +
47469 --- /dev/null
47470 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
47471 @@ -0,0 +1,543 @@
47472 +/*
47473 + * Copyright 2008-2012 Freescale Semiconductor Inc.
47474 + *
47475 + * Redistribution and use in source and binary forms, with or without
47476 + * modification, are permitted provided that the following conditions are met:
47477 + * * Redistributions of source code must retain the above copyright
47478 + * notice, this list of conditions and the following disclaimer.
47479 + * * Redistributions in binary form must reproduce the above copyright
47480 + * notice, this list of conditions and the following disclaimer in the
47481 + * documentation and/or other materials provided with the distribution.
47482 + * * Neither the name of Freescale Semiconductor nor the
47483 + * names of its contributors may be used to endorse or promote products
47484 + * derived from this software without specific prior written permission.
47485 + *
47486 + *
47487 + * ALTERNATIVELY, this software may be distributed under the terms of the
47488 + * GNU General Public License ("GPL") as published by the Free Software
47489 + * Foundation, either version 2 of that License or (at your option) any
47490 + * later version.
47491 + *
47492 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
47493 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47494 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47495 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
47496 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47497 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47498 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47499 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47500 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47501 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47502 + */
47503 +
47504 +
47505 +/******************************************************************************
47506 + @File fm_pcd.h
47507 +
47508 + @Description FM PCD ...
47509 +*//***************************************************************************/
47510 +#ifndef __FM_PCD_H
47511 +#define __FM_PCD_H
47512 +
47513 +#include "std_ext.h"
47514 +#include "error_ext.h"
47515 +#include "list_ext.h"
47516 +#include "fm_pcd_ext.h"
47517 +#include "fm_common.h"
47518 +#include "fsl_fman_prs.h"
47519 +#include "fsl_fman_kg.h"
47520 +
47521 +#define __ERR_MODULE__ MODULE_FM_PCD
47522 +
47523 +
47524 +/****************************/
47525 +/* Defaults */
47526 +/****************************/
47527 +#define DEFAULT_plcrAutoRefresh FALSE
47528 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
47529 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47530 +#define DEFAULT_fmPcdPlcrExceptions 0
47531 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
47532 +
47533 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
47534 +#define DEFAULT_numOfUsedProfilesPerWindow 16
47535 +#define DEFAULT_numOfSharedPlcrProfiles 4
47536 +
47537 +/****************************/
47538 +/* Network defines */
47539 +/****************************/
47540 +#define UDP_HEADER_SIZE 8
47541 +
47542 +#define ESP_SPI_OFFSET 0
47543 +#define ESP_SPI_SIZE 4
47544 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
47545 +#define ESP_SEQ_NUM_SIZE 4
47546 +
47547 +/****************************/
47548 +/* General defines */
47549 +/****************************/
47550 +#define ILLEGAL_CLS_PLAN 0xff
47551 +#define ILLEGAL_NETENV 0xff
47552 +
47553 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
47554 +
47555 +/****************************/
47556 +/* Error defines */
47557 +/****************************/
47558 +
47559 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
47560 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
47561 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
47562 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
47563 +
47564 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
47565 +switch (exception){ \
47566 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
47567 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
47568 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
47569 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
47570 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
47571 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
47572 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
47573 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
47574 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
47575 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
47576 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
47577 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
47578 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
47579 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
47580 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
47581 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
47582 + default: bitMask = 0;break;}
47583 +
47584 +/***********************************************************************/
47585 +/* Policer defines */
47586 +/***********************************************************************/
47587 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
47588 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
47589 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
47590 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
47591 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
47592 +
47593 +/***********************************************************************/
47594 +/* Memory map */
47595 +/***********************************************************************/
47596 +#if defined(__MWERKS__) && !defined(__GNUC__)
47597 +#pragma pack(push,1)
47598 +#endif /* defined(__MWERKS__) && ... */
47599 +
47600 +
47601 +typedef struct {
47602 +/* General Configuration and Status Registers */
47603 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
47604 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
47605 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
47606 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
47607 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
47608 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
47609 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
47610 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
47611 +/* Global Statistic Counters */
47612 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
47613 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
47614 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
47615 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
47616 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
47617 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
47618 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
47619 +/* Profile RAM Access Registers */
47620 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
47621 + t_FmPcdPlcrProfileRegs profileRegs;
47622 +/* Error Capture Registers */
47623 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
47624 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
47625 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
47626 +/* Debug Registers */
47627 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
47628 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
47629 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
47630 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
47631 + (for port-ID 1-11, only for supported Port-ID registers) */
47632 +} t_FmPcdPlcrRegs;
47633 +
47634 +#if defined(__MWERKS__) && !defined(__GNUC__)
47635 +#pragma pack(pop)
47636 +#endif /* defined(__MWERKS__) && ... */
47637 +
47638 +
47639 +/***********************************************************************/
47640 +/* Driver's internal structures */
47641 +/***********************************************************************/
47642 +
47643 +typedef struct {
47644 + bool known;
47645 + uint8_t id;
47646 +} t_FmPcdKgSchemesExtractsEntry;
47647 +
47648 +typedef struct {
47649 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
47650 +} t_FmPcdKgSchemesExtracts;
47651 +
47652 +typedef struct {
47653 + t_Handle h_Manip;
47654 + bool keepRes;
47655 + e_FmPcdEngine nextEngine;
47656 + uint8_t parseCode;
47657 +} t_FmPcdInfoForManip;
47658 +
47659 +/**************************************************************************//**
47660 + @Description A structure of parameters to communicate
47661 + between the port and PCD regarding the KG scheme.
47662 +*//***************************************************************************/
47663 +typedef struct {
47664 + uint8_t netEnvId; /* in */
47665 + uint8_t numOfDistinctionUnits; /* in */
47666 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
47667 + uint32_t vector; /* out */
47668 +} t_NetEnvParams;
47669 +
47670 +typedef struct {
47671 + bool allocated;
47672 + uint8_t ownerId; /* guestId for KG in multi-partition only.
47673 + portId for PLCR in any environment */
47674 +} t_FmPcdAllocMng;
47675 +
47676 +typedef struct {
47677 + volatile bool lock;
47678 + bool used;
47679 + uint8_t owners;
47680 + uint8_t netEnvId;
47681 + uint8_t guestId;
47682 + uint8_t baseEntry;
47683 + uint16_t sizeOfGrp;
47684 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
47685 +} t_FmPcdKgClsPlanGrp;
47686 +
47687 +typedef struct {
47688 + t_Handle h_FmPcd;
47689 + uint8_t schemeId;
47690 + t_FmPcdLock *p_Lock;
47691 + bool valid;
47692 + uint8_t netEnvId;
47693 + uint8_t owners;
47694 + uint32_t matchVector;
47695 + uint32_t ccUnits;
47696 + bool nextRelativePlcrProfile;
47697 + uint16_t relativeProfileId;
47698 + uint16_t numOfProfiles;
47699 + t_FmPcdKgKeyOrder orderedArray;
47700 + e_FmPcdEngine nextEngine;
47701 + e_FmPcdDoneAction doneAction;
47702 + bool requiredActionFlag;
47703 + uint32_t requiredAction;
47704 + bool extractedOrs;
47705 + uint8_t bitOffsetInPlcrProfile;
47706 + bool directPlcr;
47707 +#if (DPAA_VERSION >= 11)
47708 + bool vspe;
47709 +#endif
47710 +} t_FmPcdKgScheme;
47711 +
47712 +typedef union {
47713 + struct fman_kg_scheme_regs schemeRegs;
47714 + struct fman_kg_pe_regs portRegs;
47715 + struct fman_kg_cp_regs clsPlanRegs;
47716 +} u_FmPcdKgIndirectAccessRegs;
47717 +
47718 +typedef struct {
47719 + struct fman_kg_regs *p_FmPcdKgRegs;
47720 + uint32_t schemeExceptionsBitMask;
47721 + uint8_t numOfSchemes;
47722 + t_Handle h_HwSpinlock;
47723 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
47724 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
47725 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
47726 + uint8_t emptyClsPlanGrpId;
47727 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
47728 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
47729 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
47730 +} t_FmPcdKg;
47731 +
47732 +typedef struct {
47733 + uint16_t profilesBase;
47734 + uint16_t numOfProfiles;
47735 + t_Handle h_FmPort;
47736 +} t_FmPcdPlcrMapParam;
47737 +
47738 +typedef struct {
47739 + uint16_t absoluteProfileId;
47740 + t_Handle h_FmPcd;
47741 + bool valid;
47742 + t_FmPcdLock *p_Lock;
47743 + t_FmPcdAllocMng profilesMng;
47744 + bool requiredActionFlag;
47745 + uint32_t requiredAction;
47746 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
47747 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
47748 +
47749 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
47750 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
47751 +
47752 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
47753 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
47754 +} t_FmPcdPlcrProfile;
47755 +
47756 +typedef struct {
47757 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
47758 + uint16_t partPlcrProfilesBase;
47759 + uint16_t partNumOfPlcrProfiles;
47760 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
47761 + uint16_t numOfSharedProfiles;
47762 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
47763 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
47764 + t_Handle h_HwSpinlock;
47765 + t_Handle h_SwSpinlock;
47766 +} t_FmPcdPlcr;
47767 +
47768 +typedef struct {
47769 + uint32_t *p_SwPrsCode;
47770 + uint32_t *p_CurrSwPrs;
47771 + uint8_t currLabel;
47772 + struct fman_prs_regs *p_FmPcdPrsRegs;
47773 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
47774 + uint32_t fmPcdPrsPortIdStatistics;
47775 +} t_FmPcdPrs;
47776 +
47777 +typedef struct {
47778 + struct {
47779 + e_NetHeaderType hdr;
47780 + protocolOpt_t opt; /* only one option !! */
47781 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
47782 +} t_FmPcdIntDistinctionUnit;
47783 +
47784 +typedef struct {
47785 + e_NetHeaderType hdr;
47786 + protocolOpt_t opt; /* only one option !! */
47787 + e_NetHeaderType aliasHdr;
47788 +} t_FmPcdNetEnvAliases;
47789 +
47790 +typedef struct {
47791 + uint8_t netEnvId;
47792 + t_Handle h_FmPcd;
47793 + t_Handle h_Spinlock;
47794 + bool used;
47795 + uint8_t owners;
47796 + uint8_t clsPlanGrpId;
47797 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
47798 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
47799 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
47800 + uint32_t macsecVector;
47801 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
47802 +} t_FmPcdNetEnv;
47803 +
47804 +typedef struct {
47805 + struct fman_prs_cfg dfltCfg;
47806 + bool plcrAutoRefresh;
47807 + uint16_t prsMaxParseCycleLimit;
47808 +} t_FmPcdDriverParam;
47809 +
47810 +typedef struct {
47811 + t_Handle h_Fm;
47812 + t_Handle h_FmMuram;
47813 + t_FmRevisionInfo fmRevInfo;
47814 +
47815 + uint64_t physicalMuramBase;
47816 +
47817 + t_Handle h_Spinlock;
47818 + t_List freeLocksLst;
47819 + t_List acquiredLocksLst;
47820 +
47821 + t_Handle h_IpcSession; /* relevant for guest only */
47822 + bool enabled;
47823 + uint8_t guestId; /**< Guest Partition Id */
47824 + uint8_t numOfEnabledGuestPartitionsPcds;
47825 + char fmPcdModuleName[MODULE_NAME_SIZE];
47826 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
47827 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
47828 + t_FmPcdKg *p_FmPcdKg;
47829 + t_FmPcdPlcr *p_FmPcdPlcr;
47830 + t_FmPcdPrs *p_FmPcdPrs;
47831 +
47832 + void *p_CcShadow; /**< CC MURAM shadow */
47833 + uint32_t ccShadowSize;
47834 + uint32_t ccShadowAlign;
47835 + volatile bool shadowLock;
47836 + t_Handle h_ShadowSpinlock;
47837 +
47838 + t_Handle h_Hc;
47839 +
47840 + uint32_t exceptions;
47841 + t_FmPcdExceptionCallback *f_Exception;
47842 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
47843 + t_Handle h_App;
47844 + uintptr_t ipv6FrameIdAddr;
47845 + uintptr_t capwapFrameIdAddr;
47846 + bool advancedOffloadSupport;
47847 +
47848 + t_FmPcdDriverParam *p_FmPcdDriverParam;
47849 +} t_FmPcd;
47850 +
47851 +#if (DPAA_VERSION >= 11)
47852 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
47853 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
47854 +#define FRM_REPLIC_UPDATE_INFO 0x02
47855 +#endif /* (DPAA_VERSION >= 11) */
47856 +/***********************************************************************/
47857 +/* PCD internal routines */
47858 +/***********************************************************************/
47859 +
47860 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
47861 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
47862 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
47863 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
47864 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
47865 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
47866 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
47867 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
47868 +
47869 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
47870 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
47871 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
47872 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
47873 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
47874 +
47875 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
47876 +t_Error KgInit(t_FmPcd *p_FmPcd);
47877 +t_Error KgFree(t_FmPcd *p_FmPcd);
47878 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
47879 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
47880 +void KgEnable(t_FmPcd *p_FmPcd);
47881 +void KgDisable(t_FmPcd *p_FmPcd);
47882 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
47883 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
47884 +
47885 +/* only for MULTI partittion */
47886 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
47887 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
47888 +/* only for SINGLE partittion */
47889 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
47890 +
47891 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
47892 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
47893 +
47894 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
47895 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
47896 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
47897 +void PlcrEnable(t_FmPcd *p_FmPcd);
47898 +void PlcrDisable(t_FmPcd *p_FmPcd);
47899 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
47900 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
47901 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47902 + uint8_t hardwarePortId,
47903 + uint16_t numOfProfiles,
47904 + uint16_t base);
47905 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
47906 +
47907 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
47908 +t_Error PrsInit(t_FmPcd *p_FmPcd);
47909 +void PrsEnable(t_FmPcd *p_FmPcd);
47910 +void PrsDisable(t_FmPcd *p_FmPcd);
47911 +void PrsFree(t_FmPcd *p_FmPcd );
47912 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
47913 +
47914 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
47915 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
47916 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
47917 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
47918 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
47919 +
47920 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
47921 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
47922 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
47923 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
47924 + t_Handle p_Ad,
47925 + t_Handle *p_AdNewPtr);
47926 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
47927 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
47928 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
47929 +#ifdef FM_CAPWAP_SUPPORT
47930 +t_Handle FmPcdManipApplSpecificBuild(void);
47931 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
47932 +#endif /* FM_CAPWAP_SUPPORT */
47933 +#if (DPAA_VERSION >= 11)
47934 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
47935 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
47936 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
47937 +
47938 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
47939 + t_Handle h_ReplicGroup,
47940 + t_List *p_AdTables,
47941 + uint32_t *p_NumOfAdTables);
47942 +#endif /* (DPAA_VERSION >= 11) */
47943 +
47944 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
47945 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
47946 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
47947 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
47948 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
47949 +
47950 +typedef struct
47951 +{
47952 + t_Handle h_StatsAd;
47953 + t_Handle h_StatsCounters;
47954 +#if (DPAA_VERSION >= 11)
47955 + t_Handle h_StatsFLRs;
47956 +#endif /* (DPAA_VERSION >= 11) */
47957 +} t_FmPcdCcStatsParams;
47958 +
47959 +void NextStepAd(t_Handle h_Ad,
47960 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
47961 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
47962 + t_FmPcd *p_FmPcd);
47963 +void ReleaseLst(t_List *p_List);
47964 +
47965 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
47966 +{
47967 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47968 + ASSERT_COND(p_FmPcd);
47969 + return p_FmPcd->h_FmMuram;
47970 +}
47971 +
47972 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
47973 +{
47974 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47975 + ASSERT_COND(p_FmPcd);
47976 + return p_FmPcd->physicalMuramBase;
47977 +}
47978 +
47979 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
47980 +{
47981 + ASSERT_COND(p_Lock);
47982 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
47983 +}
47984 +
47985 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
47986 +{
47987 + ASSERT_COND(p_Lock);
47988 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
47989 +}
47990 +
47991 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
47992 +{
47993 + uint32_t intFlags;
47994 +
47995 + ASSERT_COND(p_Lock);
47996 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
47997 + if (p_Lock->flag)
47998 + {
47999 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
48000 + return FALSE;
48001 + }
48002 + p_Lock->flag = TRUE;
48003 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
48004 + return TRUE;
48005 +}
48006 +
48007 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
48008 +{
48009 + ASSERT_COND(p_Lock);
48010 + p_Lock->flag = FALSE;
48011 +}
48012 +
48013 +
48014 +#endif /* __FM_PCD_H */
48015 --- /dev/null
48016 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
48017 @@ -0,0 +1,280 @@
48018 +/*
48019 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48020 + *
48021 + * Redistribution and use in source and binary forms, with or without
48022 + * modification, are permitted provided that the following conditions are met:
48023 + * * Redistributions of source code must retain the above copyright
48024 + * notice, this list of conditions and the following disclaimer.
48025 + * * Redistributions in binary form must reproduce the above copyright
48026 + * notice, this list of conditions and the following disclaimer in the
48027 + * documentation and/or other materials provided with the distribution.
48028 + * * Neither the name of Freescale Semiconductor nor the
48029 + * names of its contributors may be used to endorse or promote products
48030 + * derived from this software without specific prior written permission.
48031 + *
48032 + *
48033 + * ALTERNATIVELY, this software may be distributed under the terms of the
48034 + * GNU General Public License ("GPL") as published by the Free Software
48035 + * Foundation, either version 2 of that License or (at your option) any
48036 + * later version.
48037 + *
48038 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48039 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48040 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48041 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48042 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48043 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48044 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48045 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48046 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48047 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48048 + */
48049 +
48050 +
48051 +/**************************************************************************//**
48052 + @File fm_pcd_ipc.h
48053 +
48054 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
48055 +*//***************************************************************************/
48056 +#ifndef __FM_PCD_IPC_H
48057 +#define __FM_PCD_IPC_H
48058 +
48059 +#include "std_ext.h"
48060 +
48061 +
48062 +/**************************************************************************//**
48063 + @Group FM_grp Frame Manager API
48064 +
48065 + @Description FM API functions, definitions and enums
48066 +
48067 + @{
48068 +*//***************************************************************************/
48069 +
48070 +
48071 +#if defined(__MWERKS__) && !defined(__GNUC__)
48072 +#pragma pack(push,1)
48073 +#endif /* defined(__MWERKS__) && ... */
48074 +
48075 +/**************************************************************************//**
48076 + @Description Structure for getting a sw parser address according to a label
48077 + Fields commented 'IN' are passed by the port module to be used
48078 + by the FM module.
48079 + Fields commented 'OUT' will be filled by FM before returning to port.
48080 +*//***************************************************************************/
48081 +typedef _Packed struct t_FmPcdIpcSwPrsLable
48082 +{
48083 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
48084 + the sw parser code. */
48085 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
48086 + attachments for the same header, use this
48087 +
48088 + index to distinguish between them. */
48089 +} _PackedType t_FmPcdIpcSwPrsLable;
48090 +
48091 +/**************************************************************************//**
48092 + @Description Structure for port-PCD communication.
48093 + Fields commented 'IN' are passed by the port module to be used
48094 + by the FM module.
48095 + Fields commented 'OUT' will be filled by FM before returning to port.
48096 + Some fields are optional (depending on configuration) and
48097 + will be analized by the port and FM modules accordingly.
48098 +*//***************************************************************************/
48099 +
48100 +typedef struct t_FmPcdIpcKgSchemesParams
48101 +{
48102 + uint8_t guestId;
48103 + uint8_t numOfSchemes;
48104 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
48105 +} _PackedType t_FmPcdIpcKgSchemesParams;
48106 +
48107 +typedef struct t_FmPcdIpcKgClsPlanParams
48108 +{
48109 + uint8_t guestId;
48110 + uint16_t numOfClsPlanEntries;
48111 + uint8_t clsPlanBase;
48112 +} _PackedType t_FmPcdIpcKgClsPlanParams;
48113 +
48114 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
48115 +{
48116 + uint8_t hardwarePortId;
48117 + bool include;
48118 +} _PackedType t_FmPcdIpcPrsIncludePort;
48119 +
48120 +
48121 +#define FM_PCD_MAX_REPLY_SIZE 16
48122 +#define FM_PCD_MAX_MSG_SIZE 36
48123 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
48124 +
48125 +typedef _Packed struct {
48126 + uint32_t msgId;
48127 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
48128 +} _PackedType t_FmPcdIpcMsg;
48129 +
48130 +typedef _Packed struct t_FmPcdIpcReply {
48131 + uint32_t error;
48132 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
48133 +} _PackedType t_FmPcdIpcReply;
48134 +
48135 +typedef _Packed struct t_FmIpcResourceAllocParams {
48136 + uint8_t guestId;
48137 + uint16_t base;
48138 + uint16_t num;
48139 +}_PackedType t_FmIpcResourceAllocParams;
48140 +
48141 +#if defined(__MWERKS__) && !defined(__GNUC__)
48142 +#pragma pack(pop)
48143 +#endif /* defined(__MWERKS__) && ... */
48144 +
48145 +
48146 +
48147 +/**************************************************************************//**
48148 + @Function FM_PCD_ALLOC_KG_SCHEMES
48149 +
48150 + @Description Used by FM PCD front-end in order to allocate KG resources
48151 +
48152 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
48153 +*//***************************************************************************/
48154 +#define FM_PCD_ALLOC_KG_SCHEMES 3
48155 +
48156 +/**************************************************************************//**
48157 + @Function FM_PCD_FREE_KG_SCHEMES
48158 +
48159 + @Description Used by FM PCD front-end in order to Free KG resources
48160 +
48161 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
48162 +*//***************************************************************************/
48163 +#define FM_PCD_FREE_KG_SCHEMES 4
48164 +
48165 +/**************************************************************************//**
48166 + @Function FM_PCD_ALLOC_PROFILES
48167 +
48168 + @Description Used by FM PCD front-end in order to allocate Policer profiles
48169 +
48170 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48171 +*//***************************************************************************/
48172 +#define FM_PCD_ALLOC_PROFILES 5
48173 +
48174 +/**************************************************************************//**
48175 + @Function FM_PCD_FREE_PROFILES
48176 +
48177 + @Description Used by FM PCD front-end in order to Free Policer profiles
48178 +
48179 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48180 +*//***************************************************************************/
48181 +#define FM_PCD_FREE_PROFILES 6
48182 +
48183 +/**************************************************************************//**
48184 + @Function FM_PCD_SET_PORT_PROFILES
48185 +
48186 + @Description Used by FM PCD front-end in order to allocate Policer profiles
48187 + for specific port
48188 +
48189 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48190 +*//***************************************************************************/
48191 +#define FM_PCD_SET_PORT_PROFILES 7
48192 +
48193 +/**************************************************************************//**
48194 + @Function FM_PCD_CLEAR_PORT_PROFILES
48195 +
48196 + @Description Used by FM PCD front-end in order to allocate Policer profiles
48197 + for specific port
48198 +
48199 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48200 +*//***************************************************************************/
48201 +#define FM_PCD_CLEAR_PORT_PROFILES 8
48202 +
48203 +/**************************************************************************//**
48204 + @Function FM_PCD_GET_PHYS_MURAM_BASE
48205 +
48206 + @Description Used by FM PCD front-end in order to get MURAM base address
48207 +
48208 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
48209 +*//***************************************************************************/
48210 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
48211 +
48212 +/**************************************************************************//**
48213 + @Function FM_PCD_GET_SW_PRS_OFFSET
48214 +
48215 + @Description Used by FM front-end to get the SW parser offset of the start of
48216 + code relevant to a given label.
48217 +
48218 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
48219 +*//***************************************************************************/
48220 +#define FM_PCD_GET_SW_PRS_OFFSET 10
48221 +
48222 +/**************************************************************************//**
48223 + @Function FM_PCD_MASTER_IS_ENABLED
48224 +
48225 + @Description Used by FM front-end in order to verify
48226 + PCD enablement.
48227 +
48228 + @Param[in] bool Pointer
48229 +*//***************************************************************************/
48230 +#define FM_PCD_MASTER_IS_ENABLED 15
48231 +
48232 +/**************************************************************************//**
48233 + @Function FM_PCD_GUEST_DISABLE
48234 +
48235 + @Description Used by FM front-end to inform back-end when
48236 + front-end PCD is disabled
48237 +
48238 + @Param[in] None
48239 +*//***************************************************************************/
48240 +#define FM_PCD_GUEST_DISABLE 16
48241 +
48242 +/**************************************************************************//**
48243 + @Function FM_PCD_FREE_KG_CLSPLAN
48244 +
48245 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
48246 +
48247 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
48248 +*//***************************************************************************/
48249 +#define FM_PCD_FREE_KG_CLSPLAN 22
48250 +
48251 +/**************************************************************************//**
48252 + @Function FM_PCD_ALLOC_KG_CLSPLAN
48253 +
48254 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
48255 +
48256 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
48257 +*//***************************************************************************/
48258 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
48259 +
48260 +/**************************************************************************//**
48261 + @Function FM_PCD_MASTER_IS_ALIVE
48262 +
48263 + @Description Used by FM front-end to check that back-end exists
48264 +
48265 + @Param[in] None
48266 +*//***************************************************************************/
48267 +#define FM_PCD_MASTER_IS_ALIVE 24
48268 +
48269 +/**************************************************************************//**
48270 + @Function FM_PCD_GET_COUNTER
48271 +
48272 + @Description Used by FM front-end to read PCD counters
48273 +
48274 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
48275 +*//***************************************************************************/
48276 +#define FM_PCD_GET_COUNTER 25
48277 +
48278 +/**************************************************************************//**
48279 + @Function FM_PCD_PRS_INC_PORT_STATS
48280 +
48281 + @Description Used by FM front-end to set/clear statistics for port
48282 +
48283 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
48284 +*//***************************************************************************/
48285 +#define FM_PCD_PRS_INC_PORT_STATS 26
48286 +
48287 +#if (DPAA_VERSION >= 11)
48288 +/* TODO - doc */
48289 +#define FM_PCD_ALLOC_SP 27
48290 +#endif /* (DPAA_VERSION >= 11) */
48291 +
48292 +
48293 +/** @} */ /* end of FM_PCD_IPC_grp group */
48294 +/** @} */ /* end of FM_grp group */
48295 +
48296 +
48297 +#endif /* __FM_PCD_IPC_H */
48298 --- /dev/null
48299 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
48300 @@ -0,0 +1,1847 @@
48301 +/*
48302 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48303 + *
48304 + * Redistribution and use in source and binary forms, with or without
48305 + * modification, are permitted provided that the following conditions are met:
48306 + * * Redistributions of source code must retain the above copyright
48307 + * notice, this list of conditions and the following disclaimer.
48308 + * * Redistributions in binary form must reproduce the above copyright
48309 + * notice, this list of conditions and the following disclaimer in the
48310 + * documentation and/or other materials provided with the distribution.
48311 + * * Neither the name of Freescale Semiconductor nor the
48312 + * names of its contributors may be used to endorse or promote products
48313 + * derived from this software without specific prior written permission.
48314 + *
48315 + *
48316 + * ALTERNATIVELY, this software may be distributed under the terms of the
48317 + * GNU General Public License ("GPL") as published by the Free Software
48318 + * Foundation, either version 2 of that License or (at your option) any
48319 + * later version.
48320 + *
48321 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48322 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48323 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48324 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48325 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48326 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48327 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48328 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48329 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48330 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48331 + */
48332 +
48333 +
48334 +/******************************************************************************
48335 + @File fm_plcr.c
48336 +
48337 + @Description FM PCD POLICER...
48338 +*//***************************************************************************/
48339 +#include <linux/math64.h>
48340 +#include "std_ext.h"
48341 +#include "error_ext.h"
48342 +#include "string_ext.h"
48343 +#include "debug_ext.h"
48344 +#include "net_ext.h"
48345 +#include "fm_ext.h"
48346 +
48347 +#include "fm_common.h"
48348 +#include "fm_pcd.h"
48349 +#include "fm_hc.h"
48350 +#include "fm_pcd_ipc.h"
48351 +#include "fm_plcr.h"
48352 +
48353 +
48354 +/****************************************/
48355 +/* static functions */
48356 +/****************************************/
48357 +
48358 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
48359 +{
48360 + ASSERT_COND(h_Profile);
48361 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
48362 +}
48363 +
48364 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
48365 +{
48366 + ASSERT_COND(h_Profile);
48367 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
48368 +}
48369 +
48370 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
48371 +{
48372 + ASSERT_COND(h_Profile);
48373 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
48374 +}
48375 +
48376 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
48377 +{
48378 + ASSERT_COND(h_Profile);
48379 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
48380 +}
48381 +
48382 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
48383 +{
48384 + ASSERT_COND(h_FmPcdPlcr);
48385 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
48386 +}
48387 +
48388 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
48389 +{
48390 + ASSERT_COND(h_FmPcdPlcr);
48391 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
48392 +}
48393 +
48394 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
48395 +{
48396 + ASSERT_COND(h_FmPcdPlcr);
48397 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
48398 +}
48399 +
48400 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
48401 +{
48402 + ASSERT_COND(h_FmPcdPlcr);
48403 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
48404 +}
48405 +
48406 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48407 +{
48408 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48409 + uint16_t i;
48410 +
48411 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
48412 +
48413 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
48414 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
48415 + return TRUE;
48416 + return FALSE;
48417 +}
48418 +
48419 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
48420 +{
48421 + uint32_t nia;
48422 + uint16_t absoluteProfileId;
48423 + uint8_t relativeSchemeId, physicalSchemeId;
48424 +
48425 + nia = FM_PCD_PLCR_NIA_VALID;
48426 +
48427 + switch (nextEngine)
48428 + {
48429 + case e_FM_PCD_DONE :
48430 + switch (p_NextEngineParams->action)
48431 + {
48432 + case e_FM_PCD_DROP_FRAME :
48433 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
48434 + break;
48435 + case e_FM_PCD_ENQ_FRAME:
48436 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
48437 + break;
48438 + default:
48439 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48440 + }
48441 + break;
48442 + case e_FM_PCD_KG:
48443 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
48444 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
48445 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
48446 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
48447 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
48448 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
48449 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
48450 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
48451 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
48452 + break;
48453 + case e_FM_PCD_PLCR:
48454 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
48455 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
48456 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
48457 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48458 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
48459 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
48460 + break;
48461 + default:
48462 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48463 + }
48464 +
48465 + *nextAction = nia;
48466 +
48467 + return E_OK;
48468 +}
48469 +
48470 +static uint32_t CalcFPP(uint32_t fpp)
48471 +{
48472 + if (fpp > 15)
48473 + return 15 - (0x1f - fpp);
48474 + else
48475 + return 16 + fpp;
48476 +}
48477 +
48478 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
48479 + uint32_t rate,
48480 + uint64_t tsuInTenthNano,
48481 + uint32_t fppShift,
48482 + uint64_t *p_Integer,
48483 + uint64_t *p_Fraction)
48484 +{
48485 + uint64_t tmp, div;
48486 +
48487 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
48488 + {
48489 + /* now we calculate the initial integer for the bigger rate */
48490 + /* from Kbps to Bytes/TSU */
48491 + tmp = (uint64_t)rate;
48492 + tmp *= 1000; /* kb --> b */
48493 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
48494 +
48495 + div = 1000000000; /* nano */
48496 + div *= 10; /* 10 nano */
48497 + div *= 8; /* bit to byte */
48498 + }
48499 + else
48500 + {
48501 + /* now we calculate the initial integer for the bigger rate */
48502 + /* from Kbps to Bytes/TSU */
48503 + tmp = (uint64_t)rate;
48504 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
48505 +
48506 + div = 1000000000; /* nano */
48507 + div *= 10; /* 10 nano */
48508 + }
48509 + *p_Integer = div64_u64(tmp<<fppShift, div);
48510 +
48511 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
48512 + * For precision, we will multiply by 2^16. we do not divid back, since we write
48513 + * this value as fraction - see spec.
48514 + */
48515 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
48516 +}
48517 +
48518 +/* .......... */
48519 +
48520 +static void CalcRates(uint32_t bitFor1Micro,
48521 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
48522 + uint32_t *cir,
48523 + uint32_t *cbs,
48524 + uint32_t *pir_eir,
48525 + uint32_t *pbs_ebs,
48526 + uint32_t *fpp)
48527 +{
48528 + uint64_t integer, fraction;
48529 + uint32_t temp, tsuInTenthNanos;
48530 + uint8_t fppShift=0;
48531 +
48532 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
48533 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
48534 +
48535 + /* we choose the faster rate to calibrate fpp */
48536 + /* The meaning of this step:
48537 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
48538 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
48539 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
48540 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
48541 + * high rate, as many bits as possible for fraction at low rate.
48542 + */
48543 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
48544 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
48545 + else
48546 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
48547 +
48548 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
48549 + * the LSB bits are for the fraction */
48550 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
48551 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
48552 + * take max FP = 31.
48553 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
48554 + * limited by the 10G physical port.
48555 + */
48556 + if (temp != 0)
48557 + {
48558 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
48559 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
48560 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
48561 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
48562 + * to use these bits for the fraction. in this way we will have for fraction - the number
48563 + * of "0" bits and the rest - for integer.
48564 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
48565 + * one bit to the left - preserving the relationship and achieving more bits
48566 + * for integer in the TS.
48567 + */
48568 +
48569 + /* count zeroes left of the higher used bit (in order to shift the value such that
48570 + * unused bits may be used for fraction).
48571 + */
48572 + while ((temp & 0x80000000) == 0)
48573 + {
48574 + temp = temp << 1;
48575 + fppShift++;
48576 + }
48577 + if (fppShift > 15)
48578 + {
48579 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
48580 + return;
48581 + }
48582 + }
48583 + else
48584 + {
48585 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
48586 + if (!temp)
48587 + /* integer and fraction are 0, we set FP to its max val */
48588 + fppShift = 31;
48589 + else
48590 + {
48591 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
48592 + * + all left zeroes of the fraction. */
48593 + fppShift=16;
48594 + /* count zeroes left of the higher used bit (in order to shift the value such that
48595 + * unused bits may be used for fraction).
48596 + */
48597 + while ((temp & 0x8000) == 0)
48598 + {
48599 + temp = temp << 1;
48600 + fppShift++;
48601 + }
48602 + }
48603 + }
48604 +
48605 + /*
48606 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
48607 + * fraction and the rest for integer */
48608 + /* now we re-calculate cir and pir_eir with the calculated FP */
48609 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
48610 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
48611 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
48612 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
48613 +
48614 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
48615 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
48616 +
48617 + /* convert FP as it should be written to reg.
48618 + * 0-15 --> 16-31
48619 + * 16-31 --> 0-15
48620 + */
48621 + *fpp = CalcFPP(fppShift);
48622 +}
48623 +
48624 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
48625 +{
48626 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48627 +
48628 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
48629 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
48630 +
48631 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
48632 +}
48633 +
48634 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
48635 + t_FmPcdPlcrProfileParams *p_ProfileParams,
48636 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
48637 +{
48638 + t_Error err = E_OK;
48639 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
48640 +
48641 + ASSERT_COND(p_FmPcd);
48642 +
48643 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
48644 + if (bitFor1Micro == 0)
48645 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
48646 +
48647 +/* Set G, Y, R Nia */
48648 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
48649 + if (err)
48650 + RETURN_ERROR(MAJOR, err, NO_MSG);
48651 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
48652 + if (err)
48653 + RETURN_ERROR(MAJOR, err, NO_MSG);
48654 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
48655 + if (err)
48656 + RETURN_ERROR(MAJOR, err, NO_MSG);
48657 +
48658 +/* Mode fmpl_pemode */
48659 + pemode = FM_PCD_PLCR_PEMODE_PI;
48660 +
48661 + switch (p_ProfileParams->algSelection)
48662 + {
48663 + case e_FM_PCD_PLCR_PASS_THROUGH:
48664 + p_PlcrRegs->fmpl_pecir = 0;
48665 + p_PlcrRegs->fmpl_pecbs = 0;
48666 + p_PlcrRegs->fmpl_pepepir_eir = 0;
48667 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
48668 + p_PlcrRegs->fmpl_pelts = 0;
48669 + p_PlcrRegs->fmpl_pects = 0;
48670 + p_PlcrRegs->fmpl_pepts_ets = 0;
48671 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
48672 + switch (p_ProfileParams->colorMode)
48673 + {
48674 + case e_FM_PCD_PLCR_COLOR_BLIND:
48675 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
48676 + switch (p_ProfileParams->color.dfltColor)
48677 + {
48678 + case e_FM_PCD_PLCR_GREEN:
48679 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
48680 + break;
48681 + case e_FM_PCD_PLCR_YELLOW:
48682 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
48683 + break;
48684 + case e_FM_PCD_PLCR_RED:
48685 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
48686 + break;
48687 + case e_FM_PCD_PLCR_OVERRIDE:
48688 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
48689 + break;
48690 + default:
48691 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48692 + }
48693 +
48694 + break;
48695 + case e_FM_PCD_PLCR_COLOR_AWARE:
48696 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
48697 + break;
48698 + default:
48699 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48700 + }
48701 + break;
48702 +
48703 + case e_FM_PCD_PLCR_RFC_2698:
48704 + /* Select algorithm MODE[ALG] = "01" */
48705 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
48706 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
48707 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
48708 + goto cont_rfc;
48709 + case e_FM_PCD_PLCR_RFC_4115:
48710 + /* Select algorithm MODE[ALG] = "10" */
48711 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
48712 +cont_rfc:
48713 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
48714 + switch (p_ProfileParams->colorMode)
48715 + {
48716 + case e_FM_PCD_PLCR_COLOR_BLIND:
48717 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
48718 + break;
48719 + case e_FM_PCD_PLCR_COLOR_AWARE:
48720 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
48721 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
48722 + switch (p_ProfileParams->color.override)
48723 + {
48724 + case e_FM_PCD_PLCR_GREEN:
48725 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
48726 + break;
48727 + case e_FM_PCD_PLCR_YELLOW:
48728 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
48729 + break;
48730 + case e_FM_PCD_PLCR_RED:
48731 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
48732 + break;
48733 + case e_FM_PCD_PLCR_OVERRIDE:
48734 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
48735 + break;
48736 + default:
48737 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48738 + }
48739 + break;
48740 + default:
48741 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48742 + }
48743 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
48744 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
48745 + {
48746 + case e_FM_PCD_PLCR_BYTE_MODE :
48747 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
48748 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
48749 + {
48750 + case e_FM_PCD_PLCR_L2_FRM_LEN:
48751 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
48752 + break;
48753 + case e_FM_PCD_PLCR_L3_FRM_LEN:
48754 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
48755 + break;
48756 + case e_FM_PCD_PLCR_L4_FRM_LEN:
48757 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
48758 + break;
48759 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
48760 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
48761 + break;
48762 + default:
48763 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48764 + }
48765 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
48766 + {
48767 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
48768 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
48769 + break;
48770 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
48771 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
48772 + break;
48773 + default:
48774 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48775 + }
48776 + break;
48777 + case e_FM_PCD_PLCR_PACKET_MODE :
48778 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
48779 + break;
48780 + default:
48781 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48782 + }
48783 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
48784 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
48785 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
48786 +
48787 + /* Configure Traffic Parameters*/
48788 + {
48789 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
48790 +
48791 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
48792 +
48793 + /* Set Committed Information Rate (CIR) */
48794 + p_PlcrRegs->fmpl_pecir = cir;
48795 + /* Set Committed Burst Size (CBS). */
48796 + p_PlcrRegs->fmpl_pecbs = cbs;
48797 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
48798 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
48799 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
48800 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
48801 +
48802 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
48803 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
48804 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
48805 + /* Committed Rate Token Bucket Size (CTS) */
48806 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
48807 +
48808 + /* Set the FPP based on calculation */
48809 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
48810 + }
48811 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
48812 + default:
48813 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48814 + }
48815 +
48816 + p_PlcrRegs->fmpl_pemode = pemode;
48817 +
48818 + p_PlcrRegs->fmpl_pegnia = gnia;
48819 + p_PlcrRegs->fmpl_peynia = ynia;
48820 + p_PlcrRegs->fmpl_pernia = rnia;
48821 +
48822 + /* Zero Counters */
48823 + p_PlcrRegs->fmpl_pegpc = 0;
48824 + p_PlcrRegs->fmpl_peypc = 0;
48825 + p_PlcrRegs->fmpl_perpc = 0;
48826 + p_PlcrRegs->fmpl_perypc = 0;
48827 + p_PlcrRegs->fmpl_perrpc = 0;
48828 +
48829 + return E_OK;
48830 +}
48831 +
48832 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
48833 +{
48834 + uint32_t profilesFound;
48835 + uint16_t i, k=0;
48836 + uint32_t intFlags;
48837 +
48838 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48839 +
48840 + if (!numOfProfiles)
48841 + return E_OK;
48842 +
48843 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
48844 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
48845 +
48846 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
48847 + /* Find numOfProfiles free profiles (may be spread) */
48848 + profilesFound = 0;
48849 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
48850 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
48851 + {
48852 + profilesFound++;
48853 + profilesIds[k] = i;
48854 + k++;
48855 + if (profilesFound == numOfProfiles)
48856 + break;
48857 + }
48858 +
48859 + if (profilesFound != numOfProfiles)
48860 + {
48861 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48862 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
48863 + }
48864 +
48865 + for (i = 0;i<k;i++)
48866 + {
48867 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
48868 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
48869 + }
48870 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48871 +
48872 + return E_OK;
48873 +}
48874 +
48875 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
48876 +{
48877 + uint16_t i;
48878 +
48879 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
48880 +
48881 + ASSERT_COND(numOfProfiles);
48882 +
48883 + for (i=0; i < numOfProfiles; i++)
48884 + {
48885 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
48886 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
48887 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
48888 + }
48889 +}
48890 +
48891 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
48892 +{
48893 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48894 +
48895 + /* this routine is protected by calling routine */
48896 +
48897 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48898 +
48899 + if (set)
48900 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
48901 + else
48902 + {
48903 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
48904 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
48905 + }
48906 +}
48907 +
48908 +/*********************************************/
48909 +/*............Policer Exception..............*/
48910 +/*********************************************/
48911 +static void EventsCB(t_Handle h_FmPcd)
48912 +{
48913 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48914 + uint32_t event, mask, force;
48915 +
48916 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
48917 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
48918 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
48919 +
48920 + event &= mask;
48921 +
48922 + /* clear the forced events */
48923 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
48924 + if (force & event)
48925 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
48926 +
48927 +
48928 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
48929 +
48930 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
48931 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
48932 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
48933 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
48934 +}
48935 +
48936 +/* ..... */
48937 +
48938 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
48939 +{
48940 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48941 + uint32_t event, force, captureReg, mask;
48942 +
48943 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
48944 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
48945 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
48946 +
48947 + event &= mask;
48948 +
48949 + /* clear the forced events */
48950 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
48951 + if (force & event)
48952 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
48953 +
48954 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
48955 +
48956 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
48957 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
48958 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
48959 + {
48960 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
48961 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
48962 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
48963 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
48964 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
48965 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
48966 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
48967 + }
48968 +}
48969 +
48970 +
48971 +/*****************************************************************************/
48972 +/* Inter-module API routines */
48973 +/*****************************************************************************/
48974 +
48975 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
48976 +{
48977 + t_FmPcdPlcr *p_FmPcdPlcr;
48978 + uint16_t i=0;
48979 +
48980 + UNUSED(p_FmPcd);
48981 + UNUSED(p_FmPcdParams);
48982 +
48983 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
48984 + if (!p_FmPcdPlcr)
48985 + {
48986 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
48987 + return NULL;
48988 + }
48989 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
48990 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
48991 + {
48992 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
48993 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
48994 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
48995 + }
48996 +
48997 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
48998 +
48999 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
49000 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
49001 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
49002 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
49003 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
49004 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
49005 +
49006 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
49007 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
49008 +
49009 + return p_FmPcdPlcr;
49010 +}
49011 +
49012 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
49013 +{
49014 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
49015 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49016 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49017 + t_Error err = E_OK;
49018 + uint32_t tmpReg32 = 0;
49019 + uint16_t base;
49020 +
49021 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
49022 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
49023 +
49024 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
49025 + if (!p_FmPcdPlcr->h_HwSpinlock)
49026 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
49027 +
49028 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
49029 + if (!p_FmPcdPlcr->h_SwSpinlock)
49030 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
49031 +
49032 + base = PlcrAllocProfilesForPartition(p_FmPcd,
49033 + p_FmPcdPlcr->partPlcrProfilesBase,
49034 + p_FmPcdPlcr->partNumOfPlcrProfiles,
49035 + p_FmPcd->guestId);
49036 + if (base == (uint16_t)ILLEGAL_BASE)
49037 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
49038 +
49039 + if (p_FmPcdPlcr->numOfSharedProfiles)
49040 + {
49041 + err = AllocSharedProfiles(p_FmPcd,
49042 + p_FmPcdPlcr->numOfSharedProfiles,
49043 + p_FmPcdPlcr->sharedProfilesIds);
49044 + if (err)
49045 + RETURN_ERROR(MAJOR, err,NO_MSG);
49046 + }
49047 +
49048 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49049 + return E_OK;
49050 +
49051 + /**********************FMPL_GCR******************/
49052 + tmpReg32 = 0;
49053 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
49054 + if (p_Param->plcrAutoRefresh)
49055 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
49056 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
49057 +
49058 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
49059 + /**********************FMPL_GCR******************/
49060 +
49061 + /**********************FMPL_EEVR******************/
49062 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
49063 + /**********************FMPL_EEVR******************/
49064 + /**********************FMPL_EIER******************/
49065 + tmpReg32 = 0;
49066 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
49067 + {
49068 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49069 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
49070 + }
49071 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
49072 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
49073 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
49074 + /**********************FMPL_EIER******************/
49075 +
49076 + /**********************FMPL_EVR******************/
49077 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
49078 + /**********************FMPL_EVR******************/
49079 + /**********************FMPL_IER******************/
49080 + tmpReg32 = 0;
49081 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
49082 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
49083 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
49084 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
49085 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
49086 + /**********************FMPL_IER******************/
49087 +
49088 + /* register even if no interrupts enabled, to allow future enablement */
49089 + FmRegisterIntr(p_FmPcd->h_Fm,
49090 + e_FM_MOD_PLCR,
49091 + 0,
49092 + e_FM_INTR_TYPE_ERR,
49093 + ErrorExceptionsCB,
49094 + p_FmPcd);
49095 + FmRegisterIntr(p_FmPcd->h_Fm,
49096 + e_FM_MOD_PLCR,
49097 + 0,
49098 + e_FM_INTR_TYPE_NORMAL,
49099 + EventsCB,
49100 + p_FmPcd);
49101 +
49102 + /* driver initializes one DFLT profile at the last entry*/
49103 + /**********************FMPL_DPMR******************/
49104 + tmpReg32 = 0;
49105 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
49106 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
49107 +
49108 + return E_OK;
49109 +}
49110 +
49111 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
49112 +{
49113 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
49114 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
49115 +
49116 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
49117 + FreeSharedProfiles(p_FmPcd,
49118 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
49119 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
49120 +
49121 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
49122 + PlcrFreeProfilesForPartition(p_FmPcd,
49123 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
49124 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
49125 + p_FmPcd->guestId);
49126 +
49127 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
49128 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
49129 +
49130 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
49131 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
49132 +
49133 + return E_OK;
49134 +}
49135 +
49136 +void PlcrEnable(t_FmPcd *p_FmPcd)
49137 +{
49138 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49139 +
49140 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
49141 +}
49142 +
49143 +void PlcrDisable(t_FmPcd *p_FmPcd)
49144 +{
49145 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49146 +
49147 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
49148 +}
49149 +
49150 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
49151 +{
49152 + uint32_t intFlags;
49153 + uint16_t profilesFound = 0;
49154 + int i = 0;
49155 +
49156 + ASSERT_COND(p_FmPcd);
49157 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
49158 +
49159 + if (!numOfProfiles)
49160 + return 0;
49161 +
49162 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
49163 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
49164 + return (uint16_t)ILLEGAL_BASE;
49165 +
49166 + if (p_FmPcd->h_IpcSession)
49167 + {
49168 + t_FmIpcResourceAllocParams ipcAllocParams;
49169 + t_FmPcdIpcMsg msg;
49170 + t_FmPcdIpcReply reply;
49171 + t_Error err;
49172 + uint32_t replyLength;
49173 +
49174 + memset(&msg, 0, sizeof(msg));
49175 + memset(&reply, 0, sizeof(reply));
49176 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49177 + ipcAllocParams.guestId = p_FmPcd->guestId;
49178 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
49179 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
49180 + msg.msgId = FM_PCD_ALLOC_PROFILES;
49181 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49182 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
49183 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49184 + (uint8_t*)&msg,
49185 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49186 + (uint8_t*)&reply,
49187 + &replyLength,
49188 + NULL,
49189 + NULL);
49190 + if ((err != E_OK) ||
49191 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
49192 + {
49193 + REPORT_ERROR(MAJOR, err, NO_MSG);
49194 + return (uint16_t)ILLEGAL_BASE;
49195 + }
49196 + else
49197 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
49198 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
49199 + {
49200 + REPORT_ERROR(MAJOR, err, NO_MSG);
49201 + return (uint16_t)ILLEGAL_BASE;
49202 + }
49203 + }
49204 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49205 + {
49206 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
49207 + return (uint16_t)ILLEGAL_BASE;
49208 + }
49209 +
49210 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
49211 + for (i=base; i<(base+numOfProfiles); i++)
49212 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
49213 + profilesFound++;
49214 + else
49215 + break;
49216 +
49217 + if (profilesFound == numOfProfiles)
49218 + for (i=base; i<(base+numOfProfiles); i++)
49219 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
49220 + else
49221 + {
49222 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
49223 + return (uint16_t)ILLEGAL_BASE;
49224 + }
49225 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
49226 +
49227 + return base;
49228 +}
49229 +
49230 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
49231 +{
49232 + int i = 0;
49233 +
49234 + ASSERT_COND(p_FmPcd);
49235 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
49236 +
49237 + if (p_FmPcd->h_IpcSession)
49238 + {
49239 + t_FmIpcResourceAllocParams ipcAllocParams;
49240 + t_FmPcdIpcMsg msg;
49241 + t_Error err;
49242 +
49243 + memset(&msg, 0, sizeof(msg));
49244 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49245 + ipcAllocParams.guestId = p_FmPcd->guestId;
49246 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
49247 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
49248 + msg.msgId = FM_PCD_FREE_PROFILES;
49249 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49250 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49251 + (uint8_t*)&msg,
49252 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49253 + NULL,
49254 + NULL,
49255 + NULL,
49256 + NULL);
49257 + if (err != E_OK)
49258 + REPORT_ERROR(MAJOR, err, NO_MSG);
49259 + return;
49260 + }
49261 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49262 + {
49263 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
49264 + return;
49265 + }
49266 +
49267 + for (i=base; i<(base+numOfProfiles); i++)
49268 + {
49269 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
49270 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
49271 + else
49272 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
49273 + }
49274 +}
49275 +
49276 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
49277 + uint8_t hardwarePortId,
49278 + uint16_t numOfProfiles,
49279 + uint16_t base)
49280 +{
49281 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49282 + uint32_t log2Num, tmpReg32;
49283 +
49284 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49285 + !p_Regs &&
49286 + p_FmPcd->h_IpcSession)
49287 + {
49288 + t_FmIpcResourceAllocParams ipcAllocParams;
49289 + t_FmPcdIpcMsg msg;
49290 + t_Error err;
49291 +
49292 + memset(&msg, 0, sizeof(msg));
49293 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49294 + ipcAllocParams.guestId = hardwarePortId;
49295 + ipcAllocParams.num = numOfProfiles;
49296 + ipcAllocParams.base = base;
49297 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
49298 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49299 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49300 + (uint8_t*)&msg,
49301 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49302 + NULL,
49303 + NULL,
49304 + NULL,
49305 + NULL);
49306 + if (err != E_OK)
49307 + RETURN_ERROR(MAJOR, err, NO_MSG);
49308 + return E_OK;
49309 + }
49310 + else if (!p_Regs)
49311 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49312 + ("Either IPC or 'baseAddress' is required!"));
49313 +
49314 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
49315 +
49316 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
49317 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
49318 + ("The requesting port has already an allocated profiles window."));
49319 +
49320 + /**********************FMPL_PMRx******************/
49321 + LOG2((uint64_t)numOfProfiles, log2Num);
49322 + tmpReg32 = base;
49323 + tmpReg32 |= log2Num << 16;
49324 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
49325 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
49326 +
49327 + return E_OK;
49328 +}
49329 +
49330 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
49331 +{
49332 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49333 +
49334 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49335 + !p_Regs &&
49336 + p_FmPcd->h_IpcSession)
49337 + {
49338 + t_FmIpcResourceAllocParams ipcAllocParams;
49339 + t_FmPcdIpcMsg msg;
49340 + t_Error err;
49341 +
49342 + memset(&msg, 0, sizeof(msg));
49343 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49344 + ipcAllocParams.guestId = hardwarePortId;
49345 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
49346 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49347 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49348 + (uint8_t*)&msg,
49349 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49350 + NULL,
49351 + NULL,
49352 + NULL,
49353 + NULL);
49354 + if (err != E_OK)
49355 + RETURN_ERROR(MAJOR, err, NO_MSG);
49356 + return E_OK;
49357 + }
49358 + else if (!p_Regs)
49359 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49360 + ("Either IPC or 'baseAddress' is required!"));
49361 +
49362 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
49363 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
49364 +
49365 + return E_OK;
49366 +}
49367 +
49368 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
49369 +{
49370 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49371 + t_Error err = E_OK;
49372 + uint32_t profilesFound;
49373 + uint32_t intFlags;
49374 + uint16_t i, first, swPortIndex = 0;
49375 +
49376 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49377 +
49378 + if (!numOfProfiles)
49379 + return E_OK;
49380 +
49381 + ASSERT_COND(hardwarePortId);
49382 +
49383 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
49384 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
49385 +
49386 + if (!POWER_OF_2(numOfProfiles))
49387 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
49388 +
49389 + first = 0;
49390 + profilesFound = 0;
49391 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
49392 +
49393 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
49394 + {
49395 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
49396 + {
49397 + profilesFound++;
49398 + i++;
49399 + if (profilesFound == numOfProfiles)
49400 + break;
49401 + }
49402 + else
49403 + {
49404 + profilesFound = 0;
49405 + /* advance i to the next aligned address */
49406 + i = first = (uint16_t)(first + numOfProfiles);
49407 + }
49408 + }
49409 +
49410 + if (profilesFound == numOfProfiles)
49411 + {
49412 + for (i=first; i<first + numOfProfiles; i++)
49413 + {
49414 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
49415 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
49416 + }
49417 + }
49418 + else
49419 + {
49420 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49421 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
49422 + }
49423 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49424 +
49425 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
49426 + if (err)
49427 + {
49428 + RETURN_ERROR(MAJOR, err, NO_MSG);
49429 + }
49430 +
49431 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
49432 +
49433 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
49434 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
49435 +
49436 + return E_OK;
49437 +}
49438 +
49439 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
49440 +{
49441 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49442 + t_Error err = E_OK;
49443 + uint32_t intFlags;
49444 + uint16_t i, swPortIndex = 0;
49445 +
49446 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
49447 +
49448 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49449 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49450 +
49451 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
49452 +
49453 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
49454 + if (err)
49455 + RETURN_ERROR(MAJOR, err,NO_MSG);
49456 +
49457 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
49458 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
49459 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
49460 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
49461 + i++)
49462 + {
49463 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
49464 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
49465 +
49466 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
49467 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
49468 + }
49469 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49470 +
49471 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
49472 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
49473 +
49474 + return E_OK;
49475 +}
49476 +
49477 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
49478 +{
49479 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49480 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49481 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
49482 + uint32_t tmpReg32, intFlags;
49483 + t_Error err;
49484 +
49485 + /* Calling function locked all PCD modules, so no need to lock here */
49486 +
49487 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
49488 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
49489 +
49490 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
49491 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
49492 +
49493 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
49494 +
49495 + if (p_FmPcd->h_Hc)
49496 + {
49497 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
49498 +
49499 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
49500 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
49501 +
49502 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49503 + return err;
49504 + }
49505 +
49506 + /* lock the HW because once we read the registers we don't want them to be changed
49507 + * by another access. (We can copy to a tmp location and release the lock!) */
49508 +
49509 + intFlags = PlcrHwLock(p_FmPcdPlcr);
49510 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
49511 +
49512 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
49513 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
49514 + {
49515 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
49516 + {
49517 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
49518 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
49519 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
49520 + {
49521 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49522 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49523 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
49524 + }
49525 +
49526 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
49527 + {
49528 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
49529 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
49530 + {
49531 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49532 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49533 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
49534 + }
49535 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
49536 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
49537 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
49538 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
49539 + WritePar(p_FmPcd, tmpReg32);
49540 + }
49541 +
49542 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
49543 + {
49544 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
49545 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
49546 + {
49547 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49548 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49549 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
49550 + }
49551 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
49552 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
49553 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
49554 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
49555 + WritePar(p_FmPcd, tmpReg32);
49556 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49557 + }
49558 +
49559 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
49560 + {
49561 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
49562 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
49563 + {
49564 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49565 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49566 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
49567 + }
49568 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
49569 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
49570 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
49571 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
49572 + WritePar(p_FmPcd, tmpReg32);
49573 +
49574 + }
49575 + }
49576 + }
49577 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49578 +
49579 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
49580 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
49581 +
49582 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49583 +
49584 + return E_OK;
49585 +}
49586 +
49587 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49588 +{
49589 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49590 +
49591 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49592 +
49593 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
49594 +}
49595 +
49596 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49597 +{
49598 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49599 +
49600 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49601 +
49602 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
49603 +}
49604 +
49605 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49606 +{
49607 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49608 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49609 +
49610 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
49611 +
49612 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
49613 +}
49614 +
49615 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49616 +{
49617 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49618 + uint32_t intFlags;
49619 +
49620 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49621 +
49622 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
49623 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
49624 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
49625 +}
49626 +
49627 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49628 +{
49629 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49630 + uint32_t intFlags;
49631 +
49632 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49633 +
49634 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
49635 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
49636 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
49637 +}
49638 +
49639 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
49640 +{
49641 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
49642 +}
49643 +
49644 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
49645 + e_FmPcdProfileTypeSelection profileType,
49646 + t_Handle h_FmPort,
49647 + uint16_t relativeProfile,
49648 + uint16_t *p_AbsoluteId)
49649 +{
49650 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49651 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49652 + uint8_t i;
49653 +
49654 + switch (profileType)
49655 + {
49656 + case e_FM_PCD_PLCR_PORT_PRIVATE:
49657 + /* get port PCD id from port handle */
49658 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
49659 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
49660 + break;
49661 + if (i == FM_MAX_NUM_OF_PORTS)
49662 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
49663 +
49664 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
49665 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
49666 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
49667 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
49668 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
49669 + break;
49670 + case e_FM_PCD_PLCR_SHARED:
49671 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
49672 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
49673 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
49674 + break;
49675 + default:
49676 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
49677 + }
49678 +
49679 + return E_OK;
49680 +}
49681 +
49682 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
49683 +{
49684 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49685 + uint16_t swPortIndex = 0;
49686 +
49687 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
49688 +
49689 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
49690 +}
49691 +
49692 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
49693 +{
49694 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49695 + uint16_t swPortIndex = 0;
49696 +
49697 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
49698 +
49699 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
49700 +
49701 +}
49702 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
49703 +{
49704 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
49705 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
49706 +}
49707 +
49708 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
49709 +{
49710 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
49711 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
49712 + FM_PCD_PLCR_PAR_PWSEL_MASK);
49713 +}
49714 +
49715 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
49716 +{
49717 +
49718 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
49719 + return TRUE;
49720 + else
49721 + return FALSE;
49722 +}
49723 +
49724 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
49725 +{
49726 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
49727 + FM_PCD_PLCR_PAR_R |
49728 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
49729 + FM_PCD_PLCR_PAR_PWSEL_MASK);
49730 +}
49731 +
49732 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
49733 +{
49734 + switch (counter)
49735 + {
49736 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
49737 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
49738 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
49739 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
49740 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
49741 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
49742 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
49743 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
49744 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
49745 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
49746 + default:
49747 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49748 + return 0;
49749 + }
49750 +}
49751 +
49752 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
49753 +{
49754 +
49755 + uint32_t tmpReg32 = 0;
49756 +
49757 + if (green)
49758 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
49759 + if (yellow)
49760 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
49761 + if (red)
49762 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
49763 +
49764 + return tmpReg32;
49765 +}
49766 +
49767 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
49768 +{
49769 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49770 +
49771 + /* this routine is protected by calling routine */
49772 +
49773 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49774 +
49775 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
49776 +}
49777 +
49778 +/*********************** End of inter-module routines ************************/
49779 +
49780 +
49781 +/**************************************************/
49782 +/*............Policer API.........................*/
49783 +/**************************************************/
49784 +
49785 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
49786 +{
49787 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49788 +
49789 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49790 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49791 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
49792 +
49793 + if (!FmIsMaster(p_FmPcd->h_Fm))
49794 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
49795 +
49796 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
49797 +
49798 + return E_OK;
49799 +}
49800 +
49801 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
49802 +{
49803 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49804 +
49805 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49806 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49807 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
49808 +
49809 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
49810 +
49811 + return E_OK;
49812 +}
49813 +
49814 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
49815 +{
49816 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49817 + uint32_t tmpReg32;
49818 +
49819 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49820 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49821 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
49822 +
49823 + if (!FmIsMaster(p_FmPcd->h_Fm))
49824 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
49825 +
49826 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
49827 + if (enable)
49828 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
49829 + else
49830 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
49831 +
49832 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
49833 + return E_OK;
49834 +}
49835 +
49836 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
49837 + t_FmPcdPlcrProfileParams *p_ProfileParams)
49838 +{
49839 + t_FmPcd *p_FmPcd;
49840 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
49841 + t_FmPcdPlcrProfileRegs plcrProfileReg;
49842 + uint32_t intFlags;
49843 + uint16_t absoluteProfileId;
49844 + t_Error err = E_OK;
49845 + uint32_t tmpReg32;
49846 + t_FmPcdPlcrProfile *p_Profile;
49847 +
49848 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
49849 +
49850 + if (p_ProfileParams->modify)
49851 + {
49852 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
49853 + p_FmPcd = p_Profile->h_FmPcd;
49854 + absoluteProfileId = p_Profile->absoluteProfileId;
49855 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
49856 + {
49857 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
49858 + return NULL;
49859 + }
49860 +
49861 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
49862 +
49863 + /* Try lock profile using flag */
49864 + if (!PlcrProfileFlagTryLock(p_Profile))
49865 + {
49866 + DBG(TRACE, ("Profile Try Lock - BUSY"));
49867 + /* Signal to caller BUSY condition */
49868 + p_ProfileParams->id.h_Profile = NULL;
49869 + return NULL;
49870 + }
49871 + }
49872 + else
49873 + {
49874 + p_FmPcd = (t_FmPcd*)h_FmPcd;
49875 +
49876 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
49877 +
49878 + /* SMP: needs to be protected only if another core now changes the windows */
49879 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
49880 + p_ProfileParams->id.newParams.profileType,
49881 + p_ProfileParams->id.newParams.h_FmPort,
49882 + p_ProfileParams->id.newParams.relativeProfileId,
49883 + &absoluteProfileId);
49884 + if (err)
49885 + {
49886 + REPORT_ERROR(MAJOR, err, NO_MSG);
49887 + return NULL;
49888 + }
49889 +
49890 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
49891 + {
49892 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
49893 + return NULL;
49894 + }
49895 +
49896 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
49897 + {
49898 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
49899 + return NULL;
49900 + }
49901 +
49902 + /* initialize profile struct */
49903 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
49904 +
49905 + p_Profile->h_FmPcd = p_FmPcd;
49906 + p_Profile->absoluteProfileId = absoluteProfileId;
49907 +
49908 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
49909 + if (!p_Profile->p_Lock)
49910 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
49911 + }
49912 +
49913 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
49914 +
49915 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
49916 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
49917 +
49918 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
49919 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
49920 +
49921 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
49922 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
49923 +
49924 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
49925 +
49926 + /* build the policer profile registers */
49927 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
49928 + if (err)
49929 + {
49930 + REPORT_ERROR(MAJOR, err, NO_MSG);
49931 + if (p_ProfileParams->modify)
49932 + /* unlock */
49933 + PlcrProfileFlagUnlock(p_Profile);
49934 + if (!p_ProfileParams->modify &&
49935 + p_Profile->p_Lock)
49936 + /* release allocated Profile lock */
49937 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
49938 + return NULL;
49939 + }
49940 +
49941 + if (p_FmPcd->h_Hc)
49942 + {
49943 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
49944 + if (p_ProfileParams->modify)
49945 + PlcrProfileFlagUnlock(p_Profile);
49946 + if (err)
49947 + {
49948 + /* release the allocated scheme lock */
49949 + if (!p_ProfileParams->modify &&
49950 + p_Profile->p_Lock)
49951 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
49952 +
49953 + return NULL;
49954 + }
49955 + if (!p_ProfileParams->modify)
49956 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
49957 + return (t_Handle)p_Profile;
49958 + }
49959 +
49960 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49961 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
49962 +
49963 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
49964 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
49965 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
49966 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
49967 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
49968 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
49969 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
49970 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
49971 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
49972 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
49973 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
49974 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
49975 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
49976 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
49977 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
49978 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
49979 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
49980 +
49981 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
49982 + WritePar(p_FmPcd, tmpReg32);
49983 +
49984 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49985 +
49986 + if (!p_ProfileParams->modify)
49987 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
49988 + else
49989 + PlcrProfileFlagUnlock(p_Profile);
49990 +
49991 + return (t_Handle)p_Profile;
49992 +}
49993 +
49994 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
49995 +{
49996 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
49997 + t_FmPcd *p_FmPcd;
49998 + uint16_t profileIndx;
49999 + uint32_t tmpReg32, intFlags;
50000 + t_Error err;
50001 +
50002 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
50003 + p_FmPcd = p_Profile->h_FmPcd;
50004 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50005 +
50006 + profileIndx = p_Profile->absoluteProfileId;
50007 +
50008 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
50009 +
50010 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
50011 +
50012 + if (p_FmPcd->h_Hc)
50013 + {
50014 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
50015 + if (p_Profile->p_Lock)
50016 + /* release allocated Profile lock */
50017 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
50018 +
50019 + return err;
50020 + }
50021 +
50022 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50023 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
50024 +
50025 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
50026 + WritePar(p_FmPcd, tmpReg32);
50027 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50028 +
50029 +
50030 + if (p_Profile->p_Lock)
50031 + /* release allocated Profile lock */
50032 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
50033 +
50034 + /* we do not memset profile as all its fields are being re-initialized at "set",
50035 + * plus its allocation information is still valid. */
50036 + return E_OK;
50037 +}
50038 +
50039 +/***************************************************/
50040 +/*............Policer Profile Counter..............*/
50041 +/***************************************************/
50042 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
50043 +{
50044 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
50045 + t_FmPcd *p_FmPcd;
50046 + uint16_t profileIndx;
50047 + uint32_t intFlags, counterVal = 0;
50048 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
50049 +
50050 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
50051 + p_FmPcd = p_Profile->h_FmPcd;
50052 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50053 +
50054 + if (p_FmPcd->h_Hc)
50055 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
50056 +
50057 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
50058 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
50059 +
50060 + profileIndx = p_Profile->absoluteProfileId;
50061 +
50062 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
50063 + {
50064 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
50065 + return 0;
50066 + }
50067 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50068 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
50069 +
50070 + switch (counter)
50071 + {
50072 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
50073 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
50074 + break;
50075 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
50076 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
50077 + break;
50078 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
50079 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
50080 + break;
50081 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
50082 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
50083 + break;
50084 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
50085 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
50086 + break;
50087 + default:
50088 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
50089 + break;
50090 + }
50091 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50092 +
50093 + return counterVal;
50094 +}
50095 +
50096 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
50097 +{
50098 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
50099 + t_FmPcd *p_FmPcd;
50100 + uint16_t profileIndx;
50101 + uint32_t tmpReg32, intFlags;
50102 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
50103 +
50104 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
50105 +
50106 + p_FmPcd = p_Profile->h_FmPcd;
50107 + profileIndx = p_Profile->absoluteProfileId;
50108 +
50109 + if (p_FmPcd->h_Hc)
50110 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
50111 +
50112 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
50113 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
50114 +
50115 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50116 + switch (counter)
50117 + {
50118 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
50119 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
50120 + break;
50121 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
50122 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
50123 + break;
50124 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
50125 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
50126 + break;
50127 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
50128 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
50129 + break;
50130 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
50131 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
50132 + break;
50133 + default:
50134 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50135 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
50136 + }
50137 +
50138 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
50139 + * Profile Number, PWSEL=0xFFFF (select all words).
50140 + */
50141 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
50142 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
50143 + WritePar(p_FmPcd, tmpReg32);
50144 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50145 +
50146 + return E_OK;
50147 +}
50148 --- /dev/null
50149 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
50150 @@ -0,0 +1,165 @@
50151 +/*
50152 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50153 + *
50154 + * Redistribution and use in source and binary forms, with or without
50155 + * modification, are permitted provided that the following conditions are met:
50156 + * * Redistributions of source code must retain the above copyright
50157 + * notice, this list of conditions and the following disclaimer.
50158 + * * Redistributions in binary form must reproduce the above copyright
50159 + * notice, this list of conditions and the following disclaimer in the
50160 + * documentation and/or other materials provided with the distribution.
50161 + * * Neither the name of Freescale Semiconductor nor the
50162 + * names of its contributors may be used to endorse or promote products
50163 + * derived from this software without specific prior written permission.
50164 + *
50165 + *
50166 + * ALTERNATIVELY, this software may be distributed under the terms of the
50167 + * GNU General Public License ("GPL") as published by the Free Software
50168 + * Foundation, either version 2 of that License or (at your option) any
50169 + * later version.
50170 + *
50171 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50172 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50173 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50174 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50175 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50176 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50177 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50178 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50179 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50180 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50181 + */
50182 +
50183 +
50184 +/******************************************************************************
50185 + @File fm_plcr.h
50186 +
50187 + @Description FM Policer private header
50188 +*//***************************************************************************/
50189 +#ifndef __FM_PLCR_H
50190 +#define __FM_PLCR_H
50191 +
50192 +#include "std_ext.h"
50193 +
50194 +
50195 +/***********************************************************************/
50196 +/* Policer defines */
50197 +/***********************************************************************/
50198 +
50199 +#define FM_PCD_PLCR_PAR_GO 0x80000000
50200 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
50201 +#define FM_PCD_PLCR_PAR_R 0x40000000
50202 +
50203 +/* shifts */
50204 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
50205 +
50206 +/* masks */
50207 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
50208 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
50209 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
50210 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
50211 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
50212 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
50213 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
50214 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
50215 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
50216 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
50217 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
50218 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
50219 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
50220 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
50221 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
50222 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
50223 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
50224 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
50225 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
50226 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
50227 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
50228 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
50229 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
50230 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
50231 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
50232 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
50233 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
50234 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
50235 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
50236 +
50237 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
50238 +
50239 +#define FM_PCD_PLCR_GCR_EN 0x80000000
50240 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
50241 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
50242 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
50243 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
50244 +
50245 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
50246 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
50247 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
50248 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
50249 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
50250 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
50251 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
50252 +
50253 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
50254 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
50255 +
50256 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
50257 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
50258 +/* PWSEL Selctive select options */
50259 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
50260 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
50261 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
50262 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
50263 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
50264 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
50265 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
50266 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
50267 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
50268 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
50269 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
50270 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
50271 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
50272 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
50273 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
50274 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
50275 +
50276 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
50277 + 1-> 2^N specific locations. */
50278 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
50279 + 2-> 2^(N-1) base locations. */
50280 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
50281 + 4-> 2^(N-2) base locations. */
50282 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
50283 + 8->2^(N-3) base locations. */
50284 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
50285 + 16-> 2^(N-4) base locations. */
50286 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
50287 + 32-> 2^(N-5) base locations. */
50288 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
50289 + 64-> 2^(N-6) base locations. */
50290 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
50291 + 128-> 2^(N-7) base locations. */
50292 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
50293 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
50294 +
50295 +#define FM_PCD_PLCR_PMR_V 0x80000000
50296 +#define PLCR_ERR_ECC_CAP 0x80000000
50297 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
50298 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
50299 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
50300 +
50301 +#define PLCR_ERR_UNINIT_CAP 0x80000000
50302 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
50303 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
50304 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
50305 +
50306 +/* shifts */
50307 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
50308 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
50309 +
50310 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
50311 +
50312 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
50313 +
50314 +
50315 +#endif /* __FM_PLCR_H */
50316 --- /dev/null
50317 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
50318 @@ -0,0 +1,423 @@
50319 +/*
50320 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50321 + *
50322 + * Redistribution and use in source and binary forms, with or without
50323 + * modification, are permitted provided that the following conditions are met:
50324 + * * Redistributions of source code must retain the above copyright
50325 + * notice, this list of conditions and the following disclaimer.
50326 + * * Redistributions in binary form must reproduce the above copyright
50327 + * notice, this list of conditions and the following disclaimer in the
50328 + * documentation and/or other materials provided with the distribution.
50329 + * * Neither the name of Freescale Semiconductor nor the
50330 + * names of its contributors may be used to endorse or promote products
50331 + * derived from this software without specific prior written permission.
50332 + *
50333 + *
50334 + * ALTERNATIVELY, this software may be distributed under the terms of the
50335 + * GNU General Public License ("GPL") as published by the Free Software
50336 + * Foundation, either version 2 of that License or (at your option) any
50337 + * later version.
50338 + *
50339 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50340 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50341 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50342 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50343 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50344 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50345 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50346 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50347 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50348 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50349 + */
50350 +
50351 +
50352 +/******************************************************************************
50353 + @File fm_pcd.c
50354 +
50355 + @Description FM PCD ...
50356 +*//***************************************************************************/
50357 +#include <linux/math64.h>
50358 +#include "std_ext.h"
50359 +#include "error_ext.h"
50360 +#include "string_ext.h"
50361 +#include "debug_ext.h"
50362 +#include "net_ext.h"
50363 +
50364 +#include "fm_common.h"
50365 +#include "fm_pcd.h"
50366 +#include "fm_pcd_ipc.h"
50367 +#include "fm_prs.h"
50368 +#include "fsl_fman_prs.h"
50369 +
50370 +
50371 +static void PcdPrsErrorException(t_Handle h_FmPcd)
50372 +{
50373 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50374 + uint32_t event, ev_mask;
50375 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50376 +
50377 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50378 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
50379 +
50380 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
50381 +
50382 + fman_prs_ack_err_event(PrsRegs, event);
50383 +
50384 + DBG(TRACE, ("parser error - 0x%08x\n",event));
50385 +
50386 + if(event & FM_PCD_PRS_DOUBLE_ECC)
50387 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
50388 +}
50389 +
50390 +static void PcdPrsException(t_Handle h_FmPcd)
50391 +{
50392 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50393 + uint32_t event, ev_mask;
50394 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50395 +
50396 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50397 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
50398 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
50399 +
50400 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
50401 +
50402 + DBG(TRACE, ("parser event - 0x%08x\n",event));
50403 +
50404 + fman_prs_ack_expt_event(PrsRegs, event);
50405 +
50406 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
50407 +}
50408 +
50409 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
50410 +{
50411 + t_FmPcdPrs *p_FmPcdPrs;
50412 + uintptr_t baseAddr;
50413 +
50414 + UNUSED(p_FmPcd);
50415 + UNUSED(p_FmPcdParams);
50416 +
50417 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
50418 + if (!p_FmPcdPrs)
50419 + {
50420 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
50421 + return NULL;
50422 + }
50423 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
50424 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
50425 +
50426 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
50427 + {
50428 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
50429 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
50430 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
50431 + }
50432 +
50433 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
50434 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
50435 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
50436 +
50437 + return p_FmPcdPrs;
50438 +}
50439 +
50440 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
50441 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
50442 +#else
50443 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
50444 +#endif /* FM_CAPWAP_SUPPORT */
50445 +
50446 +t_Error PrsInit(t_FmPcd *p_FmPcd)
50447 +{
50448 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
50449 + uint32_t *p_TmpCode;
50450 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
50451 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
50452 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50453 + uint32_t i;
50454 +
50455 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
50456 +
50457 + /* nothing to do in guest-partition */
50458 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
50459 + return E_OK;
50460 +
50461 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
50462 + if (!p_TmpCode)
50463 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
50464 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
50465 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
50466 +
50467 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
50468 +
50469 + /* register even if no interrupts enabled, to allow future enablement */
50470 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
50471 +
50472 + /* register even if no interrupts enabled, to allow future enablement */
50473 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
50474 +
50475 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
50476 + FmEnableRamsEcc(p_FmPcd->h_Fm);
50477 +
50478 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
50479 + FmEnableRamsEcc(p_FmPcd->h_Fm);
50480 +
50481 + /* load sw parser Ip-Frag patch */
50482 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
50483 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
50484 +
50485 + XX_FreeSmart(p_TmpCode);
50486 +
50487 + return E_OK;
50488 +}
50489 +
50490 +void PrsFree(t_FmPcd *p_FmPcd)
50491 +{
50492 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50493 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
50494 + /* register even if no interrupts enabled, to allow future enablement */
50495 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
50496 +}
50497 +
50498 +void PrsEnable(t_FmPcd *p_FmPcd)
50499 +{
50500 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50501 +
50502 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50503 + fman_prs_enable(PrsRegs);
50504 +}
50505 +
50506 +void PrsDisable(t_FmPcd *p_FmPcd)
50507 +{
50508 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50509 +
50510 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50511 + fman_prs_disable(PrsRegs);
50512 +}
50513 +
50514 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
50515 +{
50516 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50517 +
50518 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50519 + return fman_prs_is_enabled(PrsRegs);
50520 +}
50521 +
50522 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
50523 +{
50524 + struct fman_prs_regs *PrsRegs;
50525 + uint32_t bitMask = 0;
50526 + uint8_t prsPortId;
50527 +
50528 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
50529 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50530 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
50531 +
50532 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50533 +
50534 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
50535 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
50536 +
50537 + if (include)
50538 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
50539 + else
50540 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
50541 +
50542 + fman_prs_set_stst_port_msk(PrsRegs,
50543 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
50544 +
50545 + return E_OK;
50546 +}
50547 +
50548 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
50549 +{
50550 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50551 + t_Error err;
50552 +
50553 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
50554 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50555 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
50556 +
50557 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
50558 + p_FmPcd->h_IpcSession)
50559 + {
50560 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
50561 + t_FmPcdIpcMsg msg;
50562 +
50563 + prsIncludePortParams.hardwarePortId = hardwarePortId;
50564 + prsIncludePortParams.include = include;
50565 + memset(&msg, 0, sizeof(msg));
50566 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
50567 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
50568 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
50569 + (uint8_t*)&msg,
50570 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
50571 + NULL,
50572 + NULL,
50573 + NULL,
50574 + NULL);
50575 + if (err != E_OK)
50576 + RETURN_ERROR(MAJOR, err, NO_MSG);
50577 + return E_OK;
50578 + }
50579 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
50580 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
50581 + ("running in guest-mode without IPC!"));
50582 +
50583 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
50584 +}
50585 +
50586 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
50587 +{
50588 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50589 + t_FmPcdPrsLabelParams *p_Label;
50590 + int i;
50591 +
50592 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
50593 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
50594 +
50595 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
50596 + p_FmPcd->h_IpcSession)
50597 + {
50598 + t_Error err = E_OK;
50599 + t_FmPcdIpcSwPrsLable labelParams;
50600 + t_FmPcdIpcMsg msg;
50601 + uint32_t prsOffset = 0;
50602 + t_FmPcdIpcReply reply;
50603 + uint32_t replyLength;
50604 +
50605 + memset(&reply, 0, sizeof(reply));
50606 + memset(&msg, 0, sizeof(msg));
50607 + labelParams.enumHdr = (uint32_t)hdr;
50608 + labelParams.indexPerHdr = indexPerHdr;
50609 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
50610 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
50611 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
50612 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
50613 + (uint8_t*)&msg,
50614 + sizeof(msg.msgId) +sizeof(labelParams),
50615 + (uint8_t*)&reply,
50616 + &replyLength,
50617 + NULL,
50618 + NULL);
50619 + if (err != E_OK)
50620 + RETURN_ERROR(MAJOR, err, NO_MSG);
50621 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
50622 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
50623 +
50624 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
50625 + return prsOffset;
50626 + }
50627 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
50628 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
50629 + ("running in guest-mode without IPC!"));
50630 +
50631 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
50632 +
50633 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
50634 + {
50635 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
50636 +
50637 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
50638 + return p_Label->instructionOffset;
50639 + }
50640 +
50641 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
50642 + return (uint32_t)ILLEGAL_BASE;
50643 +}
50644 +
50645 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
50646 +{
50647 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50648 + struct fman_prs_regs *PrsRegs;
50649 +
50650 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
50651 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
50652 +
50653 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50654 +
50655 +
50656 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
50657 + {
50658 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
50659 + return;
50660 + }
50661 +
50662 + fman_prs_set_stst(PrsRegs, enable);
50663 +}
50664 +
50665 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
50666 +{
50667 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50668 + uint32_t *p_LoadTarget;
50669 + uint32_t *p_TmpCode;
50670 + int i;
50671 +
50672 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50673 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
50674 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
50675 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
50676 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
50677 +
50678 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
50679 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
50680 +
50681 + if (!p_SwPrs->override)
50682 + {
50683 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
50684 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
50685 + }
50686 + else
50687 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
50688 +
50689 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
50690 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
50691 +
50692 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
50693 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
50694 +
50695 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
50696 + if (!p_TmpCode)
50697 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
50698 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
50699 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
50700 +
50701 + /* save sw parser labels */
50702 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
50703 + p_SwPrs->labelsTable,
50704 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
50705 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
50706 +
50707 + /* load sw parser code */
50708 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
50709 +
50710 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
50711 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
50712 +
50713 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
50714 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
50715 +
50716 + /* copy data parameters */
50717 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
50718 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
50719 +
50720 + /* Clear last 4 bytes */
50721 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
50722 +
50723 + XX_FreeSmart(p_TmpCode);
50724 +
50725 + return E_OK;
50726 +}
50727 +
50728 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
50729 +{
50730 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50731 +
50732 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50733 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
50734 +
50735 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
50736 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
50737 +
50738 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
50739 +
50740 + return E_OK;
50741 +}
50742 --- /dev/null
50743 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
50744 @@ -0,0 +1,316 @@
50745 +/*
50746 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50747 + *
50748 + * Redistribution and use in source and binary forms, with or without
50749 + * modification, are permitted provided that the following conditions are met:
50750 + * * Redistributions of source code must retain the above copyright
50751 + * notice, this list of conditions and the following disclaimer.
50752 + * * Redistributions in binary form must reproduce the above copyright
50753 + * notice, this list of conditions and the following disclaimer in the
50754 + * documentation and/or other materials provided with the distribution.
50755 + * * Neither the name of Freescale Semiconductor nor the
50756 + * names of its contributors may be used to endorse or promote products
50757 + * derived from this software without specific prior written permission.
50758 + *
50759 + *
50760 + * ALTERNATIVELY, this software may be distributed under the terms of the
50761 + * GNU General Public License ("GPL") as published by the Free Software
50762 + * Foundation, either version 2 of that License or (at your option) any
50763 + * later version.
50764 + *
50765 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50766 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50767 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50768 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50769 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50770 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50771 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50772 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50773 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50774 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50775 + */
50776 +
50777 +
50778 +/******************************************************************************
50779 + @File fm_prs.h
50780 +
50781 + @Description FM Parser private header
50782 + *//***************************************************************************/
50783 +#ifndef __FM_PRS_H
50784 +#define __FM_PRS_H
50785 +
50786 +#include "std_ext.h"
50787 +
50788 +/***********************************************************************/
50789 +/* SW parser IP_FRAG patch */
50790 +/***********************************************************************/
50791 +
50792 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
50793 +#define SW_PRS_UDP_LITE_PATCH \
50794 +{\
50795 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
50796 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
50797 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
50798 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
50799 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
50800 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
50801 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
50802 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
50803 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
50804 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
50805 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
50806 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
50807 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
50808 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
50809 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
50810 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
50811 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
50812 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
50813 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
50814 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
50815 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
50816 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
50817 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
50818 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
50819 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
50820 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
50821 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
50822 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
50823 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
50824 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
50825 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
50826 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
50827 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
50828 + 0x00,0x01,0x1B,0xFF \
50829 +}
50830 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
50831 +
50832 +#if (DPAA_VERSION == 10)
50833 +/* Version: 106.1.9 */
50834 +#define SW_PRS_OFFLOAD_PATCH \
50835 +{ \
50836 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
50837 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
50838 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
50839 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
50840 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
50841 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
50842 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
50843 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
50844 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
50845 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
50846 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
50847 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
50848 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
50849 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
50850 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
50851 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
50852 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
50853 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
50854 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
50855 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
50856 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
50857 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
50858 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
50859 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
50860 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
50861 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
50862 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
50863 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
50864 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
50865 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
50866 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
50867 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
50868 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
50869 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
50870 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
50871 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
50872 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
50873 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
50874 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
50875 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
50876 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
50877 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
50878 +}
50879 +
50880 +#else
50881 +#define SW_PRS_OFFLOAD_PATCH \
50882 +{ \
50883 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
50884 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
50885 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
50886 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
50887 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
50888 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
50889 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
50890 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
50891 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
50892 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
50893 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
50894 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
50895 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
50896 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
50897 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
50898 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
50899 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
50900 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
50901 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
50902 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
50903 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
50904 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
50905 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
50906 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
50907 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
50908 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
50909 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
50910 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
50911 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
50912 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
50913 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
50914 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
50915 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
50916 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
50917 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
50918 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
50919 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
50920 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
50921 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
50922 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
50923 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
50924 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
50925 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
50926 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
50927 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
50928 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
50929 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
50930 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
50931 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
50932 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
50933 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
50934 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
50935 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
50936 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
50937 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
50938 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
50939 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
50940 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
50941 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
50942 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
50943 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
50944 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
50945 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
50946 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
50947 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
50948 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
50949 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
50950 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
50951 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
50952 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
50953 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
50954 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
50955 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
50956 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
50957 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
50958 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
50959 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
50960 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
50961 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
50962 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
50963 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
50964 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
50965 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
50966 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
50967 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
50968 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
50969 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
50970 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
50971 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
50972 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
50973 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
50974 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
50975 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
50976 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
50977 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
50978 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
50979 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
50980 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
50981 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
50982 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
50983 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
50984 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
50985 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
50986 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
50987 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
50988 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
50989 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
50990 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
50991 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
50992 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
50993 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
50994 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
50995 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
50996 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
50997 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
50998 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
50999 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
51000 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
51001 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
51002 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
51003 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
51004 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
51005 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
51006 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
51007 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
51008 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
51009 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
51010 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
51011 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
51012 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
51013 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
51014 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
51015 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
51016 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
51017 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
51018 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
51019 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
51020 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
51021 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
51022 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
51023 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
51024 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
51025 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
51026 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
51027 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
51028 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
51029 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
51030 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
51031 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
51032 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
51033 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
51034 +}
51035 +#endif /* (DPAA_VERSION == 10) */
51036 +
51037 +/****************************/
51038 +/* Parser defines */
51039 +/****************************/
51040 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
51041 + the end of the SW parser area */
51042 +
51043 +/* masks */
51044 +#define PRS_ERR_CAP 0x80000000
51045 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
51046 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
51047 +#define PRS_ERR_ADDR_MASK 0x000001FF
51048 +
51049 +/* others */
51050 +#define PRS_MAX_CYCLE_LIMIT 8191
51051 +#define PRS_SW_DATA 0x00000800
51052 +#define PRS_REGS_OFFSET 0x00000840
51053 +
51054 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
51055 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
51056 +
51057 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
51058 + bitMask = 0x80000000>>prsPortId
51059 +
51060 +#endif /* __FM_PRS_H */
51061 --- /dev/null
51062 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
51063 @@ -0,0 +1,984 @@
51064 +/*
51065 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51066 + *
51067 + * Redistribution and use in source and binary forms, with or without
51068 + * modification, are permitted provided that the following conditions are met:
51069 + * * Redistributions of source code must retain the above copyright
51070 + * notice, this list of conditions and the following disclaimer.
51071 + * * Redistributions in binary form must reproduce the above copyright
51072 + * notice, this list of conditions and the following disclaimer in the
51073 + * documentation and/or other materials provided with the distribution.
51074 + * * Neither the name of Freescale Semiconductor nor the
51075 + * names of its contributors may be used to endorse or promote products
51076 + * derived from this software without specific prior written permission.
51077 + *
51078 + *
51079 + * ALTERNATIVELY, this software may be distributed under the terms of the
51080 + * GNU General Public License ("GPL") as published by the Free Software
51081 + * Foundation, either version 2 of that License or (at your option) any
51082 + * later version.
51083 + *
51084 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51085 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51086 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51087 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51088 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51089 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51090 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51091 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51092 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51093 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51094 + */
51095 +
51096 +
51097 +/******************************************************************************
51098 + @File fm_replic.c
51099 +
51100 + @Description FM frame replicator
51101 +*//***************************************************************************/
51102 +#include "std_ext.h"
51103 +#include "error_ext.h"
51104 +#include "string_ext.h"
51105 +#include "debug_ext.h"
51106 +#include "fm_pcd_ext.h"
51107 +#include "fm_muram_ext.h"
51108 +#include "fm_common.h"
51109 +#include "fm_hc.h"
51110 +#include "fm_replic.h"
51111 +#include "fm_cc.h"
51112 +#include "list_ext.h"
51113 +
51114 +
51115 +/****************************************/
51116 +/* static functions */
51117 +/****************************************/
51118 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51119 + uint32_t memberIndex,
51120 + bool isAddOperation)
51121 +{
51122 + uint8_t memberPosition;
51123 + uint32_t lastMemberIndex;
51124 +
51125 + ASSERT_COND(p_ReplicGroup);
51126 +
51127 + /* the last member index is different between add and remove operation -
51128 + in case of remove - this is exactly the last member index
51129 + in case of add - this is the last member index + 1 - e.g.
51130 + if we have 4 members, the index of the actual last member is 3(because the
51131 + index starts from 0) therefore in order to add a new member as the last
51132 + member we shall use memberIndex = 4 and not 3
51133 + */
51134 + if (isAddOperation)
51135 + lastMemberIndex = p_ReplicGroup->numOfEntries;
51136 + else
51137 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
51138 +
51139 + /* last */
51140 + if (memberIndex == lastMemberIndex)
51141 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
51142 + else
51143 + {
51144 + /* first */
51145 + if (memberIndex == 0)
51146 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
51147 + else
51148 + {
51149 + /* middle */
51150 + ASSERT_COND(memberIndex < lastMemberIndex);
51151 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
51152 + }
51153 + }
51154 + return memberPosition;
51155 +}
51156 +
51157 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
51158 + t_FmPcdCcNextEngineParams *p_MemberParams)
51159 +{
51160 + t_Error err;
51161 +
51162 +
51163 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
51164 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
51165 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
51166 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
51167 +
51168 + /* check the regular parameters of the next engine */
51169 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
51170 + if (err)
51171 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
51172 +
51173 + return E_OK;
51174 +}
51175 +
51176 +static t_Error CheckParams(t_Handle h_FmPcd,
51177 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
51178 +{
51179 + int i;
51180 + t_Error err;
51181 +
51182 + /* check that max num of entries is at least 2 */
51183 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
51184 + 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));
51185 +
51186 + /* check that number of entries is greater than zero */
51187 + if (!p_ReplicGroupParam->numOfEntries)
51188 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
51189 +
51190 + /* check that max num of entries is equal or greater than number of entries */
51191 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
51192 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
51193 +
51194 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
51195 + {
51196 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
51197 + if (err)
51198 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
51199 + }
51200 + return E_OK;
51201 +}
51202 +
51203 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
51204 +{
51205 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
51206 + t_List *p_Next;
51207 +
51208 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
51209 + {
51210 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
51211 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
51212 + ASSERT_COND(p_ReplicMember);
51213 + LIST_DelAndInit(p_Next);
51214 + }
51215 + return p_ReplicMember;
51216 +}
51217 +
51218 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51219 + t_FmPcdFrmReplicMember *p_ReplicMember)
51220 +{
51221 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
51222 +}
51223 +
51224 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51225 + t_FmPcdFrmReplicMember *p_CurrentMember,
51226 + t_List *p_ListHead)
51227 +{
51228 + LIST_Add(&p_CurrentMember->node, p_ListHead);
51229 +
51230 + p_ReplicGroup->numOfEntries++;
51231 +}
51232 +
51233 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51234 + t_FmPcdFrmReplicMember *p_CurrentMember)
51235 +{
51236 + ASSERT_COND(p_ReplicGroup->numOfEntries);
51237 + LIST_DelAndInit(&p_CurrentMember->node);
51238 + p_ReplicGroup->numOfEntries--;
51239 +}
51240 +
51241 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51242 + t_AdOfTypeContLookup *p_SourceTd,
51243 + t_FmPcdFrmReplicMember *p_ReplicMember)
51244 +{
51245 + t_FmPcd *p_FmPcd;
51246 +
51247 + ASSERT_COND(p_SourceTd);
51248 + ASSERT_COND(p_ReplicMember);
51249 + ASSERT_COND(p_ReplicGroup);
51250 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51251 +
51252 + /* Link the first member in the group to the source TD */
51253 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51254 +
51255 + WRITE_UINT32(p_SourceTd->matchTblPtr,
51256 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
51257 + p_FmPcd->physicalMuramBase));
51258 +}
51259 +
51260 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51261 + t_FmPcdFrmReplicMember *p_CurrentMember,
51262 + t_FmPcdFrmReplicMember *p_NextMember)
51263 +{
51264 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
51265 + t_AdOfTypeResult *p_NextReplicAd = NULL;
51266 + t_FmPcd *p_FmPcd;
51267 + uint32_t offset = 0;
51268 +
51269 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
51270 + if (p_NextMember)
51271 + {
51272 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
51273 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51274 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
51275 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
51276 + }
51277 +
51278 + /* link the current AD to point to the AD of the next member */
51279 + WRITE_UINT32(p_CurrReplicAd->res, offset);
51280 +}
51281 +
51282 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51283 + void *p_OldDescriptor,
51284 + void *p_NewDescriptor)
51285 +{
51286 + t_Handle h_Hc;
51287 + t_Error err;
51288 + t_FmPcd *p_FmPcd;
51289 +
51290 + ASSERT_COND(p_ReplicGroup);
51291 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51292 + ASSERT_COND(p_OldDescriptor);
51293 + ASSERT_COND(p_NewDescriptor);
51294 +
51295 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51296 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
51297 + if (!h_Hc)
51298 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
51299 +
51300 + err = FmHcPcdCcDoDynamicChange(h_Hc,
51301 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
51302 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
51303 + if (err)
51304 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
51305 +
51306 + return E_OK;
51307 +}
51308 +
51309 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
51310 +{
51311 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
51312 + uint32_t tmp;
51313 +
51314 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
51315 + if (last)
51316 + /* clear the NL bit in case it's the last member in the group*/
51317 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
51318 + else
51319 + /* set the NL bit in case it's not the last member in the group */
51320 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
51321 +
51322 + /* set FR bit in the action descriptor */
51323 + tmp = GET_UINT32(p_CurrReplicAd->nia);
51324 + WRITE_UINT32(p_CurrReplicAd->nia,
51325 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
51326 +}
51327 +
51328 +static void BuildSourceTd(void *p_Ad)
51329 +{
51330 + t_AdOfTypeContLookup *p_SourceTd;
51331 +
51332 + ASSERT_COND(p_Ad);
51333 +
51334 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
51335 +
51336 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51337 +
51338 + /* initialize the source table descriptor */
51339 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
51340 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
51341 +}
51342 +
51343 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51344 + t_FmPcdFrmReplicMember *p_NextMember,
51345 + t_FmPcdFrmReplicMember *p_CurrentMember,
51346 + bool sourceDescriptor,
51347 + bool last)
51348 +{
51349 + t_FmPcd *p_FmPcd;
51350 + t_FmPcdFrmReplicMember shadowMember;
51351 + t_Error err;
51352 +
51353 + ASSERT_COND(p_ReplicGroup);
51354 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51355 +
51356 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51357 + ASSERT_COND(p_FmPcd->p_CcShadow);
51358 +
51359 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
51360 + return ERROR_CODE(E_BUSY);
51361 +
51362 + if (sourceDescriptor)
51363 + {
51364 + BuildSourceTd(p_FmPcd->p_CcShadow);
51365 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
51366 +
51367 + /* Modify the source table descriptor according to the prepared shadow descriptor */
51368 + err = ModifyDescriptor(p_ReplicGroup,
51369 + p_ReplicGroup->p_SourceTd,
51370 + p_FmPcd->p_CcShadow/* new prepared source td */);
51371 +
51372 + RELEASE_LOCK(p_FmPcd->shadowLock);
51373 + if (err)
51374 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
51375 +
51376 + }
51377 + else
51378 + {
51379 + IO2IOCpy32(p_FmPcd->p_CcShadow,
51380 + p_CurrentMember->p_MemberAd,
51381 + FM_PCD_CC_AD_ENTRY_SIZE);
51382 +
51383 + /* update the last bit in the shadow ad */
51384 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
51385 +
51386 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
51387 +
51388 + /* update the next FR member index */
51389 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
51390 +
51391 + /* Modify the next member according to the prepared shadow descriptor */
51392 + err = ModifyDescriptor(p_ReplicGroup,
51393 + p_CurrentMember->p_MemberAd,
51394 + p_FmPcd->p_CcShadow);
51395 +
51396 + RELEASE_LOCK(p_FmPcd->shadowLock);
51397 + if (err)
51398 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
51399 + }
51400 +
51401 +
51402 + return E_OK;
51403 +}
51404 +
51405 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51406 + uint16_t memberIndex)
51407 +{
51408 + int i=0;
51409 + t_List *p_Pos;
51410 + t_FmPcdFrmReplicMember *p_Member = NULL;
51411 +
51412 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
51413 + {
51414 + if (i == memberIndex)
51415 + {
51416 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
51417 + return p_Member;
51418 + }
51419 + i++;
51420 + }
51421 + return p_Member;
51422 +}
51423 +
51424 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
51425 +{
51426 + t_FmPcdFrmReplicMember *p_CurrentMember;
51427 + t_Handle h_Muram;
51428 +
51429 + ASSERT_COND(p_ReplicGroup);
51430 +
51431 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
51432 + ASSERT_COND(h_Muram);
51433 +
51434 + /* Initialize an internal structure of a member to add to the available members list */
51435 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
51436 + if (!p_CurrentMember)
51437 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
51438 +
51439 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
51440 +
51441 + /* Allocate the member AD */
51442 + p_CurrentMember->p_MemberAd =
51443 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
51444 + FM_PCD_CC_AD_ENTRY_SIZE,
51445 + FM_PCD_CC_AD_TABLE_ALIGN);
51446 + if (!p_CurrentMember->p_MemberAd)
51447 + {
51448 + XX_Free(p_CurrentMember);
51449 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
51450 + }
51451 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51452 +
51453 + /* Add the new member to the available members list */
51454 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
51455 +
51456 + return E_OK;
51457 +}
51458 +
51459 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51460 + t_FmPcdCcNextEngineParams *p_MemberParams,
51461 + bool last)
51462 +{
51463 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
51464 +
51465 + ASSERT_COND(p_ReplicGroup);
51466 +
51467 + /* Get an available member from the internal members list */
51468 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
51469 + if (!p_CurrentMember)
51470 + {
51471 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
51472 + return NULL;
51473 + }
51474 + p_CurrentMember->h_Manip = NULL;
51475 +
51476 + /* clear the Ad of the new member */
51477 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51478 +
51479 + INIT_LIST(&p_CurrentMember->node);
51480 +
51481 + /* Initialize the Ad of the member */
51482 + NextStepAd(p_CurrentMember->p_MemberAd,
51483 + NULL,
51484 + p_MemberParams,
51485 + p_ReplicGroup->h_FmPcd);
51486 +
51487 + /* save Manip handle (for free needs) */
51488 + if (p_MemberParams->h_Manip)
51489 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
51490 +
51491 + /* Initialize the relevant frame replicator fields in the AD */
51492 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
51493 +
51494 + return p_CurrentMember;
51495 +}
51496 +
51497 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51498 + t_FmPcdFrmReplicMember *p_Member)
51499 +{
51500 + /* Note: Can't free the member AD just returns the member to the available
51501 + member list - therefore only memset the AD */
51502 +
51503 + /* zero the AD */
51504 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51505 +
51506 +
51507 + /* return the member to the available members list */
51508 + PutAvailableMember(p_ReplicGroup, p_Member);
51509 +}
51510 +
51511 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51512 + uint16_t memberIndex)
51513 +{
51514 + t_FmPcd *p_FmPcd = NULL;
51515 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
51516 + t_Error err;
51517 + uint8_t memberPosition;
51518 +
51519 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51520 + ASSERT_COND(p_FmPcd);
51521 + UNUSED(p_FmPcd);
51522 +
51523 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
51524 + ASSERT_COND(p_CurrentMember);
51525 +
51526 + /* determine the member position in the group */
51527 + memberPosition = GetMemberPosition(p_ReplicGroup,
51528 + memberIndex,
51529 + FALSE/*remove operation*/);
51530 +
51531 + switch (memberPosition)
51532 + {
51533 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
51534 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
51535 + ASSERT_COND(p_NextMember);
51536 +
51537 + /* update the source td itself by using a host command */
51538 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
51539 + p_NextMember,
51540 + NULL,
51541 + TRUE/*sourceDescriptor*/,
51542 + FALSE/*last*/);
51543 + break;
51544 +
51545 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
51546 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
51547 + ASSERT_COND(p_PreviousMember);
51548 +
51549 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
51550 + ASSERT_COND(p_NextMember);
51551 +
51552 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
51553 + p_NextMember,
51554 + p_PreviousMember,
51555 + FALSE/*sourceDescriptor*/,
51556 + FALSE/*last*/);
51557 +
51558 + break;
51559 +
51560 + case FRM_REPLIC_LAST_MEMBER_INDEX:
51561 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
51562 + ASSERT_COND(p_PreviousMember);
51563 +
51564 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
51565 + NULL,
51566 + p_PreviousMember,
51567 + FALSE/*sourceDescriptor*/,
51568 + TRUE/*last*/);
51569 + break;
51570 +
51571 + default:
51572 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
51573 + }
51574 +
51575 + if (err)
51576 + RETURN_ERROR(MAJOR, err, NO_MSG);
51577 +
51578 + if (p_CurrentMember->h_Manip)
51579 + {
51580 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
51581 + p_CurrentMember->h_Manip = NULL;
51582 + }
51583 +
51584 + /* remove the member from the driver internal members list */
51585 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
51586 +
51587 + /* return the member to the available members list */
51588 + FreeMember(p_ReplicGroup, p_CurrentMember);
51589 +
51590 + return E_OK;
51591 +}
51592 +
51593 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
51594 +{
51595 + int i, j;
51596 + t_Handle h_Muram;
51597 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
51598 +
51599 + if (p_ReplicGroup)
51600 + {
51601 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51602 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
51603 + ASSERT_COND(h_Muram);
51604 +
51605 + /* free the source table descriptor */
51606 + if (p_ReplicGroup->p_SourceTd)
51607 + {
51608 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
51609 + p_ReplicGroup->p_SourceTd = NULL;
51610 + }
51611 +
51612 + /* Remove all members from the members linked list (hw and sw) and
51613 + return the members to the available members list */
51614 + if (p_ReplicGroup->numOfEntries)
51615 + {
51616 + j = p_ReplicGroup->numOfEntries-1;
51617 +
51618 + /* manually removal of the member because there are no owners of
51619 + this group */
51620 + for (i=j; i>=0; i--)
51621 + {
51622 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
51623 + ASSERT_COND(p_CurrentMember);
51624 +
51625 + if (p_CurrentMember->h_Manip)
51626 + {
51627 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
51628 + p_CurrentMember->h_Manip = NULL;
51629 + }
51630 +
51631 + /* remove the member from the internal driver members list */
51632 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
51633 +
51634 + /* return the member to the available members list */
51635 + FreeMember(p_ReplicGroup, p_CurrentMember);
51636 + }
51637 + }
51638 +
51639 + /* Free members AD */
51640 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
51641 + {
51642 + p_Member = GetAvailableMember(p_ReplicGroup);
51643 + ASSERT_COND(p_Member);
51644 + if (p_Member->p_MemberAd)
51645 + {
51646 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
51647 + p_Member->p_MemberAd = NULL;
51648 + }
51649 + XX_Free(p_Member);
51650 + }
51651 +
51652 + /* release the group lock */
51653 + if (p_ReplicGroup->p_Lock)
51654 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
51655 +
51656 + /* free the replicator group */
51657 + XX_Free(p_ReplicGroup);
51658 + }
51659 +}
51660 +
51661 +
51662 +/*****************************************************************************/
51663 +/* Inter-module API routines */
51664 +/*****************************************************************************/
51665 +
51666 +/* NOTE: the inter-module routines are locked by cc in case of using them */
51667 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
51668 +{
51669 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
51670 + ASSERT_COND(p_ReplicGroup);
51671 +
51672 + return (p_ReplicGroup->p_SourceTd);
51673 +}
51674 +
51675 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
51676 + void *p_Ad,
51677 + t_Handle *h_AdNew)
51678 +{
51679 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
51680 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
51681 + t_FmPcd *p_FmPcd;
51682 +
51683 + ASSERT_COND(p_ReplicGroup);
51684 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51685 +
51686 + /* build a bypass ad */
51687 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
51688 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
51689 +
51690 + *h_AdNew = NULL;
51691 +}
51692 +
51693 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
51694 + bool add)
51695 +{
51696 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
51697 + ASSERT_COND(p_ReplicGroup);
51698 +
51699 + /* update the group owner counter */
51700 + if (add)
51701 + p_ReplicGroup->owners++;
51702 + else
51703 + {
51704 + ASSERT_COND(p_ReplicGroup->owners);
51705 + p_ReplicGroup->owners--;
51706 + }
51707 +}
51708 +
51709 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
51710 +{
51711 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
51712 +
51713 + ASSERT_COND(h_ReplicGroup);
51714 +
51715 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
51716 + return E_OK;
51717 +
51718 + return ERROR_CODE(E_BUSY);
51719 +}
51720 +
51721 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
51722 +{
51723 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
51724 +
51725 + ASSERT_COND(h_ReplicGroup);
51726 +
51727 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
51728 +}
51729 +/*********************** End of inter-module routines ************************/
51730 +
51731 +
51732 +/****************************************/
51733 +/* API Init unit functions */
51734 +/****************************************/
51735 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
51736 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
51737 +{
51738 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
51739 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
51740 + int i;
51741 + t_Error err;
51742 + bool last = FALSE;
51743 + t_Handle h_Muram;
51744 +
51745 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
51746 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
51747 +
51748 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
51749 + {
51750 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
51751 + return NULL;
51752 + }
51753 +
51754 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
51755 + if (err)
51756 + {
51757 + REPORT_ERROR(MAJOR, err, (NO_MSG));
51758 + return NULL;
51759 + }
51760 +
51761 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
51762 + if (!p_ReplicGroup)
51763 + {
51764 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
51765 + return NULL;
51766 + }
51767 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
51768 +
51769 + /* initialize lists for internal driver use */
51770 + INIT_LIST(&p_ReplicGroup->availableMembersList);
51771 + INIT_LIST(&p_ReplicGroup->membersList);
51772 +
51773 + p_ReplicGroup->h_FmPcd = h_FmPcd;
51774 +
51775 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
51776 + ASSERT_COND(h_Muram);
51777 +
51778 + /* initialize the group lock */
51779 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
51780 + if (!p_ReplicGroup->p_Lock)
51781 + {
51782 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
51783 + DeleteGroup(p_ReplicGroup);
51784 + return NULL;
51785 + }
51786 +
51787 + /* Allocate the frame replicator source table descriptor */
51788 + p_ReplicGroup->p_SourceTd =
51789 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
51790 + FM_PCD_CC_AD_ENTRY_SIZE,
51791 + FM_PCD_CC_AD_TABLE_ALIGN);
51792 + if (!p_ReplicGroup->p_SourceTd)
51793 + {
51794 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
51795 + DeleteGroup(p_ReplicGroup);
51796 + return NULL;
51797 + }
51798 +
51799 + /* update the shadow size - required for the host commands */
51800 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
51801 + FM_PCD_CC_AD_ENTRY_SIZE,
51802 + FM_PCD_CC_AD_TABLE_ALIGN);
51803 + if (err)
51804 + {
51805 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
51806 + DeleteGroup(p_ReplicGroup);
51807 + return NULL;
51808 + }
51809 +
51810 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
51811 +
51812 + /* Allocate the maximal number of members ADs and Statistics AD for the group
51813 + It prevents allocation of Muram in run-time */
51814 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
51815 + {
51816 + err = AllocMember(p_ReplicGroup);
51817 + if (err)
51818 + {
51819 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
51820 + DeleteGroup(p_ReplicGroup);
51821 + return NULL;
51822 + }
51823 + }
51824 +
51825 + /* Initialize the members linked lists:
51826 + (hw - the one that is used by the FMan controller and
51827 + sw - the one that is managed by the driver internally) */
51828 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
51829 + {
51830 + /* check if this is the last member in the group */
51831 + if (i == (p_ReplicGroupParam->numOfEntries-1))
51832 + last = TRUE;
51833 + else
51834 + last = FALSE;
51835 +
51836 + /* Initialize a new member */
51837 + p_CurrentMember = InitMember(p_ReplicGroup,
51838 + &(p_ReplicGroupParam->nextEngineParams[i]),
51839 + last);
51840 + if (!p_CurrentMember)
51841 + {
51842 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
51843 + DeleteGroup(p_ReplicGroup);
51844 + return NULL;
51845 + }
51846 +
51847 + /* Build the members group - link two consecutive members in the hw linked list */
51848 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
51849 +
51850 + /* update the driver internal members list to be compatible to the hw members linked list */
51851 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
51852 +
51853 + p_NextMember = p_CurrentMember;
51854 + }
51855 +
51856 + /* initialize the source table descriptor */
51857 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
51858 +
51859 + /* link the source table descriptor to point to the first member in the group */
51860 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
51861 +
51862 + return p_ReplicGroup;
51863 +}
51864 +
51865 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
51866 +{
51867 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
51868 +
51869 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
51870 +
51871 + if (p_ReplicGroup->owners)
51872 + RETURN_ERROR(MAJOR,
51873 + E_INVALID_STATE,
51874 + ("the group has owners and can't be deleted"));
51875 +
51876 + DeleteGroup(p_ReplicGroup);
51877 +
51878 + return E_OK;
51879 +}
51880 +
51881 +
51882 +/*****************************************************************************/
51883 +/* API Run-time Frame replicator Control unit functions */
51884 +/*****************************************************************************/
51885 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
51886 + uint16_t memberIndex,
51887 + t_FmPcdCcNextEngineParams *p_MemberParams)
51888 +{
51889 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
51890 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
51891 + t_Error err;
51892 + uint8_t memberPosition;
51893 +
51894 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
51895 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
51896 +
51897 + /* group lock */
51898 + err = FrmReplicGroupTryLock(p_ReplicGroup);
51899 + if (GET_ERROR_TYPE(err) == E_BUSY)
51900 + return ERROR_CODE(E_BUSY);
51901 +
51902 + if (memberIndex > p_ReplicGroup->numOfEntries)
51903 + {
51904 + /* unlock */
51905 + FrmReplicGroupUnlock(p_ReplicGroup);
51906 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
51907 + ("memberIndex is greater than the members in the list"));
51908 + }
51909 +
51910 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
51911 + {
51912 + /* unlock */
51913 + FrmReplicGroupUnlock(p_ReplicGroup);
51914 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
51915 + }
51916 +
51917 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
51918 + {
51919 + /* unlock */
51920 + FrmReplicGroupUnlock(p_ReplicGroup);
51921 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51922 + ("numOfEntries with new entry can not be larger than %d\n",
51923 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
51924 + }
51925 +
51926 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
51927 + if (err)
51928 + {
51929 + /* unlock */
51930 + FrmReplicGroupUnlock(p_ReplicGroup);
51931 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
51932 + }
51933 + /* determine the member position in the group */
51934 + memberPosition = GetMemberPosition(p_ReplicGroup,
51935 + memberIndex,
51936 + TRUE/* add operation */);
51937 +
51938 + /* Initialize a new member */
51939 + p_NewMember = InitMember(p_ReplicGroup,
51940 + p_MemberParams,
51941 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
51942 + if (!p_NewMember)
51943 + {
51944 + /* unlock */
51945 + FrmReplicGroupUnlock(p_ReplicGroup);
51946 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
51947 + }
51948 +
51949 + switch (memberPosition)
51950 + {
51951 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
51952 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
51953 + ASSERT_COND(p_CurrentMember);
51954 +
51955 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
51956 +
51957 + /* update the internal group source TD */
51958 + LinkSourceToMember(p_ReplicGroup,
51959 + p_ReplicGroup->p_SourceTd,
51960 + p_NewMember);
51961 +
51962 + /* add member to the internal sw member list */
51963 + AddMemberToList(p_ReplicGroup,
51964 + p_NewMember,
51965 + &p_ReplicGroup->membersList);
51966 + break;
51967 +
51968 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
51969 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
51970 + ASSERT_COND(p_CurrentMember);
51971 +
51972 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
51973 + ASSERT_COND(p_PreviousMember);
51974 +
51975 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
51976 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
51977 +
51978 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
51979 + break;
51980 +
51981 + case FRM_REPLIC_LAST_MEMBER_INDEX:
51982 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
51983 + ASSERT_COND(p_PreviousMember);
51984 +
51985 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
51986 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
51987 +
51988 + /* add the new member to the internal sw member list */
51989 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
51990 + break;
51991 +
51992 + default:
51993 + /* unlock */
51994 + FrmReplicGroupUnlock(p_ReplicGroup);
51995 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
51996 +
51997 + }
51998 +
51999 + /* unlock */
52000 + FrmReplicGroupUnlock(p_ReplicGroup);
52001 +
52002 + return E_OK;
52003 +}
52004 +
52005 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
52006 + uint16_t memberIndex)
52007 +{
52008 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
52009 + t_Error err;
52010 +
52011 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
52012 +
52013 + /* lock */
52014 + err = FrmReplicGroupTryLock(p_ReplicGroup);
52015 + if (GET_ERROR_TYPE(err) == E_BUSY)
52016 + return ERROR_CODE(E_BUSY);
52017 +
52018 + if (memberIndex >= p_ReplicGroup->numOfEntries)
52019 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
52020 +
52021 + /* Design decision: group must contain at least one member
52022 + No possibility to remove the last member from the group */
52023 + if (p_ReplicGroup->numOfEntries == 1)
52024 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
52025 +
52026 + err = RemoveMember(p_ReplicGroup, memberIndex);
52027 +
52028 + /* unlock */
52029 + FrmReplicGroupUnlock(p_ReplicGroup);
52030 +
52031 + switch (GET_ERROR_TYPE(err))
52032 + {
52033 + case E_OK:
52034 + return E_OK;
52035 +
52036 + case E_BUSY:
52037 + DBG(TRACE, ("E_BUSY error"));
52038 + return ERROR_CODE(E_BUSY);
52039 +
52040 + default:
52041 + RETURN_ERROR(MAJOR, err, NO_MSG);
52042 + }
52043 +}
52044 +
52045 +/*********************** End of API routines ************************/
52046 +
52047 +
52048 --- /dev/null
52049 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
52050 @@ -0,0 +1,101 @@
52051 +/*
52052 + * Copyright 2008-2012 Freescale Semiconductor Inc.
52053 + *
52054 + * Redistribution and use in source and binary forms, with or without
52055 + * modification, are permitted provided that the following conditions are met:
52056 + * * Redistributions of source code must retain the above copyright
52057 + * notice, this list of conditions and the following disclaimer.
52058 + * * Redistributions in binary form must reproduce the above copyright
52059 + * notice, this list of conditions and the following disclaimer in the
52060 + * documentation and/or other materials provided with the distribution.
52061 + * * Neither the name of Freescale Semiconductor nor the
52062 + * names of its contributors may be used to endorse or promote products
52063 + * derived from this software without specific prior written permission.
52064 + *
52065 + *
52066 + * ALTERNATIVELY, this software may be distributed under the terms of the
52067 + * GNU General Public License ("GPL") as published by the Free Software
52068 + * Foundation, either version 2 of that License or (at your option) any
52069 + * later version.
52070 + *
52071 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
52072 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52073 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52074 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
52075 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52076 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52077 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52078 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52079 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52080 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52081 + */
52082 +
52083 +
52084 +/******************************************************************************
52085 + @File fm_replic.h
52086 +
52087 + @Description FM frame replicator
52088 +*//***************************************************************************/
52089 +#ifndef __FM_REPLIC_H
52090 +#define __FM_REPLIC_H
52091 +
52092 +#include "std_ext.h"
52093 +#include "error_ext.h"
52094 +
52095 +
52096 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
52097 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
52098 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
52099 +#define FRM_REPLIC_FR_BIT 0x08000000
52100 +#define FRM_REPLIC_NL_BIT 0x10000000
52101 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
52102 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
52103 +
52104 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
52105 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
52106 +
52107 +#define SOURCE_TD_ITSELF_OPTION 0x01
52108 +#define SOURCE_TD_COPY_OPTION 0x02
52109 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
52110 +#define SOURCE_TD_NONE 0x04
52111 +
52112 +/*typedef enum e_SourceTdOption
52113 +{
52114 + e_SOURCE_TD_NONE = 0,
52115 + e_SOURCE_TD_ITSELF_OPTION = 1,
52116 + e_SOURCE_TD_COPY_OPTION = 2,
52117 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
52118 +} e_SourceTdOption;
52119 +*/
52120 +
52121 +typedef struct
52122 +{
52123 + volatile uint32_t type;
52124 + volatile uint32_t frGroupPointer;
52125 + volatile uint32_t operationCode;
52126 + volatile uint32_t reserved;
52127 +} t_FrmReplicGroupSourceAd;
52128 +
52129 +typedef struct t_FmPcdFrmReplicMember
52130 +{
52131 + void *p_MemberAd; /**< pointer to the member AD */
52132 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
52133 + t_Handle h_Manip; /**< manip handle - need for free routines */
52134 + t_List node;
52135 +} t_FmPcdFrmReplicMember;
52136 +
52137 +typedef struct t_FmPcdFrmReplicGroup
52138 +{
52139 + t_Handle h_FmPcd;
52140 +
52141 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
52142 + uint8_t numOfEntries; /**< actual number of members in the group */
52143 + uint16_t owners; /**< how many keys share this frame replicator group */
52144 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
52145 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
52146 + t_List availableMembersList;/**< list of all the available members in the group */
52147 + t_FmPcdLock *p_Lock;
52148 +} t_FmPcdFrmReplicGroup;
52149 +
52150 +
52151 +#endif /* __FM_REPLIC_H */
52152 --- /dev/null
52153 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
52154 @@ -0,0 +1,890 @@
52155 +/*
52156 + * Copyright 2008-2012 Freescale Semiconductor Inc.
52157 + *
52158 + * Redistribution and use in source and binary forms, with or without
52159 + * modification, are permitted provided that the following conditions are met:
52160 + * * Redistributions of source code must retain the above copyright
52161 + * notice, this list of conditions and the following disclaimer.
52162 + * * Redistributions in binary form must reproduce the above copyright
52163 + * notice, this list of conditions and the following disclaimer in the
52164 + * documentation and/or other materials provided with the distribution.
52165 + * * Neither the name of Freescale Semiconductor nor the
52166 + * names of its contributors may be used to endorse or promote products
52167 + * derived from this software without specific prior written permission.
52168 + *
52169 + *
52170 + * ALTERNATIVELY, this software may be distributed under the terms of the
52171 + * GNU General Public License ("GPL") as published by the Free Software
52172 + * Foundation, either version 2 of that License or (at your option) any
52173 + * later version.
52174 + *
52175 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
52176 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52177 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52178 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
52179 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52180 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52181 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52182 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52183 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52184 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52185 + */
52186 +
52187 +#include "std_ext.h"
52188 +#include "error_ext.h"
52189 +#include "fsl_fman_kg.h"
52190 +
52191 +/****************************************/
52192 +/* static functions */
52193 +/****************************************/
52194 +
52195 +
52196 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
52197 +{
52198 + uint32_t rw;
52199 +
52200 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
52201 +
52202 + return (uint32_t)(FM_KG_KGAR_GO |
52203 + rw |
52204 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
52205 + hwport_id |
52206 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
52207 +}
52208 +
52209 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
52210 +{
52211 + uint32_t ar;
52212 +
52213 + fman_kg_write_sp(regs, 0xffffffff, 0);
52214 +
52215 + ar = build_ar_bind_scheme(hwport_id, TRUE);
52216 + fman_kg_write_ar_wait(regs, ar);
52217 +}
52218 +
52219 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
52220 +{
52221 + uint32_t rw;
52222 +
52223 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
52224 +
52225 + return (uint32_t)(FM_KG_KGAR_GO |
52226 + rw |
52227 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
52228 + hwport_id |
52229 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
52230 +}
52231 +
52232 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
52233 +{
52234 + uint32_t ar;
52235 +
52236 + fman_kg_write_cpp(regs, 0);
52237 +
52238 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
52239 + fman_kg_write_ar_wait(regs, ar);
52240 +}
52241 +
52242 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
52243 + bool no_validation,
52244 + uint8_t *offset)
52245 +{
52246 + int code;
52247 +
52248 + switch (src) {
52249 + case E_FMAN_KG_GEN_EXTRACT_ETH:
52250 + code = no_validation ? 0x73 : 0x3;
52251 + break;
52252 +
52253 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
52254 + code = no_validation ? 0x77 : 0x7;
52255 + break;
52256 +
52257 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
52258 + code = no_validation ? 0x74 : 0x4;
52259 + break;
52260 +
52261 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
52262 + code = no_validation ? 0x75 : 0x5;
52263 + break;
52264 +
52265 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
52266 + code = no_validation ? 0x76 : 0x6;
52267 + break;
52268 +
52269 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
52270 + code = no_validation ? 0x78 : 0x8;
52271 + break;
52272 +
52273 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
52274 + code = no_validation ? 0x79 : 0x9;
52275 + break;
52276 +
52277 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
52278 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
52279 + break;
52280 +
52281 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
52282 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
52283 + break;
52284 +
52285 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
52286 + code = no_validation ? 0x7a : 0xa;
52287 + break;
52288 +
52289 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
52290 + code = no_validation ? 0x7b : 0xb;
52291 + break;
52292 +
52293 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
52294 + code = no_validation ? 0x7b : 0x1b;
52295 + break;
52296 +
52297 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
52298 + code = no_validation ? 0x7c : 0xc;
52299 + break;
52300 +
52301 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
52302 + code = no_validation ? 0x7c : 0x1c;
52303 + break;
52304 +
52305 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
52306 + code = no_validation ? 0x7c : 0x2c;
52307 + break;
52308 +
52309 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
52310 + code = no_validation ? 0x72 : 0x2;
52311 + break;
52312 +
52313 + case E_FMAN_KG_GEN_EXTRACT_GRE:
52314 + code = no_validation ? 0x7d : 0xd;
52315 + break;
52316 +
52317 + case E_FMAN_KG_GEN_EXTRACT_TCP:
52318 + code = no_validation ? 0x7e : 0xe;
52319 + break;
52320 +
52321 + case E_FMAN_KG_GEN_EXTRACT_UDP:
52322 + code = no_validation ? 0x7e : 0x1e;
52323 + break;
52324 +
52325 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
52326 + code = no_validation ? 0x7e : 0x3e;
52327 + break;
52328 +
52329 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
52330 + code = no_validation ? 0x7e : 0x4e;
52331 + break;
52332 +
52333 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
52334 + code = no_validation ? 0x7e : 0x2e;
52335 + break;
52336 +
52337 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
52338 + code = no_validation ? 0x7e : 0x6e;
52339 + break;
52340 +
52341 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
52342 + code = 0x70;
52343 + break;
52344 +
52345 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
52346 + code = 0x71;
52347 + break;
52348 +
52349 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
52350 + code = 0x10;
52351 + break;
52352 +
52353 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
52354 + code = 0x40;
52355 + break;
52356 +
52357 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
52358 + code = 0x20;
52359 + break;
52360 +
52361 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
52362 + code = 0x7f;
52363 + break;
52364 +
52365 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
52366 + code = 0x20;
52367 + *offset += 0x20;
52368 + break;
52369 +
52370 + default:
52371 + code = FM_KG_SCH_GEN_HT_INVALID;
52372 + }
52373 +
52374 + return (uint8_t)code;
52375 +}
52376 +
52377 +static uint32_t build_ar_scheme(uint8_t scheme,
52378 + uint8_t hwport_id,
52379 + bool update_counter,
52380 + bool write)
52381 +{
52382 + uint32_t rw;
52383 +
52384 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
52385 +
52386 + return (uint32_t)(FM_KG_KGAR_GO |
52387 + rw |
52388 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
52389 + hwport_id |
52390 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
52391 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
52392 +}
52393 +
52394 +static uint32_t build_ar_cls_plan(uint8_t grp,
52395 + uint8_t entries_mask,
52396 + uint8_t hwport_id,
52397 + bool write)
52398 +{
52399 + uint32_t rw;
52400 +
52401 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
52402 +
52403 + return (uint32_t)(FM_KG_KGAR_GO |
52404 + rw |
52405 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
52406 + hwport_id |
52407 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
52408 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
52409 +}
52410 +
52411 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
52412 +{
52413 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
52414 + /* Wait for GO to be idle and read error */
52415 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
52416 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
52417 + return -EINVAL;
52418 + return 0;
52419 +}
52420 +
52421 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
52422 +{
52423 +
52424 + struct fman_kg_pe_regs *kgpe_regs;
52425 + uint32_t tmp;
52426 +
52427 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
52428 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
52429 +
52430 + if (add)
52431 + tmp |= sp;
52432 + else /* clear */
52433 + tmp &= ~sp;
52434 +
52435 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
52436 +
52437 +}
52438 +
52439 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
52440 +{
52441 + struct fman_kg_pe_regs *kgpe_regs;
52442 +
52443 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
52444 +
52445 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
52446 +}
52447 +
52448 +void fman_kg_get_event(struct fman_kg_regs *regs,
52449 + uint32_t *event,
52450 + uint32_t *scheme_idx)
52451 +{
52452 + uint32_t mask, force;
52453 +
52454 + *event = ioread32be(&regs->fmkg_eer);
52455 + mask = ioread32be(&regs->fmkg_eeer);
52456 + *scheme_idx = ioread32be(&regs->fmkg_seer);
52457 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
52458 +
52459 + *event &= mask;
52460 +
52461 + /* clear the forced events */
52462 + force = ioread32be(&regs->fmkg_feer);
52463 + if (force & *event)
52464 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
52465 +
52466 + iowrite32be(*event, &regs->fmkg_eer);
52467 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
52468 +}
52469 +
52470 +
52471 +void fman_kg_init(struct fman_kg_regs *regs,
52472 + uint32_t exceptions,
52473 + uint32_t dflt_nia)
52474 +{
52475 + uint32_t tmp;
52476 + int i;
52477 +
52478 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
52479 + &regs->fmkg_eer);
52480 +
52481 + tmp = 0;
52482 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
52483 + tmp |= FM_EX_KG_DOUBLE_ECC;
52484 +
52485 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
52486 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
52487 +
52488 + iowrite32be(tmp, &regs->fmkg_eeer);
52489 + iowrite32be(0, &regs->fmkg_fdor);
52490 + iowrite32be(0, &regs->fmkg_gdv0r);
52491 + iowrite32be(0, &regs->fmkg_gdv1r);
52492 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
52493 +
52494 + /* Clear binding between ports to schemes and classification plans
52495 + * so that all ports are not bound to any scheme/classification plan */
52496 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
52497 + clear_pe_all_scheme(regs, (uint8_t)i);
52498 + clear_pe_all_cls_plan(regs, (uint8_t)i);
52499 + }
52500 +}
52501 +
52502 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
52503 +{
52504 + /* enable and enable all scheme interrupts */
52505 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
52506 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
52507 +}
52508 +
52509 +void fman_kg_enable(struct fman_kg_regs *regs)
52510 +{
52511 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
52512 + &regs->fmkg_gcr);
52513 +}
52514 +
52515 +void fman_kg_disable(struct fman_kg_regs *regs)
52516 +{
52517 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
52518 + &regs->fmkg_gcr);
52519 +}
52520 +
52521 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
52522 +{
52523 + iowrite32be(offset, &regs->fmkg_fdor);
52524 +}
52525 +
52526 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
52527 + uint8_t def_id,
52528 + uint32_t val)
52529 +{
52530 + if(def_id == 0)
52531 + iowrite32be(val, &regs->fmkg_gdv0r);
52532 + else
52533 + iowrite32be(val, &regs->fmkg_gdv1r);
52534 +}
52535 +
52536 +
52537 +void fman_kg_set_exception(struct fman_kg_regs *regs,
52538 + uint32_t exception,
52539 + bool enable)
52540 +{
52541 + uint32_t tmp;
52542 +
52543 + tmp = ioread32be(&regs->fmkg_eeer);
52544 +
52545 + if (enable) {
52546 + tmp |= exception;
52547 + } else {
52548 + tmp &= ~exception;
52549 + }
52550 +
52551 + iowrite32be(tmp, &regs->fmkg_eeer);
52552 +}
52553 +
52554 +void fman_kg_get_exception(struct fman_kg_regs *regs,
52555 + uint32_t *events,
52556 + uint32_t *scheme_ids,
52557 + bool clear)
52558 +{
52559 + uint32_t mask;
52560 +
52561 + *events = ioread32be(&regs->fmkg_eer);
52562 + mask = ioread32be(&regs->fmkg_eeer);
52563 + *events &= mask;
52564 +
52565 + *scheme_ids = 0;
52566 +
52567 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
52568 + *scheme_ids = ioread32be(&regs->fmkg_seer);
52569 + mask = ioread32be(&regs->fmkg_seeer);
52570 + *scheme_ids &= mask;
52571 + }
52572 +
52573 + if (clear) {
52574 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
52575 + iowrite32be(*events, &regs->fmkg_eer);
52576 + }
52577 +}
52578 +
52579 +void fman_kg_get_capture(struct fman_kg_regs *regs,
52580 + struct fman_kg_ex_ecc_attr *ecc_attr,
52581 + bool clear)
52582 +{
52583 + uint32_t tmp;
52584 +
52585 + tmp = ioread32be(&regs->fmkg_serc);
52586 +
52587 + if (tmp & KG_FMKG_SERC_CAP) {
52588 + /* Captured data is valid */
52589 + ecc_attr->valid = TRUE;
52590 + ecc_attr->double_ecc =
52591 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
52592 + ecc_attr->single_ecc_count =
52593 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
52594 + KG_FMKG_SERC_CNT_SHIFT);
52595 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
52596 +
52597 + if (clear)
52598 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
52599 + } else {
52600 + /* No ECC error is captured */
52601 + ecc_attr->valid = FALSE;
52602 + }
52603 +}
52604 +
52605 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
52606 + struct fman_kg_scheme_regs *scheme_regs)
52607 +{
52608 + struct fman_kg_extract_params *extract_params;
52609 + struct fman_kg_gen_extract_params *gen_params;
52610 + uint32_t tmp_reg, i, select, mask, fqb;
52611 + uint8_t offset, shift, ht;
52612 +
52613 + /* Zero out all registers so no need to care about unused ones */
52614 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
52615 +
52616 + /* Mode register */
52617 + tmp_reg = fm_kg_build_nia(params->next_engine,
52618 + params->next_engine_action);
52619 + if (tmp_reg == KG_NIA_INVALID) {
52620 + return -EINVAL;
52621 + }
52622 +
52623 + if (params->next_engine == E_FMAN_PCD_PLCR) {
52624 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
52625 + }
52626 + else if (params->next_engine == E_FMAN_PCD_CC) {
52627 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
52628 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
52629 + }
52630 +
52631 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
52632 + scheme_regs->kgse_mode = tmp_reg;
52633 +
52634 + /* Match vector */
52635 + scheme_regs->kgse_mv = params->match_vector;
52636 +
52637 + extract_params = &params->extract_params;
52638 +
52639 + /* Scheme default values registers */
52640 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
52641 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
52642 +
52643 + /* Extract Known Fields Command register */
52644 + scheme_regs->kgse_ekfc = extract_params->known_fields;
52645 +
52646 + /* Entry Extract Known Default Value register */
52647 + tmp_reg = 0;
52648 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
52649 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
52650 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
52651 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
52652 + tmp_reg |= extract_params->known_fields_def.etype <<
52653 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
52654 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
52655 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
52656 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
52657 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
52658 + tmp_reg |= extract_params->known_fields_def.mpls <<
52659 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
52660 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
52661 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
52662 + tmp_reg |= extract_params->known_fields_def.ptype <<
52663 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
52664 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
52665 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
52666 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
52667 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
52668 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
52669 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
52670 + tmp_reg |= extract_params->known_fields_def.l4_port <<
52671 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
52672 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
52673 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
52674 +
52675 + scheme_regs->kgse_ekdv = tmp_reg;
52676 +
52677 + /* Generic extract registers */
52678 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
52679 + return -EINVAL;
52680 + }
52681 +
52682 + for (i = 0; i < extract_params->gen_extract_num; i++) {
52683 + gen_params = extract_params->gen_extract + i;
52684 +
52685 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
52686 + tmp_reg |= (uint32_t)gen_params->def_val <<
52687 + FMAN_KG_SCH_GEN_DEF_SHIFT;
52688 +
52689 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
52690 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
52691 + (gen_params->extract == 0)) {
52692 + return -EINVAL;
52693 + }
52694 + } else {
52695 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
52696 + }
52697 +
52698 + tmp_reg |= (uint32_t)gen_params->extract <<
52699 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
52700 + tmp_reg |= (uint32_t)gen_params->mask <<
52701 + FMAN_KG_SCH_GEN_MASK_SHIFT;
52702 +
52703 + offset = gen_params->offset;
52704 + ht = get_gen_ht_code(gen_params->src,
52705 + gen_params->no_validation,
52706 + &offset);
52707 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
52708 + tmp_reg |= offset;
52709 +
52710 + scheme_regs->kgse_gec[i] = tmp_reg;
52711 + }
52712 +
52713 + /* Masks registers */
52714 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
52715 + return -EINVAL;
52716 + }
52717 +
52718 + select = 0;
52719 + mask = 0;
52720 + fqb = 0;
52721 + for (i = 0; i < extract_params->masks_num; i++) {
52722 + /* MCSx fields */
52723 + KG_GET_MASK_SEL_SHIFT(shift, i);
52724 + if (extract_params->masks[i].is_known) {
52725 + /* Mask known field */
52726 + select |= extract_params->masks[i].field_or_gen_idx <<
52727 + shift;
52728 + } else {
52729 + /* Mask generic extract */
52730 + select |= (extract_params->masks[i].field_or_gen_idx +
52731 + FM_KG_MASK_SEL_GEN_BASE) << shift;
52732 + }
52733 +
52734 + /* MOx fields - spread between se_bmch and se_fqb registers */
52735 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
52736 + if (i < 2) {
52737 + select |= (uint32_t)extract_params->masks[i].offset <<
52738 + shift;
52739 + } else {
52740 + fqb |= (uint32_t)extract_params->masks[i].offset <<
52741 + shift;
52742 + }
52743 +
52744 + /* BMx fields */
52745 + KG_GET_MASK_SHIFT(shift, i);
52746 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
52747 + }
52748 +
52749 + /* Finish with rest of BMx fileds -
52750 + * don't mask bits for unused masks by setting
52751 + * corresponding BMx field = 0xFF */
52752 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
52753 + KG_GET_MASK_SHIFT(shift, i);
52754 + mask |= 0xFF << shift;
52755 + }
52756 +
52757 + scheme_regs->kgse_bmch = select;
52758 + scheme_regs->kgse_bmcl = mask;
52759 +
52760 + /* Finish with FQB register initialization.
52761 + * Check fqid is 24-bit value. */
52762 + if (params->base_fqid & ~0x00FFFFFF) {
52763 + return -EINVAL;
52764 + }
52765 +
52766 + fqb |= params->base_fqid;
52767 + scheme_regs->kgse_fqb = fqb;
52768 +
52769 + /* Hash Configuration register */
52770 + tmp_reg = 0;
52771 + if (params->hash_params.use_hash) {
52772 + /* Check hash mask is 24-bit value */
52773 + if (params->hash_params.mask & ~0x00FFFFFF) {
52774 + return -EINVAL;
52775 + }
52776 +
52777 + /* Hash function produces 64-bit value, 24 bits of that
52778 + * are used to generate fq_id and policer profile.
52779 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
52780 + */
52781 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
52782 + return -EINVAL;
52783 + }
52784 +
52785 + tmp_reg |= params->hash_params.mask;
52786 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
52787 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
52788 +
52789 + if (params->hash_params.sym) {
52790 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
52791 + }
52792 +
52793 + }
52794 +
52795 + if (params->bypass_fqid_gen) {
52796 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
52797 + }
52798 +
52799 + scheme_regs->kgse_hc = tmp_reg;
52800 +
52801 + /* Policer Profile register */
52802 + if (params->policer_params.bypass_pp_gen) {
52803 + tmp_reg = 0;
52804 + } else {
52805 + /* Lower 8 bits of 24-bits extracted from hash result
52806 + * are used for policer profile generation.
52807 + * That leaves maximum shift value = 23. */
52808 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
52809 + return -EINVAL;
52810 + }
52811 +
52812 + tmp_reg = params->policer_params.base;
52813 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
52814 + FMAN_KG_SCH_PP_SH_SHIFT) &
52815 + FMAN_KG_SCH_PP_SH_MASK;
52816 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
52817 + FMAN_KG_SCH_PP_SL_SHIFT) &
52818 + FMAN_KG_SCH_PP_SL_MASK;
52819 + tmp_reg |= (uint32_t)params->policer_params.mask <<
52820 + FMAN_KG_SCH_PP_MASK_SHIFT;
52821 + }
52822 +
52823 + scheme_regs->kgse_ppc = tmp_reg;
52824 +
52825 + /* Coarse Classification Bit Select register */
52826 + if (params->next_engine == E_FMAN_PCD_CC) {
52827 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
52828 + }
52829 +
52830 + /* Packets Counter register */
52831 + if (params->update_counter) {
52832 + scheme_regs->kgse_spc = params->counter_value;
52833 + }
52834 +
52835 + return 0;
52836 +}
52837 +
52838 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
52839 + uint8_t scheme_id,
52840 + uint8_t hwport_id,
52841 + struct fman_kg_scheme_regs *scheme_regs,
52842 + bool update_counter)
52843 +{
52844 + struct fman_kg_scheme_regs *kgse_regs;
52845 + uint32_t tmp_reg;
52846 + int err, i;
52847 +
52848 + /* Write indirect scheme registers */
52849 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
52850 +
52851 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
52852 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
52853 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
52854 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
52855 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
52856 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
52857 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
52858 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
52859 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
52860 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
52861 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
52862 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
52863 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
52864 +
52865 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
52866 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
52867 +
52868 + /* Write AR (Action register) */
52869 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
52870 + err = fman_kg_write_ar_wait(regs, tmp_reg);
52871 + return err;
52872 +}
52873 +
52874 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
52875 + uint8_t scheme_id,
52876 + uint8_t hwport_id)
52877 +{
52878 + struct fman_kg_scheme_regs *kgse_regs;
52879 + uint32_t tmp_reg;
52880 + int err, i;
52881 +
52882 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
52883 +
52884 + /* Clear all registers including enable bit in mode register */
52885 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
52886 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
52887 + }
52888 +
52889 + /* Write AR (Action register) */
52890 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
52891 + err = fman_kg_write_ar_wait(regs, tmp_reg);
52892 + return err;
52893 +}
52894 +
52895 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
52896 + uint8_t scheme_id,
52897 + uint8_t hwport_id,
52898 + uint32_t *counter)
52899 +{
52900 + struct fman_kg_scheme_regs *kgse_regs;
52901 + uint32_t tmp_reg;
52902 + int err;
52903 +
52904 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
52905 +
52906 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
52907 + err = fman_kg_write_ar_wait(regs, tmp_reg);
52908 +
52909 + if (err != 0)
52910 + return err;
52911 +
52912 + *counter = ioread32be(&kgse_regs->kgse_spc);
52913 +
52914 + return 0;
52915 +}
52916 +
52917 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
52918 + uint8_t scheme_id,
52919 + uint8_t hwport_id,
52920 + uint32_t counter)
52921 +{
52922 + struct fman_kg_scheme_regs *kgse_regs;
52923 + uint32_t tmp_reg;
52924 + int err;
52925 +
52926 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
52927 +
52928 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
52929 +
52930 + err = fman_kg_write_ar_wait(regs, tmp_reg);
52931 + if (err != 0)
52932 + return err;
52933 +
52934 + /* Keygen indirect access memory contains all scheme_id registers
52935 + * by now. Change only counter value. */
52936 + iowrite32be(counter, &kgse_regs->kgse_spc);
52937 +
52938 + /* Write back scheme registers */
52939 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
52940 + err = fman_kg_write_ar_wait(regs, tmp_reg);
52941 +
52942 + return err;
52943 +}
52944 +
52945 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
52946 +{
52947 + return ioread32be(&regs->fmkg_tpc);
52948 +}
52949 +
52950 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
52951 + struct fman_kg_cp_regs *cls_plan_regs)
52952 +{
52953 + uint8_t entries_set, entry_bit;
52954 + int i;
52955 +
52956 + /* Zero out all group's register */
52957 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
52958 +
52959 + /* Go over all classification entries in params->entries_mask and
52960 + * configure the corresponding cpe register */
52961 + entries_set = params->entries_mask;
52962 + for (i = 0; entries_set; i++) {
52963 + entry_bit = (uint8_t)(0x80 >> i);
52964 + if ((entry_bit & entries_set) == 0)
52965 + continue;
52966 + entries_set ^= entry_bit;
52967 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
52968 + }
52969 +
52970 + return 0;
52971 +}
52972 +
52973 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
52974 + uint8_t grp_id,
52975 + uint8_t entries_mask,
52976 + uint8_t hwport_id,
52977 + struct fman_kg_cp_regs *cls_plan_regs)
52978 +{
52979 + struct fman_kg_cp_regs *kgcpe_regs;
52980 + uint32_t tmp_reg;
52981 + int i, err;
52982 +
52983 + /* Check group index is valid and the group isn't empty */
52984 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
52985 + return -EINVAL;
52986 +
52987 + /* Write indirect classification plan registers */
52988 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
52989 +
52990 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
52991 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
52992 + }
52993 +
52994 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
52995 + err = fman_kg_write_ar_wait(regs, tmp_reg);
52996 + return err;
52997 +}
52998 +
52999 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
53000 + uint8_t hwport_id,
53001 + uint32_t schemes)
53002 +{
53003 + struct fman_kg_pe_regs *kg_pe_regs;
53004 + uint32_t tmp_reg;
53005 + int err;
53006 +
53007 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
53008 +
53009 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
53010 +
53011 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
53012 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53013 + return err;
53014 +}
53015 +
53016 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
53017 + uint8_t grp_mask,
53018 + uint32_t *bind_cls_plans)
53019 +{
53020 + /* Check grp_base and grp_mask are 5-bits values */
53021 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
53022 + return -EINVAL;
53023 +
53024 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
53025 + return 0;
53026 +}
53027 +
53028 +
53029 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
53030 + uint8_t hwport_id,
53031 + uint32_t bind_cls_plans)
53032 +{
53033 + struct fman_kg_pe_regs *kg_pe_regs;
53034 + uint32_t tmp_reg;
53035 + int err;
53036 +
53037 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
53038 +
53039 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
53040 +
53041 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
53042 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53043 + return err;
53044 +}
53045 --- /dev/null
53046 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
53047 @@ -0,0 +1,129 @@
53048 +/*
53049 + * Copyright 2012 Freescale Semiconductor Inc.
53050 + *
53051 + * Redistribution and use in source and binary forms, with or without
53052 + * modification, are permitted provided that the following conditions are met:
53053 + * * Redistributions of source code must retain the above copyright
53054 + * notice, this list of conditions and the following disclaimer.
53055 + * * Redistributions in binary form must reproduce the above copyright
53056 + * notice, this list of conditions and the following disclaimer in the
53057 + * documentation and/or other materials provided with the distribution.
53058 + * * Neither the name of Freescale Semiconductor nor the
53059 + * names of its contributors may be used to endorse or promote products
53060 + * derived from this software without specific prior written permission.
53061 + *
53062 + *
53063 + * ALTERNATIVELY, this software may be distributed under the terms of the
53064 + * GNU General Public License ("GPL") as published by the Free Software
53065 + * Foundation, either version 2 of that License or (at your option) any
53066 + * later version.
53067 + *
53068 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
53069 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53070 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53071 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
53072 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53073 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53074 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53075 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53076 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53077 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53078 + */
53079 +
53080 +#include "fsl_fman_prs.h"
53081 +
53082 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
53083 +{
53084 + return ioread32be(&regs->fmpr_perr) & ev_mask;
53085 +}
53086 +
53087 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
53088 +{
53089 + return ioread32be(&regs->fmpr_perer);
53090 +}
53091 +
53092 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
53093 +{
53094 + iowrite32be(event, &regs->fmpr_perr);
53095 +}
53096 +
53097 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
53098 +{
53099 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
53100 +}
53101 +
53102 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
53103 +{
53104 + return ioread32be(&regs->fmpr_pever);
53105 +}
53106 +
53107 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
53108 +{
53109 + iowrite32be(event, &regs->fmpr_pevr);
53110 +}
53111 +
53112 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
53113 +{
53114 + cfg->port_id_stat = 0;
53115 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
53116 + cfg->prs_exceptions = 0x03000000;
53117 +}
53118 +
53119 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
53120 +{
53121 + uint32_t tmp;
53122 +
53123 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
53124 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
53125 + &regs->fmpr_pevr);
53126 +
53127 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
53128 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
53129 + else
53130 + iowrite32be(0, &regs->fmpr_pever);
53131 +
53132 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
53133 +
53134 + tmp = 0;
53135 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
53136 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
53137 + iowrite32be(tmp, &regs->fmpr_perer);
53138 +
53139 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
53140 +
53141 + return 0;
53142 +}
53143 +
53144 +void fman_prs_enable(struct fman_prs_regs *regs)
53145 +{
53146 + uint32_t tmp;
53147 +
53148 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
53149 + iowrite32be(tmp, &regs->fmpr_rpimac);
53150 +}
53151 +
53152 +void fman_prs_disable(struct fman_prs_regs *regs)
53153 +{
53154 + uint32_t tmp;
53155 +
53156 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
53157 + iowrite32be(tmp, &regs->fmpr_rpimac);
53158 +}
53159 +
53160 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
53161 +{
53162 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
53163 +}
53164 +
53165 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
53166 +{
53167 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
53168 +}
53169 +
53170 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
53171 +{
53172 + if (enable)
53173 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
53174 + else
53175 + iowrite32be(0, &regs->fmpr_ppsc);
53176 +}
53177 --- /dev/null
53178 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
53179 @@ -0,0 +1,15 @@
53180 +#
53181 +# Makefile for the Freescale Ethernet controllers
53182 +#
53183 +ccflags-y += -DVERSION=\"\"
53184 +#
53185 +#Include netcomm SW specific definitions
53186 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
53187 +
53188 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
53189 +
53190 +ccflags-y += -I$(NCSW_FM_INC)
53191 +
53192 +obj-y += fsl-ncsw-Pcd.o
53193 +
53194 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
53195 --- /dev/null
53196 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
53197 @@ -0,0 +1,6436 @@
53198 +/*
53199 + * Copyright 2008-2012 Freescale Semiconductor Inc.
53200 + *
53201 + * Redistribution and use in source and binary forms, with or without
53202 + * modification, are permitted provided that the following conditions are met:
53203 + * * Redistributions of source code must retain the above copyright
53204 + * notice, this list of conditions and the following disclaimer.
53205 + * * Redistributions in binary form must reproduce the above copyright
53206 + * notice, this list of conditions and the following disclaimer in the
53207 + * documentation and/or other materials provided with the distribution.
53208 + * * Neither the name of Freescale Semiconductor nor the
53209 + * names of its contributors may be used to endorse or promote products
53210 + * derived from this software without specific prior written permission.
53211 + *
53212 + *
53213 + * ALTERNATIVELY, this software may be distributed under the terms of the
53214 + * GNU General Public License ("GPL") as published by the Free Software
53215 + * Foundation, either version 2 of that License or (at your option) any
53216 + * later version.
53217 + *
53218 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
53219 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53220 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53221 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
53222 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53223 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53224 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53225 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53226 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53227 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53228 + */
53229 +
53230 +
53231 +/******************************************************************************
53232 + @File fm_port.c
53233 +
53234 + @Description FM driver routines implementation.
53235 + *//***************************************************************************/
53236 +#include "error_ext.h"
53237 +#include "std_ext.h"
53238 +#include "string_ext.h"
53239 +#include "sprint_ext.h"
53240 +#include "debug_ext.h"
53241 +#include "fm_muram_ext.h"
53242 +
53243 +#include "fman_common.h"
53244 +#include "fm_port.h"
53245 +#include "fm_port_dsar.h"
53246 +#include "common/general.h"
53247 +
53248 +/****************************************/
53249 +/* static functions */
53250 +/****************************************/
53251 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
53252 +
53253 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
53254 +{
53255 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
53256 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
53257 + t_Error ans = E_OK;
53258 + uint32_t unusedMask;
53259 +
53260 + if (p_FmPort->imEn)
53261 + {
53262 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53263 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53264 + > 2)
53265 + RETURN_ERROR(
53266 + MAJOR,
53267 + E_INVALID_VALUE,
53268 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
53269 +
53270 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
53271 + return ERROR_CODE(ans);
53272 + }
53273 + else
53274 + {
53275 + /****************************************/
53276 + /* Rx only */
53277 + /****************************************/
53278 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53279 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
53280 + {
53281 + /* external buffer pools */
53282 + if (!p_Params->extBufPools.numOfPoolsUsed)
53283 + RETURN_ERROR(
53284 + MAJOR,
53285 + E_INVALID_VALUE,
53286 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
53287 +
53288 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
53289 + p_Params->p_BackupBmPools,
53290 + &p_Params->bufPoolDepletion) != E_OK)
53291 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53292 +
53293 + /* Check that part of IC that needs copying is small enough to enter start margin */
53294 + if (p_Params->intContext.size
53295 + && (p_Params->intContext.size
53296 + + p_Params->intContext.extBufOffset
53297 + > p_Params->bufMargins.startMargins))
53298 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53299 + ("intContext.size is larger than start margins"));
53300 +
53301 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
53302 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
53303 + RETURN_ERROR(
53304 + MAJOR,
53305 + E_INVALID_VALUE,
53306 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
53307 +
53308 +#ifdef FM_NO_BACKUP_POOLS
53309 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
53310 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
53311 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
53312 +#endif /* FM_NO_BACKUP_POOLS */
53313 + }
53314 +
53315 + /****************************************/
53316 + /* Non Rx ports */
53317 + /****************************************/
53318 + else
53319 + {
53320 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
53321 + RETURN_ERROR(
53322 + MAJOR,
53323 + E_INVALID_VALUE,
53324 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
53325 +
53326 + /* to protect HW internal-context from overwrite */
53327 + if ((p_Params->intContext.size)
53328 + && (p_Params->intContext.intContextOffset
53329 + < MIN_TX_INT_OFFSET))
53330 + RETURN_ERROR(
53331 + MAJOR,
53332 + E_INVALID_VALUE,
53333 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
53334 +
53335 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
53336 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
53337 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
53338 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53339 + != DEFAULT_notSupported))
53340 + {
53341 + /* Check that not larger than 8 */
53342 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
53343 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53344 + > MAX_FIFO_PIPELINE_DEPTH))
53345 + RETURN_ERROR(
53346 + MAJOR,
53347 + E_INVALID_VALUE,
53348 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
53349 + }
53350 + }
53351 +
53352 + /****************************************/
53353 + /* Rx Or Offline Parsing */
53354 + /****************************************/
53355 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53356 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53357 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53358 + {
53359 + if (!p_Params->dfltFqid)
53360 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53361 + ("dfltFqid must be between 1 and 2^24-1"));
53362 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
53363 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
53364 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
53365 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
53366 + }
53367 +
53368 + /****************************************/
53369 + /* All ports */
53370 + /****************************************/
53371 + /* common BMI registers values */
53372 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
53373 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
53374 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53375 + ("errFqid must be between 1 and 2^24-1"));
53376 + if (p_Params->dfltFqid & ~0x00FFFFFF)
53377 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53378 + ("dfltFqid must be between 1 and 2^24-1"));
53379 + }
53380 +
53381 + /****************************************/
53382 + /* Rx only */
53383 + /****************************************/
53384 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53385 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
53386 + {
53387 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
53388 + RETURN_ERROR(
53389 + MAJOR,
53390 + E_INVALID_VALUE,
53391 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
53392 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
53393 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
53394 + RETURN_ERROR(
53395 + MAJOR,
53396 + E_INVALID_VALUE,
53397 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53398 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
53399 + RETURN_ERROR(
53400 + MAJOR,
53401 + E_INVALID_VALUE,
53402 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
53403 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
53404 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
53405 + RETURN_ERROR(
53406 + MAJOR,
53407 + E_INVALID_VALUE,
53408 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53409 +
53410 + /* Check that not larger than 16 */
53411 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
53412 + RETURN_ERROR(
53413 + MAJOR,
53414 + E_INVALID_VALUE,
53415 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
53416 +
53417 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
53418 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53419 +
53420 + /* extra FIFO size (allowed only to Rx ports) */
53421 + if (p_Params->setSizeOfFifo
53422 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
53423 + RETURN_ERROR(
53424 + MAJOR,
53425 + E_INVALID_VALUE,
53426 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
53427 +
53428 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
53429 + && !p_Params->bufPoolDepletion.numOfPools)
53430 + RETURN_ERROR(
53431 + MAJOR,
53432 + E_INVALID_VALUE,
53433 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
53434 +#ifdef FM_CSI_CFED_LIMIT
53435 + if (p_FmPort->fmRevInfo.majorRev == 4)
53436 + {
53437 + /* Check that not larger than 16 */
53438 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
53439 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
53440 + }
53441 +#endif /* FM_CSI_CFED_LIMIT */
53442 + }
53443 +
53444 + /****************************************/
53445 + /* Non Rx ports */
53446 + /****************************************/
53447 + /* extra FIFO size (allowed only to Rx ports) */
53448 + else
53449 + if (p_FmPort->fifoBufs.extra)
53450 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53451 + (" No fifoBufs.extra for non Rx ports"));
53452 +
53453 + /****************************************/
53454 + /* Tx only */
53455 + /****************************************/
53456 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
53457 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
53458 + {
53459 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
53460 + RETURN_ERROR(
53461 + MAJOR,
53462 + E_INVALID_VALUE,
53463 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
53464 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
53465 + RETURN_ERROR(
53466 + MAJOR,
53467 + E_INVALID_VALUE,
53468 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
53469 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
53470 + RETURN_ERROR(
53471 + MAJOR,
53472 + E_INVALID_VALUE,
53473 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
53474 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
53475 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
53476 + RETURN_ERROR(
53477 + MAJOR,
53478 + E_INVALID_VALUE,
53479 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53480 +
53481 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
53482 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53483 + > 2)
53484 + RETURN_ERROR(
53485 + MAJOR, E_INVALID_VALUE,
53486 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
53487 + }
53488 +
53489 + /****************************************/
53490 + /* Non Tx Ports */
53491 + /****************************************/
53492 + /* If discard override was selected , no frames may be discarded. */
53493 + else
53494 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
53495 + RETURN_ERROR(
53496 + MAJOR,
53497 + E_CONFLICT,
53498 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
53499 +
53500 + /****************************************/
53501 + /* Rx and Offline parsing */
53502 + /****************************************/
53503 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53504 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53505 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53506 + {
53507 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53508 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
53509 + else
53510 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
53511 +
53512 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
53513 + if (p_Params->errorsToDiscard & unusedMask)
53514 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
53515 + ("errorsToDiscard contains undefined bits"));
53516 + }
53517 +
53518 + /****************************************/
53519 + /* Offline Ports */
53520 + /****************************************/
53521 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
53522 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
53523 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53524 + && p_Params->setNumOfOpenDmas
53525 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
53526 + RETURN_ERROR(
53527 + MAJOR,
53528 + E_INVALID_VALUE,
53529 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
53530 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
53531 +
53532 + /****************************************/
53533 + /* Offline & HC Ports */
53534 + /****************************************/
53535 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53536 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
53537 + {
53538 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
53539 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
53540 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
53541 + /* this is an indication that user called config for this mode which is not supported in this integration */
53542 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
53543 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
53544 +
53545 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
53546 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
53547 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
53548 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
53549 + /* this is an indication that user called config for this mode which is not supported in this integration */
53550 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
53551 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
53552 + }
53553 +
53554 + /****************************************/
53555 + /* All ports */
53556 + /****************************************/
53557 + /* Check that not larger than 16 */
53558 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
53559 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
53560 + RETURN_ERROR(
53561 + MAJOR,
53562 + E_INVALID_VALUE,
53563 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
53564 +
53565 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
53566 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53567 +
53568 + /* common BMI registers values */
53569 + if (p_Params->setNumOfTasks
53570 + && ((!p_FmPort->tasks.num)
53571 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
53572 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53573 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
53574 + if (p_Params->setNumOfTasks
53575 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
53576 + RETURN_ERROR(
53577 + MAJOR,
53578 + E_INVALID_VALUE,
53579 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
53580 + if (p_Params->setNumOfOpenDmas
53581 + && ((!p_FmPort->openDmas.num)
53582 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
53583 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53584 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
53585 + if (p_Params->setNumOfOpenDmas
53586 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
53587 + RETURN_ERROR(
53588 + MAJOR,
53589 + E_INVALID_VALUE,
53590 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
53591 + if (p_Params->setSizeOfFifo
53592 + && (!p_FmPort->fifoBufs.num
53593 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
53594 + RETURN_ERROR(
53595 + MAJOR,
53596 + E_INVALID_VALUE,
53597 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53598 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
53599 + RETURN_ERROR(
53600 + MAJOR, E_INVALID_VALUE,
53601 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
53602 +
53603 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
53604 + if (p_FmPort->fmRevInfo.majorRev == 4)
53605 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
53606 + /* this is an indication that user called config for this mode which is not supported in this integration */
53607 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
53608 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
53609 +
53610 + return E_OK;
53611 +}
53612 +
53613 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
53614 +{
53615 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
53616 +
53617 + /*************************/
53618 + /* TX PORTS */
53619 + /*************************/
53620 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
53621 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
53622 + {
53623 + minFifoSizeRequired =
53624 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
53625 + + (3 * BMI_FIFO_UNITS));
53626 + if (!p_FmPort->imEn)
53627 + minFifoSizeRequired +=
53628 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53629 + * BMI_FIFO_UNITS;
53630 +
53631 + optFifoSizeForB2B = minFifoSizeRequired;
53632 +
53633 + /* Add some margin for back-to-back capability to improve performance,
53634 + allows the hardware to pipeline new frame dma while the previous
53635 + frame not yet transmitted. */
53636 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
53637 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
53638 + else
53639 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
53640 + }
53641 +
53642 + /*************************/
53643 + /* RX IM PORTS */
53644 + /*************************/
53645 + else
53646 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53647 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
53648 + && p_FmPort->imEn)
53649 + {
53650 + optFifoSizeForB2B =
53651 + minFifoSizeRequired =
53652 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
53653 + + (4 * BMI_FIFO_UNITS));
53654 + }
53655 +
53656 + /*************************/
53657 + /* RX non-IM PORTS */
53658 + /*************************/
53659 + else
53660 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53661 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
53662 + && !p_FmPort->imEn)
53663 + {
53664 + if (p_FmPort->fmRevInfo.majorRev == 4)
53665 + {
53666 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
53667 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
53668 + else
53669 + minFifoSizeRequired =
53670 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
53671 + + (7 * BMI_FIFO_UNITS));
53672 + }
53673 + else
53674 + {
53675 +#if (DPAA_VERSION >= 11)
53676 + minFifoSizeRequired =
53677 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
53678 + + (5 * BMI_FIFO_UNITS));
53679 + /* 4 according to spec + 1 for FOF>0 */
53680 +#else
53681 + minFifoSizeRequired = (uint32_t)
53682 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
53683 + + (7*BMI_FIFO_UNITS));
53684 +#endif /* (DPAA_VERSION >= 11) */
53685 + }
53686 +
53687 + optFifoSizeForB2B = minFifoSizeRequired;
53688 +
53689 + /* Add some margin for back-to-back capability to improve performance,
53690 + allows the hardware to pipeline new frame dma while the previous
53691 + frame not yet transmitted. */
53692 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53693 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
53694 + else
53695 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
53696 + }
53697 +
53698 + /* For O/H ports, check fifo size and update if necessary */
53699 + else
53700 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53701 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
53702 + {
53703 +#if (DPAA_VERSION >= 11)
53704 + optFifoSizeForB2B =
53705 + minFifoSizeRequired =
53706 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
53707 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53708 + + 5) * BMI_FIFO_UNITS));
53709 + /* 4 according to spec + 1 for FOF>0 */
53710 +#else
53711 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
53712 +#endif /* (DPAA_VERSION >= 11) */
53713 + }
53714 +
53715 + ASSERT_COND(minFifoSizeRequired > 0);
53716 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
53717 +
53718 + /* Verify the size */
53719 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
53720 + DBG(INFO,
53721 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
53722 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
53723 + DBG(INFO,
53724 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
53725 +
53726 + return E_OK;
53727 +}
53728 +
53729 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
53730 +{
53731 + if (p_FmPort->p_FmPortDriverParam)
53732 + {
53733 + XX_Free(p_FmPort->p_FmPortDriverParam);
53734 + p_FmPort->p_FmPortDriverParam = NULL;
53735 + }
53736 +}
53737 +
53738 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
53739 +{
53740 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
53741 + t_FmBufPoolDepletion *p_BufPoolDepletion =
53742 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
53743 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
53744 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
53745 + int i = 0, j = 0, err;
53746 + struct fman_port_bpools bpools;
53747 +
53748 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
53749 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
53750 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
53751 +
53752 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
53753 + sizesArray);
53754 +
53755 + /* Prepare flibs bpools structure */
53756 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
53757 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
53758 + bpools.counters_enable = TRUE;
53759 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
53760 + {
53761 + bpools.bpool[i].bpid = orderedArray[i];
53762 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
53763 + /* functionality available only for some derivatives (limited by config) */
53764 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
53765 + for (j = 0;
53766 + j
53767 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
53768 + j++)
53769 + if (orderedArray[i]
53770 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
53771 + {
53772 + bpools.bpool[i].is_backup = TRUE;
53773 + break;
53774 + }
53775 + }
53776 +
53777 + /* save pools parameters for later use */
53778 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
53779 + p_FmPort->rxPoolsParams.largestBufSize =
53780 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
53781 + p_FmPort->rxPoolsParams.secondLargestBufSize =
53782 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
53783 +
53784 + /* FMBM_RMPD reg. - pool depletion */
53785 + if (p_BufPoolDepletion->poolsGrpModeEnable)
53786 + {
53787 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
53788 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
53789 + {
53790 + if (p_BufPoolDepletion->poolsToConsider[i])
53791 + {
53792 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
53793 + {
53794 + if (i == orderedArray[j])
53795 + {
53796 + bpools.bpool[j].grp_bp_depleted = TRUE;
53797 + break;
53798 + }
53799 + }
53800 + }
53801 + }
53802 + }
53803 +
53804 + if (p_BufPoolDepletion->singlePoolModeEnable)
53805 + {
53806 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
53807 + {
53808 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
53809 + {
53810 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
53811 + {
53812 + if (i == orderedArray[j])
53813 + {
53814 + bpools.bpool[j].single_bp_depleted = TRUE;
53815 + break;
53816 + }
53817 + }
53818 + }
53819 + }
53820 + }
53821 +
53822 +#if (DPAA_VERSION >= 11)
53823 + /* fill QbbPEV */
53824 + if (p_BufPoolDepletion->poolsGrpModeEnable
53825 + || p_BufPoolDepletion->singlePoolModeEnable)
53826 + {
53827 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
53828 + {
53829 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
53830 + {
53831 + bpools.bpool[i].pfc_priorities_en = TRUE;
53832 + }
53833 + }
53834 + }
53835 +#endif /* (DPAA_VERSION >= 11) */
53836 +
53837 + /* Issue flibs function */
53838 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
53839 + if (err != 0)
53840 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
53841 +
53842 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
53843 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
53844 +
53845 + return E_OK;
53846 +}
53847 +
53848 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
53849 +{
53850 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53851 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
53852 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
53853 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
53854 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
53855 + return E_OK;
53856 +}
53857 +
53858 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
53859 +{
53860 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
53861 + struct fman_port_params portParams;
53862 + uint32_t tmpVal;
53863 + t_Error err;
53864 +
53865 + /* Set up flibs parameters and issue init function */
53866 +
53867 + memset(&portParams, 0, sizeof(struct fman_port_params));
53868 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
53869 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
53870 + portParams.err_fqid = p_DriverParams->errFqid;
53871 + portParams.deq_sp = p_DriverParams->deqSubPortal;
53872 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
53873 + switch (p_FmPort->portType)
53874 + {
53875 + case (e_FM_PORT_TYPE_RX_10G):
53876 + case (e_FM_PORT_TYPE_RX):
53877 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
53878 + if (!p_FmPort->imEn)
53879 + {
53880 + if (p_DriverParams->forwardReuseIntContext)
53881 + p_DriverParams->dfltCfg.rx_fd_bits =
53882 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
53883 + }
53884 + break;
53885 +
53886 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53887 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
53888 + break;
53889 + break;
53890 +
53891 + default:
53892 + break;
53893 + }
53894 +
53895 + tmpVal =
53896 + (uint32_t)(
53897 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
53898 + / OFFSET_UNITS + 1) :
53899 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
53900 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
53901 + p_DriverParams->dfltCfg.int_buf_start_margin =
53902 + p_FmPort->internalBufferOffset;
53903 +
53904 + p_DriverParams->dfltCfg.ext_buf_start_margin =
53905 + p_DriverParams->bufMargins.startMargins;
53906 + p_DriverParams->dfltCfg.ext_buf_end_margin =
53907 + p_DriverParams->bufMargins.endMargins;
53908 +
53909 + p_DriverParams->dfltCfg.ic_ext_offset =
53910 + p_DriverParams->intContext.extBufOffset;
53911 + p_DriverParams->dfltCfg.ic_int_offset =
53912 + p_DriverParams->intContext.intContextOffset;
53913 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
53914 +
53915 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
53916 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
53917 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
53918 +
53919 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
53920 + (uint8_t)p_FmPort->tasks.num;
53921 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
53922 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
53923 + else
53924 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
53925 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
53926 + (uint8_t)p_FmPort->openDmas.num;
53927 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
53928 +
53929 + if (0
53930 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
53931 + &portParams))
53932 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
53933 +
53934 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
53935 + RETURN_ERROR(MAJOR, err, NO_MSG);
53936 + else
53937 + {
53938 + // from QMIInit
53939 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53940 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
53941 + {
53942 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
53943 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
53944 + FALSE);
53945 + else
53946 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
53947 + TRUE);
53948 + }
53949 + }
53950 + /* The code bellow is a trick so the FM will not release the buffer
53951 + to BM nor will try to enqueue the frame to QM */
53952 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
53953 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
53954 + {
53955 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
53956 + {
53957 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
53958 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
53959 + * buffers to BM regardless of fmbm_tfene
53960 + */
53961 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
53962 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
53963 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
53964 + }
53965 + }
53966 +
53967 + return E_OK;
53968 +}
53969 +
53970 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
53971 +{
53972 + UNUSED(p_FmPort);
53973 +
53974 + switch (counter)
53975 + {
53976 + case (e_FM_PORT_COUNTERS_CYCLE):
53977 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
53978 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
53979 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
53980 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
53981 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
53982 + case (e_FM_PORT_COUNTERS_FRAME):
53983 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
53984 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
53985 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
53986 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
53987 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
53988 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
53989 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
53990 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
53991 + return TRUE;
53992 + default:
53993 + return FALSE;
53994 + }
53995 +}
53996 +
53997 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
53998 +{
53999 + UNUSED(p_FmPort);
54000 +
54001 + switch (counter)
54002 + {
54003 + case (e_FM_PORT_COUNTERS_CYCLE):
54004 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54005 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54006 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54007 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54008 + case (e_FM_PORT_COUNTERS_FRAME):
54009 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54010 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54011 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54012 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54013 + return TRUE;
54014 + default:
54015 + return FALSE;
54016 + }
54017 +}
54018 +
54019 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
54020 +{
54021 + switch (counter)
54022 + {
54023 + case (e_FM_PORT_COUNTERS_CYCLE):
54024 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54025 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54026 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54027 + case (e_FM_PORT_COUNTERS_FRAME):
54028 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54029 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54030 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
54031 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54032 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54033 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54034 + return TRUE;
54035 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54036 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54037 + return FALSE;
54038 + else
54039 + return TRUE;
54040 + default:
54041 + return FALSE;
54042 + }
54043 +}
54044 +
54045 +static t_Error BmiPortCheckAndGetCounterType(
54046 + t_FmPort *p_FmPort, e_FmPortCounters counter,
54047 + enum fman_port_stats_counters *p_StatsType,
54048 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
54049 +{
54050 + volatile uint32_t *p_Reg;
54051 + bool isValid;
54052 +
54053 + switch (p_FmPort->portType)
54054 + {
54055 + case (e_FM_PORT_TYPE_RX_10G):
54056 + case (e_FM_PORT_TYPE_RX):
54057 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
54058 + isValid = CheckRxBmiCounter(p_FmPort, counter);
54059 + break;
54060 + case (e_FM_PORT_TYPE_TX_10G):
54061 + case (e_FM_PORT_TYPE_TX):
54062 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
54063 + isValid = CheckTxBmiCounter(p_FmPort, counter);
54064 + break;
54065 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54066 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54067 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
54068 + isValid = CheckOhBmiCounter(p_FmPort, counter);
54069 + break;
54070 + default:
54071 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
54072 + }
54073 +
54074 + if (!isValid)
54075 + RETURN_ERROR(MINOR, E_INVALID_STATE,
54076 + ("Requested counter is not available for this port type"));
54077 +
54078 + /* check that counters are enabled */
54079 + switch (counter)
54080 + {
54081 + case (e_FM_PORT_COUNTERS_CYCLE):
54082 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54083 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54084 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54085 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54086 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
54087 + /* performance counters - may be read when disabled */
54088 + *p_IsStats = FALSE;
54089 + break;
54090 + case (e_FM_PORT_COUNTERS_FRAME):
54091 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54092 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54093 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
54094 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
54095 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54096 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54097 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
54098 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54099 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54100 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
54101 + *p_IsStats = TRUE;
54102 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
54103 + RETURN_ERROR(MINOR, E_INVALID_STATE,
54104 + ("Requested counter was not enabled"));
54105 + break;
54106 + default:
54107 + break;
54108 + }
54109 +
54110 + /* Set counter */
54111 + switch (counter)
54112 + {
54113 + case (e_FM_PORT_COUNTERS_CYCLE):
54114 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
54115 + break;
54116 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54117 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
54118 + break;
54119 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54120 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
54121 + break;
54122 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54123 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
54124 + break;
54125 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54126 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
54127 + break;
54128 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
54129 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
54130 + break;
54131 + case (e_FM_PORT_COUNTERS_FRAME):
54132 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
54133 + break;
54134 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54135 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
54136 + break;
54137 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54138 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
54139 + break;
54140 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
54141 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
54142 + break;
54143 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
54144 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
54145 + break;
54146 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
54147 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
54148 + break;
54149 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54150 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
54151 + break;
54152 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54153 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
54154 + break;
54155 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
54156 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
54157 + break;
54158 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54159 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
54160 + break;
54161 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54162 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
54163 + break;
54164 + default:
54165 + break;
54166 + }
54167 +
54168 + return E_OK;
54169 +}
54170 +
54171 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
54172 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
54173 + uint32_t *p_SoftSeqAttachReg)
54174 +{
54175 + uint8_t hdrNum, Ipv4HdrNum;
54176 + u_FmPcdHdrPrsOpts *p_prsOpts;
54177 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
54178 +
54179 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
54180 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
54181 + RETURN_ERROR(
54182 + MAJOR, E_NOT_SUPPORTED,
54183 + ("No additional parameters for private or special headers."));
54184 +
54185 + if (p_HdrParams->errDisable)
54186 + tmpReg |= PRS_HDR_ERROR_DIS;
54187 +
54188 + /* Set parser options */
54189 + if (p_HdrParams->usePrsOpts)
54190 + {
54191 + p_prsOpts = &p_HdrParams->prsOpts;
54192 + switch (p_HdrParams->hdr)
54193 + {
54194 + case (HEADER_TYPE_MPLS):
54195 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
54196 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
54197 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
54198 + if (hdrNum == ILLEGAL_HDR_NUM)
54199 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54200 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54201 + if (hdrNum < Ipv4HdrNum)
54202 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
54203 + ("Header must be equal or higher than IPv4"));
54204 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
54205 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
54206 + break;
54207 + case (HEADER_TYPE_PPPoE):
54208 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
54209 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
54210 + break;
54211 + case (HEADER_TYPE_IPv6):
54212 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
54213 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
54214 + break;
54215 + case (HEADER_TYPE_TCP):
54216 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
54217 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
54218 + else
54219 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
54220 + break;
54221 + case (HEADER_TYPE_UDP):
54222 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
54223 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
54224 + else
54225 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
54226 + break;
54227 + default:
54228 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
54229 + }
54230 + }
54231 +
54232 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
54233 + if (p_HdrParams->swPrsEnable)
54234 + {
54235 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
54236 + p_HdrParams->indexPerHdr);
54237 + if (tmpPrsOffset == ILLEGAL_BASE)
54238 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54239 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
54240 + }
54241 + *p_SoftSeqAttachReg = tmpReg;
54242 +
54243 + return E_OK;
54244 +}
54245 +
54246 +static uint32_t GetPortSchemeBindParams(
54247 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
54248 +{
54249 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54250 + uint32_t walking1Mask = 0x80000000, tmp;
54251 + uint8_t idx = 0;
54252 +
54253 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
54254 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
54255 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
54256 + p_SchemeBind->numOfSchemes = 0;
54257 + tmp = p_FmPort->schemesPerPortVector;
54258 + if (tmp)
54259 + {
54260 + while (tmp)
54261 + {
54262 + if (tmp & walking1Mask)
54263 + {
54264 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
54265 + p_SchemeBind->numOfSchemes++;
54266 + tmp &= ~walking1Mask;
54267 + }
54268 + walking1Mask >>= 1;
54269 + idx++;
54270 + }
54271 + }
54272 +
54273 + return tmp;
54274 +}
54275 +
54276 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
54277 +{
54278 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54279 + volatile uint32_t *p_BmiCfgReg = NULL;
54280 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
54281 + uint32_t lcv, walking1Mask = 0x80000000;
54282 + uint8_t cnt = 0;
54283 +
54284 + ASSERT_COND(p_FmPort);
54285 + ASSERT_COND(p_FmPort->h_FmPcd);
54286 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
54287 +
54288 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54289 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54290 + return;
54291 +
54292 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
54293 + /* get LCV for MACSEC */
54294 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
54295 + != 0)
54296 + {
54297 + while (!(lcv & walking1Mask))
54298 + {
54299 + cnt++;
54300 + walking1Mask >>= 1;
54301 + }
54302 +
54303 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
54304 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
54305 + }
54306 +}
54307 +
54308 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
54309 +{
54310 + t_Error err = E_OK;
54311 + uint32_t tmpReg;
54312 + volatile uint32_t *p_BmiNia = NULL;
54313 + volatile uint32_t *p_BmiPrsNia = NULL;
54314 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
54315 + volatile uint32_t *p_BmiInitPrsResult = NULL;
54316 + volatile uint32_t *p_BmiCcBase = NULL;
54317 + uint16_t hdrNum, L3HdrNum, greHdrNum;
54318 + int i;
54319 + bool isEmptyClsPlanGrp;
54320 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
54321 + uint16_t absoluteProfileId;
54322 + uint8_t physicalSchemeId;
54323 + uint32_t ccTreePhysOffset;
54324 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
54325 + uint32_t initialSwPrs = 0;
54326 +
54327 + ASSERT_COND(p_FmPort);
54328 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
54329 +
54330 + if (p_FmPort->imEn)
54331 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54332 + ("available for non-independant mode ports only"));
54333 +
54334 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54335 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54336 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54337 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54338 + ("available for Rx and offline parsing ports only"));
54339 +
54340 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
54341 +
54342 + p_FmPort->pcdEngines = 0;
54343 +
54344 + /* initialize p_FmPort->pcdEngines field in port's structure */
54345 + switch (p_PcdParams->pcdSupport)
54346 + {
54347 + case (e_FM_PORT_PCD_SUPPORT_NONE):
54348 + RETURN_ERROR(
54349 + MAJOR,
54350 + E_INVALID_STATE,
54351 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
54352 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
54353 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54354 + break;
54355 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
54356 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54357 + break;
54358 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
54359 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54360 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54361 + break;
54362 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
54363 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54364 + p_FmPort->pcdEngines |= FM_PCD_KG;
54365 + break;
54366 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
54367 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54368 + p_FmPort->pcdEngines |= FM_PCD_CC;
54369 + p_FmPort->pcdEngines |= FM_PCD_KG;
54370 + break;
54371 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
54372 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54373 + p_FmPort->pcdEngines |= FM_PCD_KG;
54374 + p_FmPort->pcdEngines |= FM_PCD_CC;
54375 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54376 + break;
54377 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
54378 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54379 + p_FmPort->pcdEngines |= FM_PCD_CC;
54380 + break;
54381 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
54382 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54383 + p_FmPort->pcdEngines |= FM_PCD_CC;
54384 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54385 + break;
54386 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
54387 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54388 + p_FmPort->pcdEngines |= FM_PCD_KG;
54389 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54390 + break;
54391 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
54392 + p_FmPort->pcdEngines |= FM_PCD_CC;
54393 + break;
54394 +#ifdef FM_CAPWAP_SUPPORT
54395 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
54396 + p_FmPort->pcdEngines |= FM_PCD_CC;
54397 + p_FmPort->pcdEngines |= FM_PCD_KG;
54398 + break;
54399 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
54400 + p_FmPort->pcdEngines |= FM_PCD_CC;
54401 + p_FmPort->pcdEngines |= FM_PCD_KG;
54402 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54403 + break;
54404 +#endif /* FM_CAPWAP_SUPPORT */
54405 +
54406 + default:
54407 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
54408 + }
54409 +
54410 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
54411 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
54412 + > FM_PCD_PRS_NUM_OF_HDRS))
54413 + RETURN_ERROR(
54414 + MAJOR,
54415 + E_INVALID_VALUE,
54416 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
54417 +
54418 + /* check that parameters exist for each and only each defined engine */
54419 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
54420 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
54421 + != !!p_PcdParams->p_KgParams)
54422 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
54423 + != !!p_PcdParams->p_CcParams))
54424 + RETURN_ERROR(
54425 + MAJOR,
54426 + E_INVALID_STATE,
54427 + ("PCD initialization structure is not consistent with pcdSupport"));
54428 +
54429 + /* get PCD registers pointers */
54430 + switch (p_FmPort->portType)
54431 + {
54432 + case (e_FM_PORT_TYPE_RX_10G):
54433 + case (e_FM_PORT_TYPE_RX):
54434 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
54435 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
54436 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
54437 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
54438 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
54439 + break;
54440 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54441 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
54442 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
54443 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
54444 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
54445 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
54446 + break;
54447 + default:
54448 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54449 + }
54450 +
54451 + /* set PCD port parameter */
54452 + if (p_FmPort->pcdEngines & FM_PCD_CC)
54453 + {
54454 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
54455 + p_PcdParams->p_CcParams->h_CcTree,
54456 + &ccTreePhysOffset, p_FmPort);
54457 + if (err)
54458 + RETURN_ERROR(MAJOR, err, NO_MSG);
54459 +
54460 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
54461 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
54462 + }
54463 +
54464 + if (p_FmPort->pcdEngines & FM_PCD_KG)
54465 + {
54466 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
54467 + RETURN_ERROR(
54468 + MAJOR,
54469 + E_INVALID_VALUE,
54470 + ("For ports using Keygen, at least one scheme must be bound. "));
54471 +
54472 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
54473 + p_FmPort->hardwarePortId,
54474 + p_FmPort->netEnvId,
54475 + p_FmPort->optArray,
54476 + &p_FmPort->clsPlanGrpId,
54477 + &isEmptyClsPlanGrp);
54478 + if (err)
54479 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
54480 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
54481 +
54482 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
54483 +
54484 + schemeBind.netEnvId = p_FmPort->netEnvId;
54485 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
54486 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
54487 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
54488 +
54489 + /* for each scheme */
54490 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
54491 + {
54492 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
54493 + physicalSchemeId = FmPcdKgGetSchemeId(
54494 + p_PcdParams->p_KgParams->h_Schemes[i]);
54495 + schemeBind.schemesIds[i] = physicalSchemeId;
54496 + /* build vector */
54497 + p_FmPort->schemesPerPortVector |= 1
54498 + << (31 - (uint32_t)physicalSchemeId);
54499 +#if (DPAA_VERSION >= 11)
54500 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
54501 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
54502 + if (!p_FmPort->vspe
54503 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
54504 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54505 + ("VSPE is not at port level"));
54506 +#endif /* (DPAA_VERSION >= 11) */
54507 + }
54508 +
54509 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
54510 + if (err)
54511 + RETURN_ERROR(MAJOR, err, NO_MSG);
54512 + }
54513 +
54514 + /***************************/
54515 + /* configure NIA after BMI */
54516 + /***************************/
54517 + /* rfne may contain FDCS bits, so first we read them. */
54518 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
54519 +
54520 + /* If policer is used directly after BMI or PRS */
54521 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
54522 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
54523 + || (p_PcdParams->pcdSupport
54524 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
54525 + {
54526 + if (!p_PcdParams->p_PlcrParams->h_Profile)
54527 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54528 + ("Profile should be initialized"));
54529 +
54530 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
54531 + p_PcdParams->p_PlcrParams->h_Profile);
54532 +
54533 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
54534 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54535 + ("Private port profile not valid."));
54536 +
54537 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
54538 +
54539 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
54540 + /* update BMI HPNIA */
54541 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
54542 + else
54543 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
54544 + /* update BMI NIA */
54545 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
54546 + }
54547 +
54548 + /* if CC is used directly after BMI */
54549 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
54550 +#ifdef FM_CAPWAP_SUPPORT
54551 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
54552 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
54553 +#endif /* FM_CAPWAP_SUPPORT */
54554 + )
54555 + {
54556 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54557 + RETURN_ERROR(
54558 + MAJOR,
54559 + E_INVALID_OPERATION,
54560 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
54561 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
54562 + /* check that prs start offset == RIM[FOF] */
54563 + }
54564 +
54565 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
54566 + {
54567 + ASSERT_COND(p_PcdParams->p_PrsParams);
54568 +#if (DPAA_VERSION >= 11)
54569 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
54570 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
54571 + else
54572 + {
54573 +#endif /* (DPAA_VERSION >= 11) */
54574 + /* if PRS is used it is always first */
54575 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
54576 + if (hdrNum == ILLEGAL_HDR_NUM)
54577 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
54578 +#if (DPAA_VERSION >= 11)
54579 + }
54580 +#endif /* (DPAA_VERSION >= 11) */
54581 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
54582 + /* set after parser NIA */
54583 + tmpReg = 0;
54584 + switch (p_PcdParams->pcdSupport)
54585 + {
54586 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
54587 + WRITE_UINT32(*p_BmiPrsNia,
54588 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
54589 + break;
54590 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
54591 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
54592 + tmpReg = NIA_KG_CC_EN;
54593 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
54594 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
54595 + if (p_PcdParams->p_KgParams->directScheme)
54596 + {
54597 + physicalSchemeId = FmPcdKgGetSchemeId(
54598 + p_PcdParams->p_KgParams->h_DirectScheme);
54599 + /* check that this scheme was bound to this port */
54600 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
54601 + if (p_PcdParams->p_KgParams->h_DirectScheme
54602 + == p_PcdParams->p_KgParams->h_Schemes[i])
54603 + break;
54604 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
54605 + RETURN_ERROR(
54606 + MAJOR,
54607 + E_INVALID_VALUE,
54608 + ("Direct scheme is not one of the port selected schemes."));
54609 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
54610 + }
54611 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
54612 + break;
54613 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
54614 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
54615 + WRITE_UINT32(*p_BmiPrsNia,
54616 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
54617 + break;
54618 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
54619 + break;
54620 + default:
54621 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
54622 + }
54623 +
54624 + /* set start parsing offset */
54625 + WRITE_UINT32(*p_BmiPrsStartOffset,
54626 + p_PcdParams->p_PrsParams->parsingOffset);
54627 +
54628 + /************************************/
54629 + /* Parser port parameters */
54630 + /************************************/
54631 + /* stop before configuring */
54632 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
54633 + /* wait for parser to be in idle state */
54634 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
54635 + ;
54636 +
54637 + /* set soft seq attachment register */
54638 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
54639 +
54640 + /* set protocol options */
54641 + for (i = 0; p_FmPort->optArray[i]; i++)
54642 + switch (p_FmPort->optArray[i])
54643 + {
54644 + case (ETH_BROADCAST):
54645 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
54646 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
54647 + break;
54648 + case (ETH_MULTICAST):
54649 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
54650 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
54651 + break;
54652 + case (VLAN_STACKED):
54653 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
54654 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
54655 + break;
54656 + case (MPLS_STACKED):
54657 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
54658 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
54659 + break;
54660 + case (IPV4_BROADCAST_1):
54661 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54662 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
54663 + break;
54664 + case (IPV4_MULTICAST_1):
54665 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54666 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
54667 + break;
54668 + case (IPV4_UNICAST_2):
54669 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54670 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
54671 + break;
54672 + case (IPV4_MULTICAST_BROADCAST_2):
54673 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54674 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
54675 + break;
54676 + case (IPV6_MULTICAST_1):
54677 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54678 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
54679 + break;
54680 + case (IPV6_UNICAST_2):
54681 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54682 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
54683 + break;
54684 + case (IPV6_MULTICAST_2):
54685 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54686 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
54687 + break;
54688 + }
54689 +
54690 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
54691 + HEADER_TYPE_UDP_ENCAP_ESP))
54692 + {
54693 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
54694 + RETURN_ERROR(
54695 + MINOR, E_INVALID_VALUE,
54696 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
54697 +
54698 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
54699 + HEADER_TYPE_UDP;
54700 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
54701 + TRUE;
54702 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
54703 + }
54704 +
54705 + /* set MPLS default next header - HW reset workaround */
54706 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
54707 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
54708 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
54709 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
54710 +
54711 + /* for GRE, disable errors */
54712 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
54713 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
54714 +
54715 + /* For UDP remove PAD from L4 checksum calculation */
54716 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
54717 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
54718 + /* For TCP remove PAD from L4 checksum calculation */
54719 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
54720 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
54721 +
54722 + /* config additional params for specific headers */
54723 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
54724 + i++)
54725 + {
54726 + /* case for using sw parser as the initial NIA address, before
54727 + * HW parsing
54728 + */
54729 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
54730 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
54731 + {
54732 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
54733 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
54734 + if (initialSwPrs == ILLEGAL_BASE)
54735 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54736 +
54737 + /* clear parser first HXS */
54738 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
54739 + /* rewrite with soft parser start */
54740 + p_FmPort->savedBmiNia |= initialSwPrs;
54741 + continue;
54742 + }
54743 +
54744 + hdrNum =
54745 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
54746 + if (hdrNum == ILLEGAL_HDR_NUM)
54747 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54748 + if (hdrNum == NO_HDR_NUM)
54749 + RETURN_ERROR(
54750 + MAJOR, E_INVALID_VALUE,
54751 + ("Private headers may not use additional parameters"));
54752 +
54753 + err = AdditionalPrsParams(
54754 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
54755 + &tmpHxs[hdrNum]);
54756 + if (err)
54757 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54758 + }
54759 +
54760 + /* Check if ip-reassembly port - need to link sw-parser code */
54761 + if (p_FmPort->h_IpReassemblyManip)
54762 + {
54763 + /* link to sw parser code for IP Frag - only if no other code is applied. */
54764 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54765 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
54766 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
54767 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54768 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
54769 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
54770 + } else {
54771 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
54772 + {
54773 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54774 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
54775 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
54776 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
54777 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
54778 + {
54779 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54780 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
54781 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
54782 + }
54783 + }
54784 +
54785 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
54786 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
54787 + HEADER_TYPE_UDP_LITE))
54788 + {
54789 + /* link to sw parser code for udp lite - only if no other code is applied. */
54790 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54791 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
54792 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
54793 + }
54794 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
54795 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
54796 + {
54797 + /* For all header set LCV as taken from netEnv*/
54798 + WRITE_UINT32(
54799 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
54800 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
54801 + /* set HXS register according to default+Additional params+protocol options */
54802 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
54803 + tmpHxs[i]);
54804 + }
54805 +
54806 + /* set tpid. */
54807 + tmpReg = PRS_TPID_DFLT;
54808 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
54809 + {
54810 + tmpReg &= PRS_TPID2_MASK;
54811 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
54812 + << PRS_PCTPID_SHIFT;
54813 + }
54814 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
54815 + {
54816 + tmpReg &= PRS_TPID1_MASK;
54817 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
54818 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
54819 +
54820 + /* enable parser */
54821 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
54822 +
54823 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
54824 + p_FmPort->privateInfo =
54825 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
54826 +
54827 + } /* end parser */
54828 + else {
54829 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
54830 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54831 + {
54832 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
54833 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
54834 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
54835 + }
54836 +
54837 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
54838 +
54839 + p_FmPort->privateInfo = 0;
54840 + }
54841 +
54842 + FmPortCheckNApplyMacsec(p_FmPort);
54843 +
54844 + WRITE_UINT32(
54845 + *p_BmiPrsStartOffset,
54846 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
54847 +
54848 + /* set initial parser result - used for all engines */
54849 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
54850 + {
54851 + if (!i)
54852 + WRITE_UINT32(
54853 + *(p_BmiInitPrsResult),
54854 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
54855 + else
54856 + {
54857 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
54858 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
54859 + else
54860 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
54861 + }
54862 + }
54863 +
54864 + return E_OK;
54865 +}
54866 +
54867 +static t_Error DeletePcd(t_FmPort *p_FmPort)
54868 +{
54869 + t_Error err = E_OK;
54870 + volatile uint32_t *p_BmiNia = NULL;
54871 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
54872 +
54873 + ASSERT_COND(p_FmPort);
54874 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
54875 +
54876 + if (p_FmPort->imEn)
54877 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54878 + ("available for non-independant mode ports only"));
54879 +
54880 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54881 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54882 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54883 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
54884 + ("available for Rx and offline parsing ports only"));
54885 +
54886 + if (!p_FmPort->pcdEngines)
54887 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
54888 +
54889 + /* get PCD registers pointers */
54890 + switch (p_FmPort->portType)
54891 + {
54892 + case (e_FM_PORT_TYPE_RX_10G):
54893 + case (e_FM_PORT_TYPE_RX):
54894 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
54895 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
54896 + break;
54897 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54898 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
54899 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
54900 + break;
54901 + default:
54902 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54903 + }
54904 +
54905 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
54906 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
54907 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54908 + ("port has to be detached previousely"));
54909 +
54910 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
54911 +
54912 + /* "cut" PCD out of the port's flow - go to BMI */
54913 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
54914 +
54915 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
54916 + {
54917 + /* stop parser */
54918 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
54919 + /* wait for parser to be in idle state */
54920 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
54921 + ;
54922 + }
54923 +
54924 + if (p_FmPort->pcdEngines & FM_PCD_KG)
54925 + {
54926 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
54927 +
54928 + /* unbind all schemes */
54929 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
54930 + &schemeBind);
54931 +
54932 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
54933 + if (err)
54934 + RETURN_ERROR(MAJOR, err, NO_MSG);
54935 +
54936 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
54937 + p_FmPort->hardwarePortId,
54938 + p_FmPort->clsPlanGrpId);
54939 + if (err)
54940 + RETURN_ERROR(MAJOR, err, NO_MSG);
54941 + p_FmPort->useClsPlan = FALSE;
54942 + }
54943 +
54944 + if (p_FmPort->pcdEngines & FM_PCD_CC)
54945 + {
54946 + /* unbind - we need to get the treeId too */
54947 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
54948 + if (err)
54949 + RETURN_ERROR(MAJOR, err, NO_MSG);
54950 + }
54951 +
54952 + p_FmPort->pcdEngines = 0;
54953 +
54954 + return E_OK;
54955 +}
54956 +
54957 +static t_Error AttachPCD(t_FmPort *p_FmPort)
54958 +{
54959 + volatile uint32_t *p_BmiNia = NULL;
54960 +
54961 + ASSERT_COND(p_FmPort);
54962 +
54963 + /* get PCD registers pointers */
54964 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54965 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
54966 + else
54967 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
54968 +
54969 + /* check that current NIA is BMI to BMI */
54970 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
54971 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
54972 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
54973 + ("may be called only for ports in BMI-to-BMI state."));
54974 +
54975 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
54976 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
54977 + p_FmPort->orFmanCtrl) != E_OK)
54978 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
54979 +
54980 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
54981 + {
54982 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54983 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
54984 + p_FmPort->savedBmiCmne);
54985 + else
54986 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
54987 + p_FmPort->savedBmiCmne);
54988 + }
54989 +
54990 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
54991 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
54992 + p_FmPort->savedQmiPnen);
54993 +
54994 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
54995 + {
54996 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54997 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
54998 + p_FmPort->savedBmiFene);
54999 + else
55000 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
55001 + p_FmPort->savedBmiFene);
55002 + }
55003 +
55004 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
55005 + {
55006 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55007 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
55008 + p_FmPort->savedBmiFpne);
55009 + else
55010 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
55011 + p_FmPort->savedBmiFpne);
55012 + }
55013 +
55014 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
55015 + {
55016 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
55017 +
55018 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
55019 + p_FmPort->savedBmiOfp);
55020 + }
55021 +
55022 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
55023 +
55024 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
55025 + {
55026 + p_FmPort->origNonRxQmiRegsPndn =
55027 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
55028 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
55029 + p_FmPort->savedNonRxQmiRegsPndn);
55030 + }
55031 +
55032 + return E_OK;
55033 +}
55034 +
55035 +static t_Error DetachPCD(t_FmPort *p_FmPort)
55036 +{
55037 + volatile uint32_t *p_BmiNia = NULL;
55038 +
55039 + ASSERT_COND(p_FmPort);
55040 +
55041 + /* get PCD registers pointers */
55042 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
55043 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
55044 + p_FmPort->origNonRxQmiRegsPndn);
55045 +
55046 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55047 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
55048 + else
55049 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
55050 +
55051 + WRITE_UINT32(
55052 + *p_BmiNia,
55053 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
55054 +
55055 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
55056 + FmPcdHcSync(p_FmPort->h_FmPcd);
55057 +
55058 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
55059 + {
55060 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55061 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
55062 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
55063 + else
55064 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
55065 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
55066 + }
55067 +
55068 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
55069 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
55070 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
55071 +
55072 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
55073 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
55074 + p_FmPort->orFmanCtrl) != E_OK)
55075 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55076 +
55077 + p_FmPort->requiredAction = 0;
55078 +
55079 + return E_OK;
55080 +}
55081 +
55082 +/*****************************************************************************/
55083 +/* Inter-module API routines */
55084 +/*****************************************************************************/
55085 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
55086 +{
55087 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55088 + volatile uint32_t *p_BmiCfgReg = NULL;
55089 + uint32_t tmpReg;
55090 +
55091 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
55092 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55093 +
55094 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55095 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55096 + {
55097 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
55098 + return;
55099 + }
55100 +
55101 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
55102 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
55103 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
55104 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
55105 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
55106 +
55107 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
55108 +}
55109 +
55110 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
55111 +{
55112 + return ((t_FmPort*)h_FmPort)->netEnvId;
55113 +}
55114 +
55115 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
55116 +{
55117 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
55118 +}
55119 +
55120 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
55121 +{
55122 + return ((t_FmPort*)h_FmPort)->pcdEngines;
55123 +}
55124 +
55125 +#if (DPAA_VERSION >= 11)
55126 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
55127 + void **p_Value)
55128 +{
55129 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55130 + uint32_t muramPageOffset;
55131 +
55132 + ASSERT_COND(p_FmPort);
55133 + ASSERT_COND(p_Value);
55134 +
55135 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
55136 + {
55137 + if (p_FmPort->gprFunc != gprFunc)
55138 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55139 + ("gpr was assigned with different func"));
55140 + }
55141 + else
55142 + {
55143 + switch (gprFunc)
55144 + {
55145 + case (e_FM_PORT_GPR_MURAM_PAGE):
55146 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
55147 + 256, 8);
55148 + if (!p_FmPort->p_ParamsPage)
55149 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
55150 +
55151 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
55152 + muramPageOffset =
55153 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
55154 + - p_FmPort->fmMuramPhysBaseAddr);
55155 + switch (p_FmPort->portType)
55156 + {
55157 + case (e_FM_PORT_TYPE_RX_10G):
55158 + case (e_FM_PORT_TYPE_RX):
55159 + WRITE_UINT32(
55160 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
55161 + muramPageOffset);
55162 + break;
55163 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55164 + WRITE_UINT32(
55165 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
55166 + muramPageOffset);
55167 + break;
55168 + default:
55169 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55170 + ("Invalid port type"));
55171 + }
55172 + break;
55173 + default:
55174 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
55175 + }
55176 + p_FmPort->gprFunc = gprFunc;
55177 + }
55178 +
55179 + switch (p_FmPort->gprFunc)
55180 + {
55181 + case (e_FM_PORT_GPR_MURAM_PAGE):
55182 + *p_Value = p_FmPort->p_ParamsPage;
55183 + break;
55184 + default:
55185 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
55186 + }
55187 +
55188 + return E_OK;
55189 +}
55190 +#endif /* (DPAA_VERSION >= 11) */
55191 +
55192 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
55193 + t_FmPortGetSetCcParams *p_CcParams)
55194 +{
55195 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55196 + int tmpInt;
55197 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
55198 +
55199 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
55200 +
55201 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
55202 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
55203 + {
55204 + p_CcParams->getCcParams.prOffset =
55205 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
55206 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
55207 + }
55208 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
55209 + {
55210 + p_CcParams->getCcParams.hardwarePortId =
55211 + (uint8_t)p_FmPort->hardwarePortId;
55212 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
55213 + }
55214 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
55215 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
55216 + {
55217 + p_CcParams->getCcParams.dataOffset =
55218 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
55219 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
55220 + }
55221 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
55222 + {
55223 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
55224 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
55225 + }
55226 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
55227 + {
55228 + p_CcParams->getCcParams.numOfExtraTasks =
55229 + (uint8_t)p_FmPort->tasks.extra;
55230 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
55231 + }
55232 + if (p_CcParams->getCcParams.type & FM_REV)
55233 + {
55234 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
55235 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
55236 + p_CcParams->getCcParams.type &= ~FM_REV;
55237 + }
55238 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
55239 + {
55240 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55241 + p_CcParams->getCcParams.discardMask =
55242 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
55243 + else
55244 + p_CcParams->getCcParams.discardMask =
55245 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
55246 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
55247 + }
55248 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
55249 + {
55250 + p_CcParams->getCcParams.internalBufferOffset =
55251 + p_FmPort->internalBufferOffset;
55252 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
55253 + }
55254 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
55255 + {
55256 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55257 + p_CcParams->getCcParams.nia =
55258 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
55259 + else
55260 + p_CcParams->getCcParams.nia =
55261 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
55262 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
55263 + }
55264 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
55265 + {
55266 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55267 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55268 + p_CcParams->getCcParams.nia =
55269 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
55270 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
55271 + }
55272 +
55273 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
55274 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
55275 + {
55276 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
55277 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
55278 + }
55279 +
55280 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
55281 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
55282 + {
55283 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
55284 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
55285 + }
55286 + else
55287 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
55288 + {
55289 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
55290 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55291 + ("PNEN was defined previously different"));
55292 + }
55293 +
55294 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
55295 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
55296 + {
55297 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
55298 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
55299 + }
55300 + else
55301 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
55302 + {
55303 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
55304 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55305 + ("PNDN was defined previously different"));
55306 + }
55307 +
55308 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
55309 + && (p_CcParams->setCcParams.overwrite
55310 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
55311 + {
55312 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
55313 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
55314 + }
55315 + else
55316 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
55317 + {
55318 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
55319 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
55320 + ("xFENE was defined previously different"));
55321 + }
55322 +
55323 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
55324 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
55325 + {
55326 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
55327 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
55328 + }
55329 + else
55330 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
55331 + {
55332 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
55333 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
55334 + ("xFPNE was defined previously different"));
55335 + }
55336 +
55337 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
55338 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
55339 + {
55340 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
55341 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
55342 + }
55343 + else
55344 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
55345 + {
55346 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
55347 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
55348 + ("xCMNE was defined previously different"));
55349 + }
55350 +
55351 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
55352 + && !(p_FmPort->requiredAction & UPDATE_PSO))
55353 + {
55354 + /* get PCD registers pointers */
55355 + switch (p_FmPort->portType)
55356 + {
55357 + case (e_FM_PORT_TYPE_RX_10G):
55358 + case (e_FM_PORT_TYPE_RX):
55359 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
55360 + break;
55361 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55362 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
55363 + break;
55364 + default:
55365 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55366 + }
55367 +
55368 + /* set start parsing offset */
55369 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
55370 + + p_CcParams->setCcParams.psoSize;
55371 + if (tmpInt > 0)
55372 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
55373 +
55374 + p_FmPort->requiredAction |= UPDATE_PSO;
55375 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
55376 + }
55377 + else
55378 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
55379 + {
55380 + if (p_FmPort->savedPrsStartOffset
55381 + != p_CcParams->setCcParams.psoSize)
55382 + RETURN_ERROR(
55383 + MAJOR,
55384 + E_INVALID_STATE,
55385 + ("parser start offset was defoned previousley different"));
55386 + }
55387 +
55388 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
55389 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
55390 + {
55391 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55392 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55393 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
55394 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
55395 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
55396 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
55397 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
55398 + }
55399 +
55400 + return E_OK;
55401 +}
55402 +/*********************** End of inter-module routines ************************/
55403 +
55404 +/****************************************/
55405 +/* API Init unit functions */
55406 +/****************************************/
55407 +
55408 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
55409 +{
55410 + t_FmPort *p_FmPort;
55411 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
55412 + uint32_t tmpReg;
55413 +
55414 + /* Allocate FM structure */
55415 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
55416 + if (!p_FmPort)
55417 + {
55418 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
55419 + return NULL;
55420 + }
55421 + memset(p_FmPort, 0, sizeof(t_FmPort));
55422 +
55423 + /* Allocate the FM driver's parameters structure */
55424 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
55425 + sizeof(t_FmPortDriverParam));
55426 + if (!p_FmPort->p_FmPortDriverParam)
55427 + {
55428 + XX_Free(p_FmPort);
55429 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
55430 + return NULL;
55431 + }
55432 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
55433 +
55434 + /* Initialize FM port parameters which will be kept by the driver */
55435 + p_FmPort->portType = p_FmPortParams->portType;
55436 + p_FmPort->portId = p_FmPortParams->portId;
55437 + p_FmPort->pcdEngines = FM_PCD_NONE;
55438 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
55439 + p_FmPort->h_App = p_FmPortParams->h_App;
55440 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
55441 +
55442 + /* get FM revision */
55443 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
55444 +
55445 + /* calculate global portId number */
55446 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
55447 + p_FmPortParams->portId,
55448 + p_FmPort->fmRevInfo.majorRev,
55449 + p_FmPort->fmRevInfo.minorRev);
55450 +
55451 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55452 + {
55453 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
55454 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
55455 + DBG(WARNING,
55456 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
55457 + FM_OH_PORT_ID));
55458 +
55459 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55460 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
55461 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
55462 + }
55463 +
55464 + /* Set up FM port parameters for initialization phase only */
55465 +
55466 + /* First, fill in flibs struct */
55467 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
55468 + (enum fman_port_type)p_FmPort->portType);
55469 + /* Overwrite some integration specific parameters */
55470 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
55471 + DEFAULT_PORT_rxFifoPriElevationLevel;
55472 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
55473 + DEFAULT_PORT_rxFifoThreshold;
55474 +
55475 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
55476 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
55477 +#else
55478 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
55479 +#endif
55480 + if ((p_FmPort->fmRevInfo.majorRev == 6)
55481 + && (p_FmPort->fmRevInfo.minorRev == 0))
55482 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
55483 + else
55484 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
55485 +
55486 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
55487 + if (p_FmPort->fmRevInfo.majorRev < 6)
55488 + {
55489 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
55490 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
55491 + TRUE;
55492 +#endif
55493 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
55494 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
55495 + }
55496 + else
55497 + {
55498 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
55499 + FALSE;
55500 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
55501 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
55502 + }
55503 + if (p_FmPort->fmRevInfo.majorRev == 4)
55504 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
55505 + else
55506 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
55507 +
55508 + /* Continue with other parameters */
55509 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
55510 + /* set memory map pointers */
55511 + p_FmPort->p_FmPortQmiRegs =
55512 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
55513 + p_FmPort->p_FmPortBmiRegs =
55514 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
55515 + p_FmPort->p_FmPortPrsRegs =
55516 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
55517 +
55518 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
55519 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
55520 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
55521 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
55522 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
55523 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
55524 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
55525 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
55526 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
55527 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
55528 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
55529 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
55530 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
55531 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
55532 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
55533 + */
55534 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
55535 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
55536 + DEFAULT_PORT_cheksumLastBytesIgnore;
55537 +
55538 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
55539 + /* resource distribution. */
55540 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
55541 + * BMI_FIFO_UNITS;
55542 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
55543 + * BMI_FIFO_UNITS;
55544 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
55545 + p_FmPort->openDmas.extra =
55546 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
55547 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
55548 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
55549 +
55550 +
55551 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
55552 + if ((p_FmPort->fmRevInfo.majorRev == 6)
55553 + && (p_FmPort->fmRevInfo.minorRev == 0)
55554 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55555 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
55556 + {
55557 + p_FmPort->openDmas.num = 16;
55558 + p_FmPort->openDmas.extra = 0;
55559 + }
55560 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
55561 +
55562 + /* Port type specific initialization: */
55563 + switch (p_FmPort->portType)
55564 + {
55565 + case (e_FM_PORT_TYPE_RX):
55566 + case (e_FM_PORT_TYPE_RX_10G):
55567 + /* Initialize FM port parameters for initialization phase only */
55568 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
55569 + DEFAULT_PORT_cutBytesFromEnd;
55570 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
55571 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
55572 + DEFAULT_PORT_frmDiscardOverride;
55573 +
55574 + tmpReg =
55575 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
55576 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
55577 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
55578 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
55579 + * BMI_FIFO_UNITS;
55580 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
55581 + & BMI_RX_FIFO_THRESHOLD_MASK)
55582 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
55583 +
55584 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
55585 + DEFAULT_PORT_BufMargins_endMargins;
55586 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
55587 + DEFAULT_PORT_errorsToDiscard;
55588 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
55589 + DEFAULT_PORT_forwardIntContextReuse;
55590 +#if (DPAA_VERSION >= 11)
55591 + p_FmPort->p_FmPortDriverParam->noScatherGather =
55592 + DEFAULT_PORT_noScatherGather;
55593 +#endif /* (DPAA_VERSION >= 11) */
55594 + break;
55595 +
55596 + case (e_FM_PORT_TYPE_TX):
55597 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
55598 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
55599 + tmpReg = 0x00001013;
55600 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
55601 + tmpReg);
55602 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
55603 + case (e_FM_PORT_TYPE_TX_10G):
55604 + tmpReg =
55605 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
55606 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
55607 + & BMI_TX_FIFO_MIN_FILL_MASK)
55608 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
55609 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55610 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
55611 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
55612 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
55613 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
55614 + * BMI_FIFO_UNITS;
55615 +
55616 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
55617 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
55618 + DEFAULT_PORT_deqPrefetchOption;
55619 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
55620 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
55621 + DEFAULT_PORT_deqHighPriority_10G);
55622 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
55623 + (uint16_t)(
55624 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
55625 + DEFAULT_PORT_deqByteCnt_10G);
55626 + break;
55627 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55628 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
55629 + DEFAULT_PORT_errorsToDiscard;
55630 +#if (DPAA_VERSION >= 11)
55631 + p_FmPort->p_FmPortDriverParam->noScatherGather =
55632 + DEFAULT_PORT_noScatherGather;
55633 +#endif /* (DPAA_VERSION >= 11) */
55634 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55635 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
55636 + DEFAULT_PORT_deqPrefetchOption_HC;
55637 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
55638 + DEFAULT_PORT_deqHighPriority_1G;
55639 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
55640 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
55641 + DEFAULT_PORT_deqByteCnt_1G;
55642 +
55643 + tmpReg =
55644 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
55645 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55646 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
55647 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
55648 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
55649 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
55650 + {
55651 + /* Overwrite HC defaults */
55652 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55653 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
55654 + }
55655 +
55656 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
55657 + if (p_FmPort->fmRevInfo.majorRev < 6)
55658 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
55659 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
55660 +
55661 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
55662 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
55663 + (p_FmPort->fmRevInfo.majorRev >= 6)))
55664 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
55665 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
55666 + break;
55667 +
55668 + default:
55669 + XX_Free(p_FmPort->p_FmPortDriverParam);
55670 + XX_Free(p_FmPort);
55671 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55672 + return NULL;
55673 + }
55674 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
55675 + if (p_FmPort->fmRevInfo.majorRev == 4)
55676 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
55677 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
55678 +
55679 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
55680 +
55681 + if (p_FmPort->imEn)
55682 + {
55683 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55684 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
55685 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55686 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
55687 + FmPortConfigIM(p_FmPort, p_FmPortParams);
55688 + }
55689 + else
55690 + {
55691 + switch (p_FmPort->portType)
55692 + {
55693 + case (e_FM_PORT_TYPE_RX):
55694 + case (e_FM_PORT_TYPE_RX_10G):
55695 + /* Initialize FM port parameters for initialization phase only */
55696 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
55697 + &p_FmPortParams->specificParams.rxParams.extBufPools,
55698 + sizeof(t_FmExtPools));
55699 + p_FmPort->p_FmPortDriverParam->errFqid =
55700 + p_FmPortParams->specificParams.rxParams.errFqid;
55701 + p_FmPort->p_FmPortDriverParam->dfltFqid =
55702 + p_FmPortParams->specificParams.rxParams.dfltFqid;
55703 + p_FmPort->p_FmPortDriverParam->liodnOffset =
55704 + p_FmPortParams->specificParams.rxParams.liodnOffset;
55705 + break;
55706 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55707 + case (e_FM_PORT_TYPE_TX):
55708 + case (e_FM_PORT_TYPE_TX_10G):
55709 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55710 + p_FmPort->p_FmPortDriverParam->errFqid =
55711 + p_FmPortParams->specificParams.nonRxParams.errFqid;
55712 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
55713 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
55714 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
55715 + p_FmPort->p_FmPortDriverParam->dfltFqid =
55716 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
55717 + break;
55718 + default:
55719 + XX_Free(p_FmPort->p_FmPortDriverParam);
55720 + XX_Free(p_FmPort);
55721 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55722 + return NULL;
55723 + }
55724 + }
55725 +
55726 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
55727 + if (Sprint(
55728 + p_FmPort->name,
55729 + "FM-%d-port-%s-%d",
55730 + FmGetId(p_FmPort->h_Fm),
55731 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
55732 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
55733 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
55734 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
55735 + (p_FmPort->portType
55736 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
55737 + "10g-TX")))),
55738 + p_FmPort->portId) == 0)
55739 + {
55740 + XX_Free(p_FmPort->p_FmPortDriverParam);
55741 + XX_Free(p_FmPort);
55742 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
55743 + return NULL;
55744 + }
55745 +
55746 + p_FmPort->h_Spinlock = XX_InitSpinlock();
55747 + if (!p_FmPort->h_Spinlock)
55748 + {
55749 + XX_Free(p_FmPort->p_FmPortDriverParam);
55750 + XX_Free(p_FmPort);
55751 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
55752 + return NULL;
55753 + }
55754 +
55755 + return p_FmPort;
55756 +}
55757 +
55758 +t_FmPort *rx_port = 0;
55759 +t_FmPort *tx_port = 0;
55760 +
55761 +/**************************************************************************//**
55762 + @Function FM_PORT_Init
55763 +
55764 + @Description Initializes the FM module
55765 +
55766 + @Param[in] h_FmPort - FM module descriptor
55767 +
55768 + @Return E_OK on success; Error code otherwise.
55769 + *//***************************************************************************/
55770 +t_Error FM_PORT_Init(t_Handle h_FmPort)
55771 +{
55772 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55773 + t_FmPortDriverParam *p_DriverParams;
55774 + t_Error errCode;
55775 + t_FmInterModulePortInitParams fmParams;
55776 + t_FmRevisionInfo revInfo;
55777 +
55778 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
55779 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55780 +
55781 + errCode = FmSpBuildBufferStructure(
55782 + &p_FmPort->p_FmPortDriverParam->intContext,
55783 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
55784 + &p_FmPort->p_FmPortDriverParam->bufMargins,
55785 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
55786 + if (errCode != E_OK)
55787 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
55788 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
55789 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
55790 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
55791 + {
55792 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
55793 + if (!p_FmPort->fifoBufs.num)
55794 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
55795 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
55796 + }
55797 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
55798 +
55799 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
55800 +
55801 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
55802 +
55803 + /* Set up flibs port structure */
55804 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
55805 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
55806 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
55807 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
55808 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
55809 + p_FmPort->port.bmi_regs =
55810 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
55811 + p_FmPort->port.qmi_regs =
55812 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
55813 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
55814 + p_FmPort->port.im_en = p_FmPort->imEn;
55815 + p_FmPort->p_FmPortPrsRegs =
55816 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
55817 +
55818 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55819 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
55820 + {
55821 + /* Call the external Buffer routine which also checks fifo
55822 + size and updates it if necessary */
55823 + /* define external buffer pools and pool depletion*/
55824 + errCode = SetExtBufferPools(p_FmPort);
55825 + if (errCode)
55826 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
55827 + /* check if the largest external buffer pool is large enough */
55828 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
55829 + + p_DriverParams->bufMargins.endMargins
55830 + > p_FmPort->rxPoolsParams.largestBufSize)
55831 + RETURN_ERROR(
55832 + MAJOR,
55833 + E_INVALID_VALUE,
55834 + ("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));
55835 + }
55836 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55837 + {
55838 + {
55839 +#ifdef FM_NO_OP_OBSERVED_POOLS
55840 + t_FmRevisionInfo revInfo;
55841 +
55842 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
55843 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
55844 +#endif /* FM_NO_OP_OBSERVED_POOLS */
55845 + {
55846 + /* define external buffer pools */
55847 + errCode = SetExtBufferPools(p_FmPort);
55848 + if (errCode)
55849 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
55850 + }
55851 + }
55852 + }
55853 +
55854 + /************************************************************/
55855 + /* Call FM module routine for communicating parameters */
55856 + /************************************************************/
55857 + memset(&fmParams, 0, sizeof(fmParams));
55858 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
55859 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
55860 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
55861 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
55862 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
55863 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
55864 +
55865 + if (p_FmPort->fifoBufs.num)
55866 + {
55867 + errCode = VerifySizeOfFifo(p_FmPort);
55868 + if (errCode != E_OK)
55869 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
55870 + }
55871 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
55872 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
55873 + fmParams.independentMode = p_FmPort->imEn;
55874 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
55875 + fmParams.liodnBase = p_DriverParams->liodnBase;
55876 + fmParams.deqPipelineDepth =
55877 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
55878 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
55879 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
55880 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
55881 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55882 + {
55883 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
55884 + (p_FmPort->fmRevInfo.majorRev >= 6)))
55885 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
55886 + * for deq threshold calculation.
55887 + */
55888 + fmParams.deqPipelineDepth = 2;
55889 + }
55890 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
55891 +
55892 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
55893 + if (errCode)
55894 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
55895 +
55896 + /* get params for use in init */
55897 + p_FmPort->fmMuramPhysBaseAddr =
55898 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
55899 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
55900 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
55901 +
55902 + errCode = InitLowLevelDriver(p_FmPort);
55903 + if (errCode != E_OK)
55904 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
55905 +
55906 + FmPortDriverParamFree(p_FmPort);
55907 +
55908 +#if (DPAA_VERSION >= 11)
55909 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55910 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55911 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
55912 + {
55913 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55914 +
55915 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55916 + (void**)&p_ParamsPage);
55917 + ASSERT_COND(p_ParamsPage);
55918 +
55919 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
55920 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
55921 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55922 + {
55923 + WRITE_UINT32(
55924 + p_ParamsPage->misc,
55925 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
55926 + WRITE_UINT32(
55927 + p_ParamsPage->discardMask,
55928 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
55929 + }
55930 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
55931 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55932 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55933 + WRITE_UINT32(
55934 + p_ParamsPage->errorsDiscardMask,
55935 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
55936 + else
55937 + WRITE_UINT32(
55938 + p_ParamsPage->errorsDiscardMask,
55939 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
55940 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55941 + }
55942 +#endif /* (DPAA_VERSION >= 11) */
55943 +
55944 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
55945 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
55946 + return E_OK;
55947 +}
55948 +
55949 +/**************************************************************************//**
55950 + @Function FM_PORT_Free
55951 +
55952 + @Description Frees all resources that were assigned to FM module.
55953 +
55954 + Calling this routine invalidates the descriptor.
55955 +
55956 + @Param[in] h_FmPort - FM module descriptor
55957 +
55958 + @Return E_OK on success; Error code otherwise.
55959 + *//***************************************************************************/
55960 +t_Error FM_PORT_Free(t_Handle h_FmPort)
55961 +{
55962 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55963 + t_FmInterModulePortFreeParams fmParams;
55964 +
55965 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55966 +
55967 + if (p_FmPort->pcdEngines)
55968 + RETURN_ERROR(
55969 + MAJOR,
55970 + E_INVALID_STATE,
55971 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
55972 +
55973 + if (p_FmPort->enabled)
55974 + {
55975 + if (FM_PORT_Disable(p_FmPort) != E_OK)
55976 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
55977 + }
55978 +
55979 + if (p_FmPort->imEn)
55980 + FmPortImFree(p_FmPort);
55981 +
55982 + FmPortDriverParamFree(p_FmPort);
55983 +
55984 + memset(&fmParams, 0, sizeof(fmParams));
55985 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
55986 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
55987 + fmParams.deqPipelineDepth =
55988 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
55989 +
55990 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
55991 +
55992 +#if (DPAA_VERSION >= 11)
55993 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
55994 + != E_OK)
55995 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
55996 +
55997 + if (p_FmPort->p_ParamsPage)
55998 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
55999 +#endif /* (DPAA_VERSION >= 11) */
56000 +
56001 + if (p_FmPort->h_Spinlock)
56002 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
56003 +
56004 + XX_Free(p_FmPort);
56005 +
56006 + return E_OK;
56007 +}
56008 +
56009 +/*************************************************/
56010 +/* API Advanced Init unit functions */
56011 +/*************************************************/
56012 +
56013 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
56014 +{
56015 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56016 +
56017 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56018 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56019 +
56020 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
56021 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
56022 +
56023 + return E_OK;
56024 +}
56025 +
56026 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
56027 +{
56028 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56029 +
56030 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56031 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56032 +
56033 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
56034 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
56035 + return E_OK;
56036 +}
56037 +
56038 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
56039 +{
56040 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56041 +
56042 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56043 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56044 +
56045 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
56046 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
56047 +
56048 + return E_OK;
56049 +}
56050 +
56051 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
56052 +{
56053 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56054 +
56055 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56056 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56057 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56058 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56059 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
56060 +
56061 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
56062 +
56063 + return E_OK;
56064 +}
56065 +
56066 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
56067 +{
56068 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56069 +
56070 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56071 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56072 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56073 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56074 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56075 + ("not available for Rx ports"));
56076 +
56077 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
56078 + (enum fman_port_deq_type)deqType;
56079 +
56080 + return E_OK;
56081 +}
56082 +
56083 +t_Error FM_PORT_ConfigDeqPrefetchOption(
56084 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
56085 +{
56086 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56087 +
56088 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56089 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56090 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56091 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56092 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56093 + ("not available for Rx ports"));
56094 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
56095 + (enum fman_port_deq_prefetch)deqPrefetchOption;
56096 +
56097 + return E_OK;
56098 +}
56099 +
56100 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
56101 + t_FmBackupBmPools *p_BackupBmPools)
56102 +{
56103 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56104 +
56105 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56106 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56107 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56108 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56109 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56110 + ("available for Rx ports only"));
56111 +
56112 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
56113 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
56114 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
56115 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
56116 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
56117 + sizeof(t_FmBackupBmPools));
56118 +
56119 + return E_OK;
56120 +}
56121 +
56122 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
56123 +{
56124 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56125 +
56126 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56127 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56128 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56129 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56130 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56131 + ("not available for Rx ports"));
56132 +
56133 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
56134 +
56135 + return E_OK;
56136 +}
56137 +
56138 +t_Error FM_PORT_ConfigBufferPrefixContent(
56139 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
56140 +{
56141 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56142 +
56143 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56144 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56145 +
56146 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
56147 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
56148 + /* if dataAlign was not initialized by user, we return to driver's default */
56149 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
56150 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
56151 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
56152 +
56153 + return E_OK;
56154 +}
56155 +
56156 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
56157 + uint8_t checksumLastBytesIgnore)
56158 +{
56159 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56160 +
56161 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56162 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56163 +
56164 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
56165 + checksumLastBytesIgnore;
56166 +
56167 + return E_OK;
56168 +}
56169 +
56170 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
56171 + uint8_t cutBytesFromEnd)
56172 +{
56173 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56174 +
56175 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56176 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56177 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56178 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56179 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56180 + ("available for Rx ports only"));
56181 +
56182 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
56183 +
56184 + return E_OK;
56185 +}
56186 +
56187 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
56188 + t_FmBufPoolDepletion *p_BufPoolDepletion)
56189 +{
56190 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56191 +
56192 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56193 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56194 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56195 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56196 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56197 + ("available for Rx ports only"));
56198 +
56199 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
56200 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
56201 + sizeof(t_FmBufPoolDepletion));
56202 +
56203 + return E_OK;
56204 +}
56205 +
56206 +t_Error FM_PORT_ConfigObservedPoolDepletion(
56207 + t_Handle h_FmPort,
56208 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
56209 +{
56210 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56211 +
56212 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56213 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56214 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56215 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56216 + ("available for OP ports only"));
56217 +
56218 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
56219 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
56220 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
56221 + sizeof(t_FmBufPoolDepletion));
56222 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
56223 + &p_FmPortObservedBufPoolDepletion->poolsParams,
56224 + sizeof(t_FmExtPools));
56225 +
56226 + return E_OK;
56227 +}
56228 +
56229 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
56230 +{
56231 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56232 +
56233 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56234 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56235 +
56236 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56237 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56238 + ("available for OP ports only"));
56239 +
56240 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
56241 + sizeof(t_FmExtPools));
56242 +
56243 + return E_OK;
56244 +}
56245 +
56246 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
56247 +{
56248 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56249 +
56250 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56251 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56252 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
56253 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
56254 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56255 + ("available for Tx ports only"));
56256 +
56257 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
56258 +
56259 + return E_OK;
56260 +}
56261 +
56262 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
56263 +{
56264 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56265 +
56266 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56267 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56268 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
56269 +
56270 + return E_OK;
56271 +}
56272 +
56273 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
56274 +{
56275 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56276 +
56277 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56278 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56279 +
56280 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
56281 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
56282 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56283 + ("Not available for Tx ports"));
56284 +
56285 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
56286 +
56287 + return E_OK;
56288 +}
56289 +
56290 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
56291 +{
56292 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56293 +
56294 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56295 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56296 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
56297 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
56298 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56299 + ("Not available for Tx ports"));
56300 +
56301 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
56302 +
56303 + return E_OK;
56304 +}
56305 +
56306 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
56307 + fmPortFrameErrSelect_t errs)
56308 +{
56309 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56310 +
56311 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56312 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56313 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56314 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56315 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56316 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56317 + ("available for Rx and offline parsing ports only"));
56318 +
56319 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
56320 +
56321 + return E_OK;
56322 +}
56323 +
56324 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
56325 +{
56326 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56327 +
56328 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56329 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56330 +
56331 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
56332 + (enum fman_port_dma_swap)swapData;
56333 +
56334 + return E_OK;
56335 +}
56336 +
56337 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
56338 + e_FmDmaCacheOption intContextCacheAttr)
56339 +{
56340 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56341 +
56342 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56343 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56344 +
56345 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
56346 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
56347 +
56348 + return E_OK;
56349 +}
56350 +
56351 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
56352 + e_FmDmaCacheOption headerCacheAttr)
56353 +{
56354 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56355 +
56356 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56357 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56358 +
56359 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
56360 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
56361 +
56362 + return E_OK;
56363 +}
56364 +
56365 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
56366 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
56367 +{
56368 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56369 +
56370 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56371 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56372 +
56373 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
56374 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
56375 +
56376 + return E_OK;
56377 +}
56378 +
56379 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
56380 +{
56381 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56382 +
56383 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56384 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56385 +
56386 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
56387 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
56388 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56389 + ("Not available for Tx ports"));
56390 +
56391 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
56392 +
56393 + return E_OK;
56394 +}
56395 +
56396 +#if (DPAA_VERSION >= 11)
56397 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
56398 +{
56399 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56400 +
56401 + UNUSED(noScatherGather);
56402 + UNUSED(p_FmPort);
56403 +
56404 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56405 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56406 +
56407 + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
56408 +
56409 + return E_OK;
56410 +}
56411 +#endif /* (DPAA_VERSION >= 11) */
56412 +
56413 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
56414 + bool forwardReuse)
56415 +{
56416 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56417 +
56418 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56419 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56420 +
56421 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56422 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56423 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56424 + ("available for Rx ports only"));
56425 +
56426 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
56427 +
56428 + return E_OK;
56429 +}
56430 +
56431 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
56432 +{
56433 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56434 +
56435 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56436 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56437 +
56438 + p_FmPort->maxFrameLength = length;
56439 +
56440 + return E_OK;
56441 +}
56442 +
56443 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
56444 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
56445 +{
56446 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56447 +
56448 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56449 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56450 +
56451 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
56452 +
56453 + return E_OK;
56454 +}
56455 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
56456 +
56457 +/****************************************************/
56458 +/* Hidden-DEBUG Only API */
56459 +/****************************************************/
56460 +
56461 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
56462 + uint32_t minFillLevel)
56463 +{
56464 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56465 +
56466 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56467 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56468 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
56469 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
56470 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56471 + ("available for Tx ports only"));
56472 +
56473 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
56474 +
56475 + return E_OK;
56476 +}
56477 +
56478 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
56479 + uint8_t deqPipelineDepth)
56480 +{
56481 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56482 +
56483 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56484 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56485 +
56486 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56487 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56488 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56489 + ("Not available for Rx ports"));
56490 +
56491 + if (p_FmPort->imEn)
56492 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56493 + ("Not available for IM ports!"));
56494 +
56495 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
56496 + deqPipelineDepth;
56497 +
56498 + return E_OK;
56499 +}
56500 +
56501 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
56502 + uint32_t fifoLowComfLevel)
56503 +{
56504 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56505 +
56506 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56507 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56508 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
56509 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
56510 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56511 + ("available for Tx ports only"));
56512 +
56513 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
56514 + fifoLowComfLevel;
56515 +
56516 + return E_OK;
56517 +}
56518 +
56519 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
56520 +{
56521 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56522 +
56523 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56524 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56525 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56526 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56527 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56528 + ("available for Rx ports only"));
56529 +
56530 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
56531 +
56532 + return E_OK;
56533 +}
56534 +
56535 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
56536 + uint32_t priElevationLevel)
56537 +{
56538 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56539 +
56540 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56541 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56542 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56543 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56544 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56545 + ("available for Rx ports only"));
56546 +
56547 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
56548 +
56549 + return E_OK;
56550 +}
56551 +/****************************************************/
56552 +/* API Run-time Control unit functions */
56553 +/****************************************************/
56554 +
56555 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
56556 + t_FmPortRsrc *p_NumOfOpenDmas)
56557 +{
56558 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56559 + t_Error err;
56560 +
56561 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56562 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56563 +
56564 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
56565 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
56566 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
56567 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
56568 + RETURN_ERROR(
56569 + MAJOR,
56570 + E_INVALID_VALUE,
56571 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
56572 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
56573 + (uint8_t*)&p_NumOfOpenDmas->num,
56574 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
56575 + if (err)
56576 + RETURN_ERROR(MAJOR, err, NO_MSG);
56577 +
56578 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
56579 +
56580 + return E_OK;
56581 +}
56582 +
56583 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
56584 +{
56585 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56586 + t_Error err;
56587 +
56588 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56589 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56590 +
56591 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
56592 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
56593 +
56594 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
56595 + RETURN_ERROR(
56596 + MAJOR, E_INVALID_VALUE,
56597 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
56598 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
56599 + RETURN_ERROR(
56600 + MAJOR,
56601 + E_INVALID_VALUE,
56602 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
56603 +
56604 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
56605 + (uint8_t*)&p_NumOfTasks->num,
56606 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
56607 + if (err)
56608 + RETURN_ERROR(MAJOR, err, NO_MSG);
56609 +
56610 + /* update driver's struct */
56611 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
56612 + return E_OK;
56613 +}
56614 +
56615 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
56616 +{
56617 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56618 + t_Error err;
56619 +
56620 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56621 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56622 +
56623 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
56624 + RETURN_ERROR(
56625 + MAJOR,
56626 + E_INVALID_VALUE,
56627 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
56628 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
56629 + RETURN_ERROR(
56630 + MAJOR, E_INVALID_VALUE,
56631 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
56632 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56633 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56634 + {
56635 + /* extra FIFO size (allowed only to Rx ports) */
56636 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
56637 + RETURN_ERROR(
56638 + MAJOR,
56639 + E_INVALID_VALUE,
56640 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
56641 + }
56642 + else
56643 + if (p_SizeOfFifo->extra)
56644 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
56645 + (" No SizeOfFifo-extra for non Rx ports"));
56646 +
56647 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
56648 +
56649 + /* we do not change user's parameter */
56650 + err = VerifySizeOfFifo(p_FmPort);
56651 + if (err)
56652 + RETURN_ERROR(MAJOR, err, NO_MSG);
56653 +
56654 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
56655 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
56656 + if (err)
56657 + RETURN_ERROR(MAJOR, err, NO_MSG);
56658 +
56659 + return E_OK;
56660 +}
56661 +
56662 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
56663 +{
56664 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56665 +
56666 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56667 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56668 + 0);
56669 +
56670 + return p_FmPort->bufferOffsets.dataOffset;
56671 +}
56672 +
56673 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
56674 +{
56675 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56676 +
56677 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
56678 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56679 + NULL);
56680 +
56681 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
56682 + return NULL;
56683 +
56684 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
56685 +}
56686 +
56687 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
56688 +{
56689 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56690 +
56691 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
56692 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56693 + NULL);
56694 +
56695 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
56696 + return NULL;
56697 +
56698 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
56699 +}
56700 +
56701 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
56702 +{
56703 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56704 +
56705 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
56706 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56707 + NULL);
56708 +
56709 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
56710 + return NULL;
56711 +
56712 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
56713 +}
56714 +
56715 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
56716 +{
56717 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56718 +
56719 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
56720 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56721 + NULL);
56722 +
56723 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
56724 + return NULL;
56725 +
56726 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
56727 +}
56728 +
56729 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
56730 +{
56731 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56732 + int err;
56733 +
56734 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56735 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56736 +
56737 + if (p_FmPort->imEn)
56738 + FmPortImDisable(p_FmPort);
56739 +
56740 + err = fman_port_disable(&p_FmPort->port);
56741 + if (err == -EBUSY)
56742 + {
56743 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
56744 + p_FmPort->name));
56745 + }
56746 + else
56747 + if (err != 0)
56748 + {
56749 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
56750 + }
56751 +
56752 + p_FmPort->enabled = FALSE;
56753 +
56754 + return E_OK;
56755 +}
56756 +
56757 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
56758 +{
56759 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56760 + int err;
56761 +
56762 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56763 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56764 +
56765 + /* Used by FM_PORT_Free routine as indication
56766 + if to disable port. Thus set it to TRUE prior
56767 + to enabling itself. This way if part of enable
56768 + process fails there will be still things
56769 + to disable during Free. For example, if BMI
56770 + enable succeeded but QMI failed, still BMI
56771 + needs to be disabled by Free. */
56772 + p_FmPort->enabled = TRUE;
56773 +
56774 + if (p_FmPort->imEn)
56775 + FmPortImEnable(p_FmPort);
56776 +
56777 + err = fman_port_enable(&p_FmPort->port);
56778 + if (err != 0)
56779 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
56780 +
56781 + return E_OK;
56782 +}
56783 +
56784 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
56785 +{
56786 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56787 + uint8_t factor, countUnitBit;
56788 + uint16_t baseGran;
56789 + struct fman_port_rate_limiter params;
56790 + int err;
56791 +
56792 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56793 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56794 +
56795 + switch (p_FmPort->portType)
56796 + {
56797 + case (e_FM_PORT_TYPE_TX_10G):
56798 + case (e_FM_PORT_TYPE_TX):
56799 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
56800 + break;
56801 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56802 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
56803 + break;
56804 + default:
56805 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56806 + ("available for Tx and Offline parsing ports only"));
56807 + }
56808 +
56809 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
56810 + /* normally, we use 1 usec as the reference count */
56811 + factor = 1;
56812 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
56813 + while (p_RateLimit->rateLimit < baseGran / factor)
56814 + {
56815 + if (countUnitBit == 31)
56816 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
56817 +
56818 + countUnitBit++;
56819 + factor <<= 1;
56820 + }
56821 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
56822 + if (p_RateLimit->rateLimit
56823 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
56824 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
56825 +
56826 + if (!p_RateLimit->maxBurstSize
56827 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
56828 + RETURN_ERROR(
56829 + MAJOR,
56830 + E_INVALID_VALUE,
56831 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
56832 +
56833 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
56834 + params.high_burst_size_gran = FALSE;
56835 + params.burst_size = p_RateLimit->maxBurstSize;
56836 + params.rate = p_RateLimit->rateLimit;
56837 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
56838 +
56839 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56840 + {
56841 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
56842 +
56843 + if ((p_FmPort->fmRevInfo.majorRev == 4)
56844 + || (p_FmPort->fmRevInfo.majorRev >= 6))
56845 + {
56846 + params.high_burst_size_gran = TRUE;
56847 + }
56848 + else
56849 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
56850 + {
56851 + if (p_RateLimit->rateLimitDivider
56852 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
56853 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
56854 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
56855 +
56856 + if (p_RateLimit->maxBurstSize % 1000)
56857 + {
56858 + p_RateLimit->maxBurstSize =
56859 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
56860 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
56861 + }
56862 + else
56863 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
56864 + / 1000);
56865 + }
56866 + params.rate_factor =
56867 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
56868 + params.burst_size = p_RateLimit->maxBurstSize;
56869 + }
56870 +
56871 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
56872 + if (err != 0)
56873 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
56874 +
56875 + return E_OK;
56876 +}
56877 +
56878 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
56879 +{
56880 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56881 + int err;
56882 +
56883 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56884 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56885 +
56886 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56887 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
56888 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
56889 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56890 + ("available for Tx and Offline parsing ports only"));
56891 +
56892 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
56893 + if (err != 0)
56894 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
56895 + return E_OK;
56896 +}
56897 +
56898 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
56899 + uint8_t wq)
56900 +{
56901 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56902 + uint32_t tmpReg;
56903 + uint32_t wqTmpReg;
56904 +
56905 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56906 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56907 +
56908 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
56909 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
56910 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56911 + ("PFC mapping is available for Tx ports only"));
56912 +
56913 + if (prio > 7)
56914 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56915 + ("PFC priority (%d) is out of range (0-7)", prio));
56916 + if (wq > 7)
56917 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56918 + ("WQ (%d) is out of range (0-7)", wq));
56919 +
56920 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
56921 + tmpReg &= ~(0xf << ((7 - prio) * 4));
56922 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
56923 + tmpReg |= wqTmpReg;
56924 +
56925 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
56926 + tmpReg);
56927 +
56928 + return E_OK;
56929 +}
56930 +
56931 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
56932 +{
56933 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56934 +
56935 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56936 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56937 +
56938 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
56939 +
56940 + return E_OK;
56941 +}
56942 +
56943 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
56944 +{
56945 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56946 + int err;
56947 +
56948 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56949 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56950 +
56951 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
56952 + if (err != 0)
56953 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
56954 + return E_OK;
56955 +}
56956 +
56957 +t_Error FM_PORT_SetPerformanceCountersParams(
56958 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
56959 +{
56960 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56961 + struct fman_port_perf_cnt_params params;
56962 + int err;
56963 +
56964 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56965 +
56966 + /* check parameters */
56967 + if (!p_FmPortPerformanceCnt->taskCompVal
56968 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
56969 + RETURN_ERROR(
56970 + MAJOR,
56971 + E_INVALID_VALUE,
56972 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
56973 + if (!p_FmPortPerformanceCnt->dmaCompVal
56974 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
56975 + RETURN_ERROR(
56976 + MAJOR,
56977 + E_INVALID_VALUE,
56978 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
56979 + if (!p_FmPortPerformanceCnt->fifoCompVal
56980 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
56981 + RETURN_ERROR(
56982 + MAJOR,
56983 + E_INVALID_VALUE,
56984 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
56985 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
56986 + RETURN_ERROR(
56987 + MAJOR,
56988 + E_INVALID_VALUE,
56989 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
56990 +
56991 + switch (p_FmPort->portType)
56992 + {
56993 + case (e_FM_PORT_TYPE_RX_10G):
56994 + case (e_FM_PORT_TYPE_RX):
56995 + if (!p_FmPortPerformanceCnt->queueCompVal
56996 + || (p_FmPortPerformanceCnt->queueCompVal
56997 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
56998 + RETURN_ERROR(
56999 + MAJOR,
57000 + E_INVALID_VALUE,
57001 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
57002 + break;
57003 + case (e_FM_PORT_TYPE_TX_10G):
57004 + case (e_FM_PORT_TYPE_TX):
57005 + if (!p_FmPortPerformanceCnt->queueCompVal
57006 + || (p_FmPortPerformanceCnt->queueCompVal
57007 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
57008 + RETURN_ERROR(
57009 + MAJOR,
57010 + E_INVALID_VALUE,
57011 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
57012 + break;
57013 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57014 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
57015 + if (p_FmPortPerformanceCnt->queueCompVal)
57016 + RETURN_ERROR(
57017 + MAJOR,
57018 + E_INVALID_VALUE,
57019 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
57020 + break;
57021 + default:
57022 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
57023 + }
57024 +
57025 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
57026 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
57027 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
57028 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
57029 +
57030 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
57031 + if (err != 0)
57032 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
57033 +
57034 + return E_OK;
57035 +}
57036 +
57037 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
57038 +{
57039 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57040 + t_FmPortPerformanceCnt currParams, savedParams;
57041 + t_Error err;
57042 + bool underTest, failed = FALSE;
57043 +
57044 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57045 +
57046 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
57047 + p_FmPort->portType, p_FmPort->portId);
57048 +
57049 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
57050 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
57051 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
57052 + currParams.queueCompVal = 0;
57053 + else
57054 + currParams.queueCompVal = 1;
57055 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
57056 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
57057 +
57058 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
57059 + ClearPerfCnts(p_FmPort);
57060 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
57061 + != E_OK)
57062 + RETURN_ERROR(MAJOR, err, NO_MSG);
57063 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
57064 + XX_UDelay(1000000);
57065 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
57066 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
57067 + {
57068 + XX_Print(
57069 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
57070 + p_FmPort->tasks.num);
57071 + failed = TRUE;
57072 + }
57073 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
57074 + {
57075 + XX_Print(
57076 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
57077 + p_FmPort->openDmas.num);
57078 + failed = TRUE;
57079 + }
57080 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
57081 + {
57082 + XX_Print(
57083 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
57084 + p_FmPort->fifoBufs.num);
57085 + failed = TRUE;
57086 + }
57087 + if (failed)
57088 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
57089 +
57090 + memset(&savedParams, 0, sizeof(savedParams));
57091 + while (TRUE)
57092 + {
57093 + underTest = FALSE;
57094 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
57095 + {
57096 + currParams.taskCompVal--;
57097 + underTest = TRUE;
57098 + }
57099 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
57100 + {
57101 + currParams.dmaCompVal--;
57102 + underTest = TRUE;
57103 + }
57104 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
57105 + && !savedParams.fifoCompVal)
57106 + {
57107 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
57108 + underTest = TRUE;
57109 + }
57110 + if (!underTest)
57111 + break;
57112 +
57113 + ClearPerfCnts(p_FmPort);
57114 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
57115 + != E_OK)
57116 + RETURN_ERROR(MAJOR, err, NO_MSG);
57117 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
57118 + XX_UDelay(1000000);
57119 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
57120 +
57121 + if (!savedParams.taskCompVal
57122 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
57123 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
57124 + if (!savedParams.dmaCompVal
57125 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
57126 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
57127 + if (!savedParams.fifoCompVal
57128 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
57129 + savedParams.fifoCompVal = currParams.fifoCompVal
57130 + + (2 * BMI_FIFO_UNITS);
57131 + }
57132 +
57133 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
57134 + savedParams.taskCompVal, savedParams.dmaCompVal,
57135 + savedParams.fifoCompVal);
57136 + return E_OK;
57137 +}
57138 +
57139 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
57140 +{
57141 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57142 + int err;
57143 +
57144 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57145 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57146 +
57147 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
57148 + if (err != 0)
57149 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
57150 + return E_OK;
57151 +}
57152 +
57153 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
57154 +{
57155 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57156 + volatile uint32_t *p_ErrDiscard = NULL;
57157 + int err;
57158 +
57159 + UNUSED(p_ErrDiscard);
57160 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
57161 + if (err != 0)
57162 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
57163 +
57164 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
57165 + if (p_FmPort->fmRevInfo.majorRev >= 6)
57166 + {
57167 + t_FmPcdCtrlParamsPage *p_ParamsPage;
57168 +
57169 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
57170 + (void**)&p_ParamsPage);
57171 + ASSERT_COND(p_ParamsPage);
57172 + switch (p_FmPort->portType)
57173 + {
57174 + case (e_FM_PORT_TYPE_RX_10G):
57175 + case (e_FM_PORT_TYPE_RX):
57176 + p_ErrDiscard =
57177 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
57178 + break;
57179 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57180 + p_ErrDiscard =
57181 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
57182 + break;
57183 + default:
57184 + RETURN_ERROR(
57185 + MAJOR, E_INVALID_OPERATION,
57186 + ("available for Rx and offline parsing ports only"));
57187 + }
57188 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
57189 + GET_UINT32(*p_ErrDiscard) | errs);
57190 + }
57191 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
57192 +
57193 + return E_OK;
57194 +}
57195 +
57196 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
57197 + bool enable)
57198 +{
57199 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57200 + int err;
57201 +
57202 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57203 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
57204 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57205 +
57206 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57207 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57208 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57209 + ("available for Rx ports only"));
57210 +
57211 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
57212 + if (err != 0)
57213 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
57214 + return E_OK;
57215 +}
57216 +
57217 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
57218 +{
57219 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57220 +
57221 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
57222 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
57223 + p_BmiStats->cntCycle =
57224 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
57225 + /* fmbm_rccn */
57226 + p_BmiStats->cntTaskUtil =
57227 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
57228 + /* fmbm_rtuc */
57229 + p_BmiStats->cntQueueUtil =
57230 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
57231 + /* fmbm_rrquc */
57232 + p_BmiStats->cntDmaUtil =
57233 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
57234 + /* fmbm_rduc */
57235 + p_BmiStats->cntFifoUtil =
57236 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
57237 + /* fmbm_rfuc */
57238 + p_BmiStats->cntRxPauseActivation =
57239 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
57240 + /* fmbm_rpac */
57241 + p_BmiStats->cntFrame =
57242 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
57243 + /* fmbm_rfrc */
57244 + p_BmiStats->cntDiscardFrame =
57245 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
57246 + /* fmbm_rfdc */
57247 + p_BmiStats->cntDeallocBuf =
57248 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
57249 + /* fmbm_rbdc */
57250 + p_BmiStats->cntRxBadFrame =
57251 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
57252 + /* fmbm_rfbc */
57253 + p_BmiStats->cntRxLargeFrame =
57254 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
57255 + /* fmbm_rlfc */
57256 + p_BmiStats->cntRxFilterFrame =
57257 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
57258 + /* fmbm_rffc */
57259 + p_BmiStats->cntRxListDmaErr =
57260 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
57261 + /* fmbm_rfldec */
57262 + p_BmiStats->cntRxOutOfBuffersDiscard =
57263 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
57264 + /* fmbm_rodc */
57265 + p_BmiStats->cntWredDiscard = 0;
57266 + p_BmiStats->cntLengthErr = 0;
57267 + p_BmiStats->cntUnsupportedFormat = 0;
57268 + }
57269 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
57270 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
57271 + p_BmiStats->cntCycle =
57272 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
57273 + /* fmbm_tccn */
57274 + p_BmiStats->cntTaskUtil =
57275 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
57276 + /* fmbm_ttuc */
57277 + p_BmiStats->cntQueueUtil =
57278 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
57279 + /* fmbm_ttcquc */
57280 + p_BmiStats->cntDmaUtil =
57281 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
57282 + /* fmbm_tduc */
57283 + p_BmiStats->cntFifoUtil =
57284 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
57285 + /* fmbm_tfuc */
57286 + p_BmiStats->cntRxPauseActivation = 0;
57287 + p_BmiStats->cntFrame =
57288 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
57289 + /* fmbm_tfrc */
57290 + p_BmiStats->cntDiscardFrame =
57291 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
57292 + /* fmbm_tfdc */
57293 + p_BmiStats->cntDeallocBuf =
57294 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
57295 + /* fmbm_tbdc */
57296 + p_BmiStats->cntRxBadFrame = 0;
57297 + p_BmiStats->cntRxLargeFrame = 0;
57298 + p_BmiStats->cntRxFilterFrame = 0;
57299 + p_BmiStats->cntRxListDmaErr = 0;
57300 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
57301 + p_BmiStats->cntWredDiscard = 0;
57302 + p_BmiStats->cntLengthErr =
57303 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
57304 + /* fmbm_tfledc */
57305 + p_BmiStats->cntUnsupportedFormat =
57306 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
57307 + /* fmbm_tfufdc */
57308 + }
57309 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
57310 + p_BmiStats->cntCycle =
57311 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
57312 + /* fmbm_occn */
57313 + p_BmiStats->cntTaskUtil =
57314 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
57315 + /* fmbm_otuc */
57316 + p_BmiStats->cntQueueUtil = 0;
57317 + p_BmiStats->cntDmaUtil =
57318 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
57319 + /* fmbm_oduc */
57320 + p_BmiStats->cntFifoUtil =
57321 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
57322 + /* fmbm_ofuc*/
57323 + p_BmiStats->cntRxPauseActivation = 0;
57324 + p_BmiStats->cntFrame =
57325 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
57326 + /* fmbm_ofrc */
57327 + p_BmiStats->cntDiscardFrame =
57328 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
57329 + /* fmbm_ofdc */
57330 + p_BmiStats->cntDeallocBuf =
57331 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
57332 + /* fmbm_obdc*/
57333 + p_BmiStats->cntRxBadFrame = 0;
57334 + p_BmiStats->cntRxLargeFrame = 0;
57335 + p_BmiStats->cntRxFilterFrame =
57336 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
57337 + /* fmbm_offc */
57338 + p_BmiStats->cntRxListDmaErr =
57339 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
57340 + /* fmbm_ofldec */
57341 + p_BmiStats->cntRxOutOfBuffersDiscard =
57342 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
57343 + /* fmbm_rodc */
57344 + p_BmiStats->cntWredDiscard =
57345 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
57346 + /* fmbm_ofwdc */
57347 + p_BmiStats->cntLengthErr =
57348 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
57349 + /* fmbm_ofledc */
57350 + p_BmiStats->cntUnsupportedFormat =
57351 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
57352 + /* fmbm_ofufdc */
57353 + }
57354 + return E_OK;
57355 +}
57356 +
57357 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
57358 +{
57359 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57360 + bool bmiCounter = FALSE;
57361 + enum fman_port_stats_counters statsType;
57362 + enum fman_port_perf_counters perfType;
57363 + enum fman_port_qmi_counters queueType;
57364 + bool isStats;
57365 + t_Error errCode;
57366 +
57367 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
57368 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57369 +
57370 + switch (counter)
57371 + {
57372 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57373 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57374 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57375 + /* check that counter is available for the port type */
57376 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
57377 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57378 + {
57379 + REPORT_ERROR(MINOR, E_INVALID_STATE,
57380 + ("Requested counter is not available for Rx ports"));
57381 + return 0;
57382 + }
57383 + bmiCounter = FALSE;
57384 + break;
57385 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57386 + bmiCounter = FALSE;
57387 + break;
57388 + default: /* BMI counters (or error - will be checked in BMI routine )*/
57389 + bmiCounter = TRUE;
57390 + break;
57391 + }
57392 +
57393 + if (bmiCounter)
57394 + {
57395 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
57396 + &perfType, &isStats);
57397 + if (errCode != E_OK)
57398 + {
57399 + REPORT_ERROR(MINOR, errCode, NO_MSG);
57400 + return 0;
57401 + }
57402 + if (isStats)
57403 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
57404 + else
57405 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
57406 + }
57407 + else /* QMI counter */
57408 + {
57409 + /* check that counters are enabled */
57410 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
57411 + & QMI_PORT_CFG_EN_COUNTERS))
57412 +
57413 + {
57414 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
57415 + return 0;
57416 + }
57417 +
57418 + /* Set counter */
57419 + switch (counter)
57420 + {
57421 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57422 + queueType = E_FMAN_PORT_ENQ_TOTAL;
57423 + break;
57424 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57425 + queueType = E_FMAN_PORT_DEQ_TOTAL;
57426 + break;
57427 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57428 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
57429 + break;
57430 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57431 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
57432 + break;
57433 + default:
57434 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
57435 + return 0;
57436 + }
57437 +
57438 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
57439 + }
57440 +
57441 + return 0;
57442 +}
57443 +
57444 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
57445 + uint32_t value)
57446 +{
57447 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57448 + bool bmiCounter = FALSE;
57449 + enum fman_port_stats_counters statsType;
57450 + enum fman_port_perf_counters perfType;
57451 + enum fman_port_qmi_counters queueType;
57452 + bool isStats;
57453 + t_Error errCode;
57454 +
57455 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57456 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57457 +
57458 + switch (counter)
57459 + {
57460 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57461 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57462 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57463 + /* check that counter is available for the port type */
57464 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
57465 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57466 + RETURN_ERROR(
57467 + MINOR, E_INVALID_STATE,
57468 + ("Requested counter is not available for Rx ports"));
57469 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57470 + bmiCounter = FALSE;
57471 + break;
57472 + default: /* BMI counters (or error - will be checked in BMI routine )*/
57473 + bmiCounter = TRUE;
57474 + break;
57475 + }
57476 +
57477 + if (bmiCounter)
57478 + {
57479 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
57480 + &perfType, &isStats);
57481 + if (errCode != E_OK)
57482 + {
57483 + RETURN_ERROR(MINOR, errCode, NO_MSG);
57484 + }
57485 + if (isStats)
57486 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
57487 + else
57488 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
57489 + }
57490 + else /* QMI counter */
57491 + {
57492 + /* check that counters are enabled */
57493 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
57494 + & QMI_PORT_CFG_EN_COUNTERS))
57495 + {
57496 + RETURN_ERROR(MINOR, E_INVALID_STATE,
57497 + ("Requested counter was not enabled"));
57498 + }
57499 +
57500 + /* Set counter */
57501 + switch (counter)
57502 + {
57503 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57504 + queueType = E_FMAN_PORT_ENQ_TOTAL;
57505 + break;
57506 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57507 + queueType = E_FMAN_PORT_DEQ_TOTAL;
57508 + break;
57509 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57510 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
57511 + break;
57512 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57513 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
57514 + break;
57515 + default:
57516 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
57517 + ("Requested counter is not available"));
57518 + }
57519 +
57520 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
57521 + }
57522 +
57523 + return E_OK;
57524 +}
57525 +
57526 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
57527 +{
57528 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57529 +
57530 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
57531 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57532 +
57533 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
57534 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57535 + {
57536 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
57537 + return 0;
57538 + }
57539 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
57540 +}
57541 +
57542 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
57543 + uint32_t value)
57544 +{
57545 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
57546 +
57547 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57548 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57549 +
57550 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
57551 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57552 + RETURN_ERROR( MINOR, E_INVALID_STATE,
57553 + ("Requested counter is not available for non-Rx ports"));
57554 +
57555 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
57556 + return E_OK;
57557 +}
57558 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
57559 +{
57560 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57561 + t_Error err;
57562 + bool isStalled;
57563 +
57564 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
57565 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57566 + FALSE);
57567 +
57568 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
57569 + if (err != E_OK)
57570 + {
57571 + REPORT_ERROR(MAJOR, err, NO_MSG);
57572 + return TRUE;
57573 + }
57574 + return isStalled;
57575 +}
57576 +
57577 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
57578 +{
57579 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57580 +
57581 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57582 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57583 +
57584 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
57585 +}
57586 +
57587 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
57588 +{
57589 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57590 + int err;
57591 +
57592 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57593 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57594 +
57595 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57596 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57597 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57598 + ("available for Rx ports only"));
57599 +
57600 + if (l4Checksum)
57601 + err = fman_port_modify_rx_fd_bits(
57602 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
57603 + TRUE);
57604 + else
57605 + err = fman_port_modify_rx_fd_bits(
57606 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
57607 + FALSE);
57608 + if (err != 0)
57609 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
57610 +
57611 + return E_OK;
57612 +}
57613 +
57614 +/*****************************************************************************/
57615 +/* API Run-time PCD Control unit functions */
57616 +/*****************************************************************************/
57617 +
57618 +#if (DPAA_VERSION >= 11)
57619 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
57620 +{
57621 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57622 + t_Error err = E_OK;
57623 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
57624 + uint32_t tmpReg = 0, tmp = 0;
57625 + uint16_t hwStoragePrflId;
57626 +
57627 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57628 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
57629 + /*for numOfProfiles = 0 don't call this function*/
57630 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
57631 + /*dfltRelativeId should be in the range of numOfProfiles*/
57632 + SANITY_CHECK_RETURN_ERROR(
57633 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
57634 + E_INVALID_VALUE);
57635 + /*p_FmPort should be from Rx type or OP*/
57636 + SANITY_CHECK_RETURN_ERROR(
57637 + ((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)),
57638 + E_INVALID_VALUE);
57639 + /*port should be disabled*/
57640 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
57641 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
57642 + SANITY_CHECK_RETURN_ERROR(
57643 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
57644 + E_INVALID_VALUE);
57645 + /*should be called before SetPCD - this port should be without PCD*/
57646 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
57647 +
57648 + /*alloc window of VSPs for this port*/
57649 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
57650 + p_FmPort->portId, p_VSPParams->numOfProfiles);
57651 + if (err != E_OK)
57652 + RETURN_ERROR(MAJOR, err, NO_MSG);
57653 +
57654 + /*get absolute VSP ID for dfltRelative*/
57655 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
57656 + p_FmPort->portId,
57657 + p_VSPParams->dfltRelativeId,
57658 + &hwStoragePrflId);
57659 + if (err != E_OK)
57660 + RETURN_ERROR(MAJOR, err, NO_MSG);
57661 +
57662 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
57663 + switch (p_FmPort->portType)
57664 + {
57665 + case (e_FM_PORT_TYPE_RX_10G):
57666 + case (e_FM_PORT_TYPE_RX):
57667 + p_BmiStorageProfileId =
57668 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
57669 + p_BmiVspe =
57670 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
57671 +
57672 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
57673 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
57674 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
57675 +
57676 + tmpReg = GET_UINT32(*p_BmiVspe);
57677 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
57678 +
57679 + p_BmiStorageProfileId =
57680 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
57681 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
57682 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
57683 + break;
57684 +
57685 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57686 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
57687 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
57688 + tmpReg);
57689 +
57690 + p_BmiStorageProfileId =
57691 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
57692 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
57693 + tmp |= BMI_EBD_EN;
57694 + break;
57695 +
57696 + default:
57697 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57698 + ("available for Rx and offline parsing ports only"));
57699 + }
57700 +
57701 + p_FmPort->vspe = TRUE;
57702 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
57703 +
57704 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
57705 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
57706 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
57707 +
57708 + tmpReg = GET_UINT32(*p_BmiVspe);
57709 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
57710 + return E_OK;
57711 +}
57712 +#endif /* (DPAA_VERSION >= 11) */
57713 +
57714 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
57715 +{
57716 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57717 + t_Error err = E_OK;
57718 +
57719 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
57720 + ASSERT_COND(p_FmPort->h_FmPcd);
57721 +
57722 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57723 + {
57724 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57725 + return ERROR_CODE(E_BUSY);
57726 + }
57727 +
57728 + if (numOfProfiles)
57729 + {
57730 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
57731 + p_FmPort->hardwarePortId, numOfProfiles);
57732 + if (err)
57733 + RETURN_ERROR(MAJOR, err, NO_MSG);
57734 + }
57735 + /* set the port handle within the PCD policer, even if no profiles defined */
57736 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
57737 +
57738 + RELEASE_LOCK(p_FmPort->lock);
57739 +
57740 + return E_OK;
57741 +}
57742 +
57743 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
57744 +{
57745 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57746 + t_Error err = E_OK;
57747 +
57748 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57749 + {
57750 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57751 + return ERROR_CODE(E_BUSY);
57752 + }
57753 +
57754 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
57755 +
57756 + RELEASE_LOCK(p_FmPort->lock);
57757 +
57758 + if (err)
57759 + RETURN_ERROR(MAJOR, err, NO_MSG);
57760 +
57761 + return E_OK;
57762 +}
57763 +
57764 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
57765 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
57766 +{
57767 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57768 + volatile uint32_t *p_BmiHpnia = NULL;
57769 + uint32_t tmpReg;
57770 + uint8_t relativeSchemeId;
57771 + uint8_t physicalSchemeId;
57772 +
57773 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57774 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57775 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57776 + E_INVALID_STATE);
57777 +
57778 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
57779 + switch (p_FmPort->portType)
57780 + {
57781 + case (e_FM_PORT_TYPE_RX_10G):
57782 + case (e_FM_PORT_TYPE_RX):
57783 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
57784 + break;
57785 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57786 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
57787 + break;
57788 + default:
57789 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57790 + ("available for Rx and offline parsing ports only"));
57791 + }
57792 +
57793 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57794 + {
57795 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57796 + return ERROR_CODE(E_BUSY);
57797 + }
57798 +
57799 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
57800 + if (p_FmPcdKgScheme->direct)
57801 + {
57802 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
57803 + /* check that this scheme is bound to this port */
57804 + if (!(p_FmPort->schemesPerPortVector
57805 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
57806 + {
57807 + RELEASE_LOCK(p_FmPort->lock);
57808 + RETURN_ERROR(
57809 + MAJOR, E_INVALID_STATE,
57810 + ("called with a scheme that is not bound to this port"));
57811 + }
57812 +
57813 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
57814 + physicalSchemeId);
57815 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
57816 + {
57817 + RELEASE_LOCK(p_FmPort->lock);
57818 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
57819 + ("called with invalid Scheme "));
57820 + }
57821 +
57822 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
57823 + {
57824 + RELEASE_LOCK(p_FmPort->lock);
57825 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
57826 + ("called with uninitialized Scheme "));
57827 + }
57828 +
57829 + WRITE_UINT32(
57830 + *p_BmiHpnia,
57831 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
57832 + }
57833 + else
57834 + /* change to indirect scheme */
57835 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
57836 + RELEASE_LOCK(p_FmPort->lock);
57837 +
57838 + return E_OK;
57839 +}
57840 +
57841 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
57842 + t_Handle h_Profile)
57843 +{
57844 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57845 + volatile uint32_t *p_BmiNia;
57846 + volatile uint32_t *p_BmiHpnia;
57847 + uint32_t tmpReg;
57848 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
57849 +
57850 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57851 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57852 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
57853 + E_INVALID_STATE);
57854 +
57855 + /* check relevance of this routine - only when policer is used
57856 + directly after BMI or Parser */
57857 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
57858 + || (p_FmPort->pcdEngines & FM_PCD_CC))
57859 + RETURN_ERROR(
57860 + MAJOR,
57861 + E_INVALID_STATE,
57862 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
57863 +
57864 + switch (p_FmPort->portType)
57865 + {
57866 + case (e_FM_PORT_TYPE_RX_10G):
57867 + case (e_FM_PORT_TYPE_RX):
57868 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
57869 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
57870 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
57871 + break;
57872 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57873 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
57874 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
57875 + tmpReg = 0;
57876 + break;
57877 + default:
57878 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57879 + ("available for Rx and offline parsing ports only"));
57880 + }
57881 +
57882 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57883 + {
57884 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57885 + return ERROR_CODE(E_BUSY);
57886 + }
57887 +
57888 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
57889 + {
57890 + RELEASE_LOCK(p_FmPort->lock);
57891 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
57892 + }
57893 +
57894 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
57895 +
57896 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
57897 + {
57898 + /* update BMI HPNIA */
57899 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
57900 + }
57901 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
57902 + {
57903 + /* rfne may contain FDCS bits, so first we read them. */
57904 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
57905 + /* update BMI NIA */
57906 + WRITE_UINT32(*p_BmiNia, tmpReg);
57907 + }RELEASE_LOCK(p_FmPort->lock);
57908 +
57909 + return E_OK;
57910 +}
57911 +
57912 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
57913 +{
57914 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57915 + t_Error err = E_OK;
57916 + volatile uint32_t *p_BmiCcBase = NULL;
57917 + volatile uint32_t *p_BmiNia = NULL;
57918 + uint32_t ccTreePhysOffset;
57919 +
57920 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
57921 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
57922 +
57923 + if (p_FmPort->imEn)
57924 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57925 + ("available for non-independent mode ports only"));
57926 +
57927 + /* get PCD registers pointers */
57928 + switch (p_FmPort->portType)
57929 + {
57930 + case (e_FM_PORT_TYPE_RX_10G):
57931 + case (e_FM_PORT_TYPE_RX):
57932 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
57933 + break;
57934 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57935 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
57936 + break;
57937 + default:
57938 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57939 + ("available for Rx and offline parsing ports only"));
57940 + }
57941 +
57942 + /* check that current NIA is BMI to BMI */
57943 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
57944 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
57945 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57946 + ("may be called only for ports in BMI-to-BMI state."));
57947 +
57948 + if (p_FmPort->pcdEngines & FM_PCD_CC)
57949 + {
57950 + if (p_FmPort->h_IpReassemblyManip)
57951 + {
57952 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
57953 + p_FmPort->h_IpReassemblyManip, FALSE);
57954 + if (err != E_OK)
57955 + {
57956 + RETURN_ERROR(MAJOR, err, NO_MSG);
57957 + }
57958 + }
57959 + else
57960 + if (p_FmPort->h_CapwapReassemblyManip)
57961 + {
57962 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
57963 + p_FmPort->h_CapwapReassemblyManip,
57964 + FALSE);
57965 + if (err != E_OK)
57966 + {
57967 + RETURN_ERROR(MAJOR, err, NO_MSG);
57968 + }
57969 + }
57970 + switch (p_FmPort->portType)
57971 + {
57972 + case (e_FM_PORT_TYPE_RX_10G):
57973 + case (e_FM_PORT_TYPE_RX):
57974 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
57975 + break;
57976 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57977 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
57978 + break;
57979 + default:
57980 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
57981 + }
57982 +
57983 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57984 + {
57985 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57986 + return ERROR_CODE(E_BUSY);
57987 + }
57988 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
57989 + &ccTreePhysOffset, h_FmPort);
57990 + if (err)
57991 + {
57992 + RELEASE_LOCK(p_FmPort->lock);
57993 + RETURN_ERROR(MAJOR, err, NO_MSG);
57994 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
57995 +
57996 + p_FmPort->ccTreeId = h_CcTree;
57997 + RELEASE_LOCK(p_FmPort->lock);
57998 + }
57999 + else
58000 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
58001 + ("Coarse Classification not defined for this port."));
58002 +
58003 + return E_OK;
58004 +}
58005 +
58006 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
58007 +{
58008 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58009 + t_Error err = E_OK;
58010 +
58011 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58012 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58013 +
58014 + if (p_FmPort->imEn)
58015 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58016 + ("available for non-independent mode ports only"));
58017 +
58018 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58019 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58020 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58021 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58022 + ("available for Rx and offline parsing ports only"));
58023 +
58024 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58025 + {
58026 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58027 + return ERROR_CODE(E_BUSY);
58028 + }
58029 +
58030 + if (p_FmPort->h_ReassemblyTree)
58031 + p_FmPort->pcdEngines |= FM_PCD_CC;
58032 +
58033 + err = AttachPCD(h_FmPort);
58034 + RELEASE_LOCK(p_FmPort->lock);
58035 +
58036 + return err;
58037 +}
58038 +
58039 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
58040 +{
58041 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58042 + t_Error err = E_OK;
58043 +
58044 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58045 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58046 +
58047 + if (p_FmPort->imEn)
58048 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58049 + ("available for non-independent mode ports only"));
58050 +
58051 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58052 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58053 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58054 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58055 + ("available for Rx and offline parsing ports only"));
58056 +
58057 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58058 + {
58059 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58060 + return ERROR_CODE(E_BUSY);
58061 + }
58062 +
58063 + err = DetachPCD(h_FmPort);
58064 + if (err != E_OK)
58065 + {
58066 + RELEASE_LOCK(p_FmPort->lock);
58067 + RETURN_ERROR(MAJOR, err, NO_MSG);
58068 + }
58069 +
58070 + if (p_FmPort->h_ReassemblyTree)
58071 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
58072 + RELEASE_LOCK(p_FmPort->lock);
58073 +
58074 + return E_OK;
58075 +}
58076 +
58077 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
58078 +{
58079 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58080 + t_Error err = E_OK;
58081 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
58082 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
58083 + t_FmPortPcdCcParams fmPortPcdCcParams;
58084 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
58085 +
58086 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58087 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
58088 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58089 +
58090 + if (p_FmPort->imEn)
58091 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58092 + ("available for non-independent mode ports only"));
58093 +
58094 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58095 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58096 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58097 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58098 + ("available for Rx and offline parsing ports only"));
58099 +
58100 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58101 + {
58102 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58103 + return ERROR_CODE(E_BUSY);
58104 + }
58105 +
58106 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
58107 + ASSERT_COND(p_FmPort->h_FmPcd);
58108 +
58109 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
58110 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
58111 + ("Tree handle must be given if CC is required"));
58112 +
58113 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
58114 + p_PcdParams = &modifiedPcdParams;
58115 + if ((p_PcdParams->h_IpReassemblyManip)
58116 +#if (DPAA_VERSION >= 11)
58117 + || (p_PcdParams->h_CapwapReassemblyManip)
58118 +#endif /* (DPAA_VERSION >= 11) */
58119 + )
58120 + {
58121 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
58122 + && (p_PcdParams->pcdSupport
58123 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
58124 + && (p_PcdParams->pcdSupport
58125 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
58126 + && (p_PcdParams->pcdSupport
58127 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
58128 + {
58129 + RELEASE_LOCK(p_FmPort->lock);
58130 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
58131 + ("pcdSupport must have KG for supporting Reassembly"));
58132 + }
58133 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
58134 +#if (DPAA_VERSION >= 11)
58135 + if ((p_PcdParams->h_IpReassemblyManip)
58136 + && (p_PcdParams->h_CapwapReassemblyManip))
58137 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
58138 + ("Either IP-R or CAPWAP-R is allowed"));
58139 + if ((p_PcdParams->h_CapwapReassemblyManip)
58140 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58141 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
58142 + ("CAPWAP-R is allowed only on offline-port"));
58143 + if (p_PcdParams->h_CapwapReassemblyManip)
58144 + p_FmPort->h_CapwapReassemblyManip =
58145 + p_PcdParams->h_CapwapReassemblyManip;
58146 +#endif /* (DPAA_VERSION >= 11) */
58147 +
58148 + if (!p_PcdParams->p_CcParams)
58149 + {
58150 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
58151 + || (p_PcdParams->pcdSupport
58152 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
58153 + {
58154 + RELEASE_LOCK(p_FmPort->lock);
58155 + RETURN_ERROR(
58156 + MAJOR,
58157 + E_INVALID_STATE,
58158 + ("PCD initialization structure is not consistent with pcdSupport"));
58159 + }
58160 +
58161 + /* No user-tree, need to build internal tree */
58162 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
58163 + sizeof(t_FmPcdCcTreeParams));
58164 + if (!p_FmPcdCcTreeParams)
58165 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
58166 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
58167 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
58168 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
58169 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
58170 +
58171 + if (!p_FmPort->h_ReassemblyTree)
58172 + {
58173 + RELEASE_LOCK(p_FmPort->lock);
58174 + XX_Free(p_FmPcdCcTreeParams);
58175 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
58176 + ("FM_PCD_CcBuildTree for Reassembly failed"));
58177 + }
58178 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
58179 + p_PcdParams->pcdSupport =
58180 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
58181 + else
58182 + p_PcdParams->pcdSupport =
58183 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
58184 +
58185 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
58186 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
58187 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
58188 + XX_Free(p_FmPcdCcTreeParams);
58189 + }
58190 +
58191 + if (p_FmPort->h_IpReassemblyManip)
58192 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
58193 + p_PcdParams->p_CcParams->h_CcTree,
58194 + p_PcdParams->h_NetEnv,
58195 + p_FmPort->h_IpReassemblyManip, TRUE);
58196 +#if (DPAA_VERSION >= 11)
58197 + else
58198 + if (p_FmPort->h_CapwapReassemblyManip)
58199 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
58200 + p_PcdParams->p_CcParams->h_CcTree,
58201 + p_PcdParams->h_NetEnv,
58202 + p_FmPort->h_CapwapReassemblyManip,
58203 + TRUE);
58204 +#endif /* (DPAA_VERSION >= 11) */
58205 +
58206 + if (err != E_OK)
58207 + {
58208 + if (p_FmPort->h_ReassemblyTree)
58209 + {
58210 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58211 + p_FmPort->h_ReassemblyTree = NULL;
58212 + }RELEASE_LOCK(p_FmPort->lock);
58213 + RETURN_ERROR(MAJOR, err, NO_MSG);
58214 + }
58215 + }
58216 +
58217 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
58218 + {
58219 + if (p_FmPort->h_ReassemblyTree)
58220 + {
58221 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58222 + p_FmPort->h_ReassemblyTree = NULL;
58223 + }RELEASE_LOCK(p_FmPort->lock);
58224 + DBG(TRACE, ("Try LockAll - BUSY"));
58225 + return ERROR_CODE(E_BUSY);
58226 + }
58227 +
58228 + err = SetPcd(h_FmPort, p_PcdParams);
58229 + if (err)
58230 + {
58231 + if (p_FmPort->h_ReassemblyTree)
58232 + {
58233 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58234 + p_FmPort->h_ReassemblyTree = NULL;
58235 + }
58236 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58237 + RELEASE_LOCK(p_FmPort->lock);
58238 + RETURN_ERROR(MAJOR, err, NO_MSG);
58239 + }
58240 +
58241 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
58242 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
58243 + {
58244 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
58245 + p_FmPort->hardwarePortId, TRUE);
58246 + if (err)
58247 + {
58248 + DeletePcd(p_FmPort);
58249 + if (p_FmPort->h_ReassemblyTree)
58250 + {
58251 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58252 + p_FmPort->h_ReassemblyTree = NULL;
58253 + }
58254 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58255 + RELEASE_LOCK(p_FmPort->lock);
58256 + RETURN_ERROR(MAJOR, err, NO_MSG);
58257 + }
58258 + p_FmPort->includeInPrsStatistics = TRUE;
58259 + }
58260 +
58261 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
58262 +
58263 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
58264 + {
58265 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
58266 +
58267 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
58268 + {
58269 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
58270 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
58271 + (p_FmPort->pcdEngines & FM_PCD_KG))
58272 + {
58273 + int i;
58274 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
58275 + /* The following function must be locked */
58276 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
58277 + p_PcdParams->p_KgParams->h_Schemes[i],
58278 + UPDATE_KG_NIA_CC_WA,
58279 + 0);
58280 + }
58281 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
58282 +
58283 +#if (DPAA_VERSION >= 11)
58284 + {
58285 + t_FmPcdCtrlParamsPage *p_ParamsPage;
58286 +
58287 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
58288 + (void**)&p_ParamsPage);
58289 + ASSERT_COND(p_ParamsPage);
58290 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
58291 + p_FmPort->savedBmiNia);
58292 + }
58293 +#endif /* (DPAA_VERSION >= 11) */
58294 +
58295 + /* Set post-bmi-fetch nia */
58296 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
58297 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
58298 + | NIA_ENG_FM_CTL);
58299 +
58300 + /* Set pre-bmi-fetch nia */
58301 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
58302 +#if (DPAA_VERSION >= 11)
58303 + fmPortGetSetCcParams.setCcParams.nia =
58304 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
58305 +#else
58306 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
58307 +#endif /* (DPAA_VERSION >= 11) */
58308 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
58309 + != E_OK)
58310 + {
58311 + DeletePcd(p_FmPort);
58312 + if (p_FmPort->h_ReassemblyTree)
58313 + {
58314 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58315 + p_FmPort->h_ReassemblyTree = NULL;
58316 + }
58317 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58318 + RELEASE_LOCK(p_FmPort->lock);
58319 + RETURN_ERROR(MAJOR, err, NO_MSG);
58320 + }
58321 + }
58322 +
58323 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58324 +
58325 + /* Set pop-to-next-step nia */
58326 +#if (DPAA_VERSION == 10)
58327 + if (p_FmPort->fmRevInfo.majorRev < 6)
58328 + {
58329 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
58330 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
58331 + }
58332 + else
58333 + {
58334 +#endif /* (DPAA_VERSION == 10) */
58335 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
58336 +#if (DPAA_VERSION == 10)
58337 + }
58338 +#endif /* (DPAA_VERSION == 10) */
58339 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58340 + != E_OK)
58341 + {
58342 + DeletePcd(p_FmPort);
58343 + if (p_FmPort->h_ReassemblyTree)
58344 + {
58345 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58346 + p_FmPort->h_ReassemblyTree = NULL;
58347 + }RELEASE_LOCK(p_FmPort->lock);
58348 + RETURN_ERROR(MAJOR, err, NO_MSG);
58349 + }
58350 +
58351 + /* Set post-bmi-prepare-to-enq nia */
58352 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
58353 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
58354 + | NIA_ENG_FM_CTL);
58355 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58356 + != E_OK)
58357 + {
58358 + DeletePcd(p_FmPort);
58359 + if (p_FmPort->h_ReassemblyTree)
58360 + {
58361 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58362 + p_FmPort->h_ReassemblyTree = NULL;
58363 + }RELEASE_LOCK(p_FmPort->lock);
58364 + RETURN_ERROR(MAJOR, err, NO_MSG);
58365 + }
58366 +
58367 + if ((p_FmPort->h_IpReassemblyManip)
58368 + || (p_FmPort->h_CapwapReassemblyManip))
58369 + {
58370 +#if (DPAA_VERSION == 10)
58371 + if (p_FmPort->fmRevInfo.majorRev < 6)
58372 + {
58373 + /* Overwrite post-bmi-prepare-to-enq nia */
58374 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
58375 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
58376 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
58377 + }
58378 + else
58379 + {
58380 +#endif /* (DPAA_VERSION == 10) */
58381 + /* Set the ORR bit (for order-restoration) */
58382 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
58383 + fmPortGetSetCcParams.setCcParams.nia =
58384 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
58385 +#if (DPAA_VERSION == 10)
58386 + }
58387 +#endif /* (DPAA_VERSION == 10) */
58388 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58389 + != E_OK)
58390 + {
58391 + DeletePcd(p_FmPort);
58392 + if (p_FmPort->h_ReassemblyTree)
58393 + {
58394 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58395 + p_FmPort->h_ReassemblyTree = NULL;
58396 + }RELEASE_LOCK(p_FmPort->lock);
58397 + RETURN_ERROR(MAJOR, err, NO_MSG);
58398 + }
58399 + }
58400 + }
58401 + else
58402 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58403 +
58404 +#if (DPAA_VERSION >= 11)
58405 + {
58406 + t_FmPcdCtrlParamsPage *p_ParamsPage;
58407 +
58408 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
58409 +
58410 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
58411 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
58412 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
58413 + | NIA_ENG_FM_CTL;
58414 + else
58415 + fmPortGetSetCcParams.setCcParams.nia =
58416 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
58417 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58418 + != E_OK)
58419 + {
58420 + DeletePcd(p_FmPort);
58421 + if (p_FmPort->h_ReassemblyTree)
58422 + {
58423 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58424 + p_FmPort->h_ReassemblyTree = NULL;
58425 + }RELEASE_LOCK(p_FmPort->lock);
58426 + RETURN_ERROR(MAJOR, err, NO_MSG);
58427 + }
58428 +
58429 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
58430 + (void**)&p_ParamsPage);
58431 + ASSERT_COND(p_ParamsPage);
58432 +
58433 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
58434 + WRITE_UINT32(
58435 + p_ParamsPage->misc,
58436 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
58437 +
58438 + if ((p_FmPort->h_IpReassemblyManip)
58439 + || (p_FmPort->h_CapwapReassemblyManip))
58440 + {
58441 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
58442 + WRITE_UINT32(
58443 + p_ParamsPage->discardMask,
58444 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
58445 + else
58446 + WRITE_UINT32(
58447 + p_ParamsPage->discardMask,
58448 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
58449 + }
58450 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
58451 + if (p_FmPort->vspe)
58452 + WRITE_UINT32(
58453 + p_ParamsPage->misc,
58454 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
58455 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
58456 + }
58457 +#endif /* (DPAA_VERSION >= 11) */
58458 +
58459 + err = AttachPCD(h_FmPort);
58460 + if (err)
58461 + {
58462 + DeletePcd(p_FmPort);
58463 + if (p_FmPort->h_ReassemblyTree)
58464 + {
58465 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58466 + p_FmPort->h_ReassemblyTree = NULL;
58467 + }RELEASE_LOCK(p_FmPort->lock);
58468 + RETURN_ERROR(MAJOR, err, NO_MSG);
58469 + }
58470 +
58471 + RELEASE_LOCK(p_FmPort->lock);
58472 +
58473 + return err;
58474 +}
58475 +
58476 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
58477 +{
58478 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58479 + t_Error err = E_OK;
58480 +
58481 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58482 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58483 +
58484 + if (p_FmPort->imEn)
58485 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58486 + ("available for non-independant mode ports only"));
58487 +
58488 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58489 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58490 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58491 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58492 + ("available for Rx and offline parsing ports only"));
58493 +
58494 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58495 + {
58496 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58497 + return ERROR_CODE(E_BUSY);
58498 + }
58499 +
58500 + err = DetachPCD(h_FmPort);
58501 + if (err)
58502 + {
58503 + RELEASE_LOCK(p_FmPort->lock);
58504 + RETURN_ERROR(MAJOR, err, NO_MSG);
58505 + }
58506 +
58507 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
58508 +
58509 + /* we do it anyway, instead of checking if included */
58510 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
58511 + {
58512 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
58513 + p_FmPort->hardwarePortId, FALSE);
58514 + p_FmPort->includeInPrsStatistics = FALSE;
58515 + }
58516 +
58517 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
58518 + {
58519 + RELEASE_LOCK(p_FmPort->lock);
58520 + DBG(TRACE, ("Try LockAll - BUSY"));
58521 + return ERROR_CODE(E_BUSY);
58522 + }
58523 +
58524 + err = DeletePcd(h_FmPort);
58525 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58526 + if (err)
58527 + {
58528 + RELEASE_LOCK(p_FmPort->lock);
58529 + RETURN_ERROR(MAJOR, err, NO_MSG);
58530 + }
58531 +
58532 + if (p_FmPort->h_ReassemblyTree)
58533 + {
58534 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58535 + if (err)
58536 + {
58537 + RELEASE_LOCK(p_FmPort->lock);
58538 + RETURN_ERROR(MAJOR, err, NO_MSG);
58539 + }
58540 + p_FmPort->h_ReassemblyTree = NULL;
58541 + }RELEASE_LOCK(p_FmPort->lock);
58542 +
58543 + return err;
58544 +}
58545 +
58546 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
58547 + t_FmPcdPortSchemesParams *p_PortScheme)
58548 +{
58549 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58550 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
58551 + t_Error err = E_OK;
58552 + uint32_t tmpScmVec = 0;
58553 + int i;
58554 +
58555 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58556 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58557 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
58558 + E_INVALID_STATE);
58559 +
58560 + schemeBind.netEnvId = p_FmPort->netEnvId;
58561 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
58562 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
58563 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
58564 + for (i = 0; i < schemeBind.numOfSchemes; i++)
58565 + {
58566 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
58567 + p_PortScheme->h_Schemes[i]);
58568 + /* build vector */
58569 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
58570 + }
58571 +
58572 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58573 + {
58574 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58575 + return ERROR_CODE(E_BUSY);
58576 + }
58577 +
58578 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
58579 + if (err == E_OK)
58580 + p_FmPort->schemesPerPortVector |= tmpScmVec;
58581 +
58582 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
58583 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
58584 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
58585 + (p_FmPort->fmRevInfo.majorRev < 6))
58586 + {
58587 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
58588 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
58589 + }
58590 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
58591 +
58592 + RELEASE_LOCK(p_FmPort->lock);
58593 +
58594 + return err;
58595 +}
58596 +
58597 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
58598 + t_FmPcdPortSchemesParams *p_PortScheme)
58599 +{
58600 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58601 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
58602 + t_Error err = E_OK;
58603 + uint32_t tmpScmVec = 0;
58604 + int i;
58605 +
58606 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58607 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58608 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
58609 + E_INVALID_STATE);
58610 +
58611 + schemeBind.netEnvId = p_FmPort->netEnvId;
58612 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
58613 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
58614 + for (i = 0; i < schemeBind.numOfSchemes; i++)
58615 + {
58616 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
58617 + p_PortScheme->h_Schemes[i]);
58618 + /* build vector */
58619 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
58620 + }
58621 +
58622 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58623 + {
58624 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58625 + return ERROR_CODE(E_BUSY);
58626 + }
58627 +
58628 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
58629 + if (err == E_OK)
58630 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
58631 + RELEASE_LOCK(p_FmPort->lock);
58632 +
58633 + return err;
58634 +}
58635 +
58636 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
58637 + t_FmPortCongestionGrps *p_CongestionGrps)
58638 +{
58639 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58640 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
58641 + uint8_t mod, index;
58642 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
58643 + int err;
58644 +#if (DPAA_VERSION >= 11)
58645 + int j;
58646 +#endif /* (DPAA_VERSION >= 11) */
58647 +
58648 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58649 +
58650 + /* un-necessary check of the indexes; probably will be needed in the future when there
58651 + will be more CGs available ....
58652 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
58653 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
58654 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
58655 + */
58656 +
58657 +#ifdef FM_NO_OP_OBSERVED_CGS
58658 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
58659 + (p_FmPort->fmRevInfo.majorRev < 6))
58660 + {
58661 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
58662 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
58663 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
58664 + }
58665 + else
58666 +#endif /* FM_NO_OP_OBSERVED_CGS */
58667 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58668 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58669 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58670 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
58671 + ("Available for Rx & OP ports only"));
58672 +
58673 + /* Prepare groups map array */
58674 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
58675 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
58676 + {
58677 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
58678 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
58679 + if (p_FmPort->fmRevInfo.majorRev != 4)
58680 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
58681 + else
58682 + grpsMap[0] |= (uint32_t)(1 << mod);
58683 + }
58684 +
58685 + memset(&priorityTmpArray, 0,
58686 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
58687 +
58688 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
58689 + {
58690 +#if (DPAA_VERSION >= 11)
58691 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
58692 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
58693 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
58694 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
58695 +#endif /* (DPAA_VERSION >= 11) */
58696 + }
58697 +
58698 +#if (DPAA_VERSION >= 11)
58699 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
58700 + {
58701 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
58702 + priorityTmpArray[i]);
58703 + if (err)
58704 + return err;
58705 + }
58706 +#endif /* (DPAA_VERSION >= 11) */
58707 +
58708 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
58709 + if (err != 0)
58710 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
58711 +
58712 + return E_OK;
58713 +}
58714 +
58715 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
58716 + t_FmPortCongestionGrps *p_CongestionGrps)
58717 +{
58718 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58719 + uint8_t mod, index;
58720 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
58721 + int err;
58722 +
58723 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58724 +
58725 + {
58726 +#ifdef FM_NO_OP_OBSERVED_CGS
58727 + t_FmRevisionInfo revInfo;
58728 +
58729 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
58730 + if (revInfo.majorRev != 4)
58731 + {
58732 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
58733 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
58734 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
58735 + }
58736 + else
58737 +#endif /* FM_NO_OP_OBSERVED_CGS */
58738 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58739 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58740 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58741 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
58742 + ("Available for Rx & OP ports only"));
58743 + }
58744 +
58745 + /* Prepare groups map array */
58746 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
58747 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
58748 + {
58749 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
58750 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
58751 + if (p_FmPort->fmRevInfo.majorRev != 4)
58752 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
58753 + else
58754 + grpsMap[0] |= (uint32_t)(1 << mod);
58755 + }
58756 +
58757 +#if (DPAA_VERSION >= 11)
58758 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
58759 + {
58760 + t_Error err = FmSetCongestionGroupPFCpriority(
58761 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
58762 + 0);
58763 + if (err)
58764 + return err;
58765 + }
58766 +#endif /* (DPAA_VERSION >= 11) */
58767 +
58768 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
58769 + if (err != 0)
58770 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
58771 + ("fman_port_remove_congestion_grps"));
58772 + return E_OK;
58773 +}
58774 +
58775 +#if (DPAA_VERSION >= 11)
58776 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
58777 + uint32_t *p_Ipv4OptionsCount)
58778 +{
58779 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58780 +
58781 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58782 + SANITY_CHECK_RETURN_ERROR(
58783 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
58784 + E_INVALID_VALUE);
58785 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
58786 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
58787 +
58788 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
58789 +
58790 + return E_OK;
58791 +}
58792 +#endif /* (DPAA_VERSION >= 11) */
58793 +
58794 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
58795 + t_FmPortDsarTablesSizes *params)
58796 +{
58797 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58798 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
58799 + sizeof(struct t_FmPortDsarTablesSizes));
58800 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
58801 + sizeof(struct t_FmPortDsarTablesSizes));
58802 + return E_OK;
58803 +}
58804 +
58805 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
58806 +{
58807 + uint32_t *param_page;
58808 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
58809 + t_ArCommonDesc *ArCommonDescPtr;
58810 + uint32_t size = sizeof(t_ArCommonDesc);
58811 + // ARP
58812 + // should put here if (params->max_num_of_arp_entries)?
58813 + size = ROUND_UP(size,4);
58814 + size += sizeof(t_DsarArpDescriptor);
58815 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
58816 + size += sizeof(t_DsarArpStatistics);
58817 + //ICMPV4
58818 + size = ROUND_UP(size,4);
58819 + size += sizeof(t_DsarIcmpV4Descriptor);
58820 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
58821 + size += sizeof(t_DsarIcmpV4Statistics);
58822 + //ICMPV6
58823 + size = ROUND_UP(size,4);
58824 + size += sizeof(t_DsarIcmpV6Descriptor);
58825 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
58826 + size += sizeof(t_DsarIcmpV6Statistics);
58827 + //ND
58828 + size = ROUND_UP(size,4);
58829 + size += sizeof(t_DsarNdDescriptor);
58830 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
58831 + size += sizeof(t_DsarIcmpV6Statistics);
58832 + //SNMP
58833 + size = ROUND_UP(size,4);
58834 + size += sizeof(t_DsarSnmpDescriptor);
58835 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
58836 + * params->maxNumOfSnmpIPV4Entries;
58837 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
58838 + * params->maxNumOfSnmpIPV6Entries;
58839 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
58840 + size += params->maxNumOfSnmpOidChar;
58841 + size += sizeof(t_DsarIcmpV6Statistics);
58842 + //filters
58843 + size = ROUND_UP(size,4);
58844 + size += params->maxNumOfIpProtFiltering;
58845 + size = ROUND_UP(size,4);
58846 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
58847 + size = ROUND_UP(size,4);
58848 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
58849 +
58850 + // add here for more protocols
58851 +
58852 + // statistics
58853 + size = ROUND_UP(size,4);
58854 + size += sizeof(t_ArStatistics);
58855 +
58856 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
58857 +
58858 + param_page =
58859 + XX_PhysToVirt(
58860 + p_FmPort->fmMuramPhysBaseAddr
58861 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
58862 + WRITE_UINT32(
58863 + *param_page,
58864 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
58865 + return E_OK;
58866 +}
58867 +
58868 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
58869 +{
58870 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58871 + return p_FmPort->deepSleepVars.autoResMaxSizes;
58872 +}
58873 +
58874 +struct arOffsets
58875 +{
58876 + uint32_t arp;
58877 + uint32_t nd;
58878 + uint32_t icmpv4;
58879 + uint32_t icmpv6;
58880 + uint32_t snmp;
58881 + uint32_t stats;
58882 + uint32_t filtIp;
58883 + uint32_t filtUdp;
58884 + uint32_t filtTcp;
58885 +};
58886 +
58887 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
58888 + struct t_FmPortDsarParams *params,
58889 + t_FmPort *p_FmPort)
58890 +{
58891 + uint32_t size = sizeof(t_ArCommonDesc);
58892 + // ARP
58893 + if (params->p_AutoResArpInfo)
58894 + {
58895 + size = ROUND_UP(size,4);
58896 + of->arp = size;
58897 + size += sizeof(t_DsarArpDescriptor);
58898 + size += sizeof(t_DsarArpBindingEntry)
58899 + * params->p_AutoResArpInfo->tableSize;
58900 + size += sizeof(t_DsarArpStatistics);
58901 + }
58902 + // ICMPV4
58903 + if (params->p_AutoResEchoIpv4Info)
58904 + {
58905 + size = ROUND_UP(size,4);
58906 + of->icmpv4 = size;
58907 + size += sizeof(t_DsarIcmpV4Descriptor);
58908 + size += sizeof(t_DsarIcmpV4BindingEntry)
58909 + * params->p_AutoResEchoIpv4Info->tableSize;
58910 + size += sizeof(t_DsarIcmpV4Statistics);
58911 + }
58912 + // ICMPV6
58913 + if (params->p_AutoResEchoIpv6Info)
58914 + {
58915 + size = ROUND_UP(size,4);
58916 + of->icmpv6 = size;
58917 + size += sizeof(t_DsarIcmpV6Descriptor);
58918 + size += sizeof(t_DsarIcmpV6BindingEntry)
58919 + * params->p_AutoResEchoIpv6Info->tableSize;
58920 + size += sizeof(t_DsarIcmpV6Statistics);
58921 + }
58922 + // ND
58923 + if (params->p_AutoResNdpInfo)
58924 + {
58925 + size = ROUND_UP(size,4);
58926 + of->nd = size;
58927 + size += sizeof(t_DsarNdDescriptor);
58928 + size += sizeof(t_DsarIcmpV6BindingEntry)
58929 + * (params->p_AutoResNdpInfo->tableSizeAssigned
58930 + + params->p_AutoResNdpInfo->tableSizeTmp);
58931 + size += sizeof(t_DsarIcmpV6Statistics);
58932 + }
58933 + // SNMP
58934 + if (params->p_AutoResSnmpInfo)
58935 + {
58936 + size = ROUND_UP(size,4);
58937 + of->snmp = size;
58938 + size += sizeof(t_DsarSnmpDescriptor);
58939 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
58940 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
58941 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
58942 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
58943 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
58944 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
58945 + size += sizeof(t_DsarIcmpV6Statistics);
58946 + }
58947 + //filters
58948 + size = ROUND_UP(size,4);
58949 + if (params->p_AutoResFilteringInfo)
58950 + {
58951 + of->filtIp = size;
58952 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
58953 + size = ROUND_UP(size,4);
58954 + of->filtUdp = size;
58955 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
58956 + * sizeof(t_PortTblEntry);
58957 + size = ROUND_UP(size,4);
58958 + of->filtTcp = size;
58959 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
58960 + * sizeof(t_PortTblEntry);
58961 + }
58962 + // add here for more protocols
58963 + // statistics
58964 + size = ROUND_UP(size,4);
58965 + of->stats = size;
58966 + size += sizeof(t_ArStatistics);
58967 + return size;
58968 +}
58969 +
58970 +uint32_t* ARDesc;
58971 +void PrsEnable(t_Handle p_FmPcd);
58972 +void PrsDisable(t_Handle p_FmPcd);
58973 +int PrsIsEnabled(t_Handle p_FmPcd);
58974 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
58975 +
58976 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
58977 + t_FmPortDsarTablesSizes *sizes)
58978 +{
58979 + bool macInit = FALSE;
58980 + uint8_t mac[6];
58981 + int i = 0;
58982 +
58983 + // check table sizes
58984 + if (params->p_AutoResArpInfo
58985 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
58986 + RETURN_ERROR(
58987 + MAJOR, E_INVALID_VALUE,
58988 + ("DSAR: Arp table size exceeds the configured maximum size."));
58989 + if (params->p_AutoResEchoIpv4Info
58990 + && sizes->maxNumOfEchoIpv4Entries
58991 + < params->p_AutoResEchoIpv4Info->tableSize)
58992 + RETURN_ERROR(
58993 + MAJOR,
58994 + E_INVALID_VALUE,
58995 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
58996 + if (params->p_AutoResNdpInfo
58997 + && sizes->maxNumOfNdpEntries
58998 + < params->p_AutoResNdpInfo->tableSizeAssigned
58999 + + params->p_AutoResNdpInfo->tableSizeTmp)
59000 + RETURN_ERROR(
59001 + MAJOR, E_INVALID_VALUE,
59002 + ("DSAR: NDP table size exceeds the configured maximum size."));
59003 + if (params->p_AutoResEchoIpv6Info
59004 + && sizes->maxNumOfEchoIpv6Entries
59005 + < params->p_AutoResEchoIpv6Info->tableSize)
59006 + RETURN_ERROR(
59007 + MAJOR,
59008 + E_INVALID_VALUE,
59009 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
59010 + if (params->p_AutoResSnmpInfo
59011 + && sizes->maxNumOfSnmpOidEntries
59012 + < params->p_AutoResSnmpInfo->oidsTblSize)
59013 + RETURN_ERROR(
59014 + MAJOR,
59015 + E_INVALID_VALUE,
59016 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
59017 + if (params->p_AutoResSnmpInfo
59018 + && sizes->maxNumOfSnmpIPV4Entries
59019 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
59020 + RETURN_ERROR(
59021 + MAJOR,
59022 + E_INVALID_VALUE,
59023 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
59024 + if (params->p_AutoResSnmpInfo
59025 + && sizes->maxNumOfSnmpIPV6Entries
59026 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
59027 + RETURN_ERROR(
59028 + MAJOR,
59029 + E_INVALID_VALUE,
59030 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
59031 + if (params->p_AutoResFilteringInfo)
59032 + {
59033 + if (sizes->maxNumOfIpProtFiltering
59034 + < params->p_AutoResFilteringInfo->ipProtTableSize)
59035 + RETURN_ERROR(
59036 + MAJOR,
59037 + E_INVALID_VALUE,
59038 + ("DSAR: ip filter table size exceeds the configured maximum size."));
59039 + if (sizes->maxNumOfTcpPortFiltering
59040 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
59041 + RETURN_ERROR(
59042 + MAJOR,
59043 + E_INVALID_VALUE,
59044 + ("DSAR: udp filter table size exceeds the configured maximum size."));
59045 + if (sizes->maxNumOfUdpPortFiltering
59046 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
59047 + RETURN_ERROR(
59048 + MAJOR,
59049 + E_INVALID_VALUE,
59050 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
59051 + }
59052 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
59053 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
59054 + {
59055 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
59056 + i = 1;
59057 + macInit = TRUE;
59058 +
59059 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
59060 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
59061 + RETURN_ERROR(
59062 + MAJOR, E_INVALID_VALUE,
59063 + ("DSAR: Only 1 mac address is currently supported."));
59064 + }
59065 + if (params->p_AutoResEchoIpv4Info
59066 + && params->p_AutoResEchoIpv4Info->tableSize)
59067 + {
59068 + i = 0;
59069 + if (!macInit)
59070 + {
59071 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
59072 + 6);
59073 + i = 1;
59074 + macInit = TRUE;
59075 + }
59076 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
59077 + if (memcmp(mac,
59078 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
59079 + RETURN_ERROR(
59080 + MAJOR, E_INVALID_VALUE,
59081 + ("DSAR: Only 1 mac address is currently supported."));
59082 + }
59083 + if (params->p_AutoResEchoIpv6Info
59084 + && params->p_AutoResEchoIpv6Info->tableSize)
59085 + {
59086 + i = 0;
59087 + if (!macInit)
59088 + {
59089 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
59090 + 6);
59091 + i = 1;
59092 + macInit = TRUE;
59093 + }
59094 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
59095 + if (memcmp(mac,
59096 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
59097 + RETURN_ERROR(
59098 + MAJOR, E_INVALID_VALUE,
59099 + ("DSAR: Only 1 mac address is currently supported."));
59100 + }
59101 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
59102 + {
59103 + i = 0;
59104 + if (!macInit)
59105 + {
59106 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
59107 + 6);
59108 + i = 1;
59109 + macInit = TRUE;
59110 + }
59111 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
59112 + if (memcmp(mac,
59113 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
59114 + 6))
59115 + RETURN_ERROR(
59116 + MAJOR, E_INVALID_VALUE,
59117 + ("DSAR: Only 1 mac address is currently supported."));
59118 + }
59119 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
59120 + {
59121 + i = 0;
59122 + if (!macInit)
59123 + {
59124 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
59125 + i = 1;
59126 + }
59127 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
59128 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
59129 + 6))
59130 + RETURN_ERROR(
59131 + MAJOR, E_INVALID_VALUE,
59132 + ("DSAR: Only 1 mac address is currently supported."));
59133 + }
59134 + return E_OK;
59135 +}
59136 +
59137 +static int GetBERLen(uint8_t* buf)
59138 +{
59139 + if (*buf & 0x80)
59140 + {
59141 + if ((*buf & 0x7F) == 1)
59142 + return buf[1];
59143 + else
59144 + return *(uint16_t*)&buf[1]; // assuming max len is 2
59145 + }
59146 + else
59147 + return buf[0];
59148 +}
59149 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
59150 +
59151 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
59152 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
59153 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
59154 +static int fm_soc_suspend(void)
59155 +{
59156 + uint32_t *fmclk, tmp32;
59157 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
59158 + tmp32 = GET_UINT32(*fmclk);
59159 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
59160 + tmp32 = GET_UINT32(*fmclk);
59161 + iounmap(fmclk);
59162 + return 0;
59163 +}
59164 +
59165 +void fm_clk_down(void)
59166 +{
59167 + uint32_t *fmclk, tmp32;
59168 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
59169 + tmp32 = GET_UINT32(*fmclk);
59170 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
59171 + tmp32 = GET_UINT32(*fmclk);
59172 + iounmap(fmclk);
59173 +}
59174 +
59175 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
59176 +{
59177 + int i, j;
59178 + t_Error err;
59179 + uint32_t nia;
59180 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59181 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
59182 + t_DsarArpDescriptor *ArpDescriptor;
59183 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
59184 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
59185 + t_DsarNdDescriptor* NDDescriptor;
59186 +
59187 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
59188 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
59189 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
59190 + struct arOffsets* of;
59191 + uint8_t tmp = 0;
59192 + t_FmGetSetParams fmGetSetParams;
59193 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59194 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
59195 + fmGetSetParams.setParams.sleep = 1;
59196 +
59197 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
59198 + if (err != E_OK)
59199 + return err;
59200 +
59201 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
59202 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
59203 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
59204 +
59205 + // common
59206 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
59207 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
59208 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
59209 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
59210 + else
59211 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
59212 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
59213 +
59214 + // ARP
59215 + if (params->p_AutoResArpInfo)
59216 + {
59217 + t_DsarArpBindingEntry* arp_bindings;
59218 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
59219 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
59220 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
59221 + if (params->p_AutoResArpInfo->enableConflictDetection)
59222 + WRITE_UINT16(ArpDescriptor->control, 1);
59223 + else
59224 + WRITE_UINT16(ArpDescriptor->control, 0);
59225 + if (params->p_AutoResArpInfo->tableSize)
59226 + {
59227 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
59228 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
59229 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
59230 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
59231 +
59232 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
59233 + {
59234 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
59235 + if (arp_entry[i].isVlan)
59236 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
59237 + }
59238 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
59239 + }
59240 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
59241 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
59242 + }
59243 +
59244 + // ICMPV4
59245 + if (params->p_AutoResEchoIpv4Info)
59246 + {
59247 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
59248 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
59249 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
59250 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
59251 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
59252 + if (params->p_AutoResEchoIpv4Info->tableSize)
59253 + {
59254 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
59255 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
59256 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
59257 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
59258 +
59259 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
59260 + {
59261 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
59262 + if (arp_entry[i].isVlan)
59263 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
59264 + }
59265 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
59266 + }
59267 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
59268 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
59269 + }
59270 +
59271 + // ICMPV6
59272 + if (params->p_AutoResEchoIpv6Info)
59273 + {
59274 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
59275 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
59276 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
59277 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
59278 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
59279 + if (params->p_AutoResEchoIpv6Info->tableSize)
59280 + {
59281 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
59282 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
59283 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
59284 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
59285 +
59286 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
59287 + {
59288 + for (j = 0; j < 4; j++)
59289 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
59290 + if (ndp_entry[i].isVlan)
59291 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
59292 + }
59293 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
59294 + }
59295 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
59296 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
59297 + }
59298 +
59299 + // ND
59300 + if (params->p_AutoResNdpInfo)
59301 + {
59302 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
59303 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
59304 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
59305 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
59306 + if (params->p_AutoResNdpInfo->enableConflictDetection)
59307 + WRITE_UINT16(NDDescriptor->control, 1);
59308 + else
59309 + WRITE_UINT16(NDDescriptor->control, 0);
59310 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
59311 + {
59312 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
59313 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
59314 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
59315 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
59316 + + params->p_AutoResNdpInfo->tableSizeTmp);
59317 +
59318 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
59319 + {
59320 + for (j = 0; j < 4; j++)
59321 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
59322 + if (ndp_entry[i].isVlan)
59323 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
59324 + }
59325 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
59326 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
59327 + {
59328 + for (j = 0; j < 4; j++)
59329 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
59330 + if (ndp_entry[i].isVlan)
59331 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
59332 + }
59333 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
59334 + }
59335 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
59336 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
59337 + - fmMuramVirtBaseAddr);
59338 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
59339 + }
59340 +
59341 + // SNMP
59342 + if (params->p_AutoResSnmpInfo)
59343 + {
59344 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
59345 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
59346 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
59347 + t_OidsTblEntry* snmpOid;
59348 + uint8_t *charPointer;
59349 + int len;
59350 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
59351 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
59352 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
59353 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
59354 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
59355 + if (snmpSrc->numOfIpv4Addresses)
59356 + {
59357 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
59358 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
59359 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
59360 + {
59361 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
59362 + if (snmpIpv4AddrSrc[i].isVlan)
59363 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
59364 + }
59365 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
59366 + }
59367 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
59368 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
59369 + if (snmpSrc->numOfIpv6Addresses)
59370 + {
59371 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
59372 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
59373 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
59374 + {
59375 + for (j = 0; j < 4; j++)
59376 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
59377 + if (snmpIpv6AddrSrc[i].isVlan)
59378 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
59379 + }
59380 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
59381 + }
59382 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
59383 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
59384 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
59385 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
59386 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
59387 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
59388 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59389 + charPointer += len;
59390 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
59391 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
59392 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59393 + charPointer += len;
59394 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
59395 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
59396 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
59397 + {
59398 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
59399 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
59400 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
59401 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59402 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
59403 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
59404 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
59405 + else
59406 + {
59407 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
59408 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59409 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
59410 + }
59411 + snmpOid++;
59412 + }
59413 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
59414 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59415 + }
59416 +
59417 + // filtering
59418 + if (params->p_AutoResFilteringInfo)
59419 + {
59420 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
59421 + tmp |= IP_PROT_TBL_PASS_MASK;
59422 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
59423 + tmp |= UDP_PORT_TBL_PASS_MASK;
59424 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
59425 + tmp |= TCP_PORT_TBL_PASS_MASK;
59426 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
59427 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
59428 +
59429 + // ip filtering
59430 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
59431 + {
59432 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
59433 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
59434 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
59435 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
59436 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
59437 + }
59438 +
59439 + // udp filtering
59440 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
59441 + {
59442 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
59443 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
59444 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
59445 + {
59446 + WRITE_UINT32(udp_tbl[i].Ports,
59447 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
59448 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
59449 + WRITE_UINT32(udp_tbl[i].PortsMask,
59450 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
59451 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
59452 + }
59453 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
59454 + }
59455 +
59456 + // tcp filtering
59457 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
59458 + {
59459 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
59460 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
59461 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
59462 + {
59463 + WRITE_UINT32(tcp_tbl[i].Ports,
59464 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
59465 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
59466 + WRITE_UINT32(tcp_tbl[i].PortsMask,
59467 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
59468 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
59469 + }
59470 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
59471 + }
59472 + }
59473 + // common stats
59474 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
59475 +
59476 + // get into Deep Sleep sequence:
59477 +
59478 + // Ensures that FMan do not enter the idle state. This is done by programing
59479 + // FMDPSLPCR[FM_STOP] to one.
59480 + fm_soc_suspend();
59481 +
59482 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
59483 + return E_OK;
59484 +
59485 +}
59486 +
59487 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
59488 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
59489 +{
59490 + t_FmGetSetParams fmGetSetParams;
59491 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
59492 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
59493 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
59494 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
59495 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59496 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
59497 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59498 +
59499 + /* Issue graceful stop to HC port */
59500 + FM_PORT_Disable(p_FmPortHc);
59501 +
59502 + // config tx port
59503 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
59504 + 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);
59505 + // ????
59506 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
59507 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
59508 + // Stage 7:echo
59509 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
59510 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
59511 + if (!PrsIsEnabled(h_FmPcd))
59512 + {
59513 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
59514 + PrsEnable(h_FmPcd);
59515 + }
59516 + else
59517 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
59518 +
59519 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
59520 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
59521 +
59522 + // save rcfg for restoring: accumulate mode is changed by ucode
59523 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
59524 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
59525 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59526 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
59527 + fmGetSetParams.setParams.sleep = 1;
59528 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59529 +
59530 +// ***** issue external request sync command
59531 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59532 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
59533 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59534 + // get
59535 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59536 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
59537 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59538 + if (fmGetSetParams.getParams.fmfp_extc != 0)
59539 + {
59540 + // clear
59541 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59542 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
59543 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59544 +}
59545 +
59546 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59547 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
59548 + do
59549 + {
59550 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59551 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
59552 + if (fmGetSetParams.getParams.fm_npi != 0)
59553 + XX_Print("FM: Sync did not finish\n");
59554 +
59555 + // check that all stoped
59556 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59557 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
59558 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59559 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
59560 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59561 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
59562 + XX_Print("FM: Sleeping\n");
59563 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
59564 +
59565 + return E_OK;
59566 +}
59567 +
59568 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
59569 +
59570 +void FM_PORT_Dsar_DumpRegs()
59571 +{
59572 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
59573 + DUMP_MEMORY(hh, 0x220);
59574 +}
59575 +
59576 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
59577 +{
59578 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59579 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
59580 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
59581 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
59582 + t_FmGetSetParams fmGetSetParams;
59583 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59584 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
59585 + fmGetSetParams.setParams.sleep = 0;
59586 + if (p_FmPort->deepSleepVars.autoResOffsets)
59587 + {
59588 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
59589 + p_FmPort->deepSleepVars.autoResOffsets = 0;
59590 + }
59591 +
59592 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
59593 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
59594 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
59595 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
59596 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
59597 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59598 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
59599 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
59600 + FM_PORT_Enable(p_FmPortHc);
59601 +}
59602 +
59603 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
59604 +{
59605 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
59606 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
59607 +}
59608 +
59609 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
59610 +{
59611 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59612 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
59613 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
59614 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
59615 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
59616 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
59617 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
59618 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
59619 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
59620 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
59621 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
59622 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
59623 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
59624 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
59625 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
59626 + stats->arpArCnt = arp_stats->arCnt;
59627 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
59628 + stats->ndpArCnt = nd_stats->arCnt;
59629 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
59630 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
59631 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
59632 + return E_OK;
59633 +}
59634 --- /dev/null
59635 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
59636 @@ -0,0 +1,999 @@
59637 +/*
59638 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59639 + *
59640 + * Redistribution and use in source and binary forms, with or without
59641 + * modification, are permitted provided that the following conditions are met:
59642 + * * Redistributions of source code must retain the above copyright
59643 + * notice, this list of conditions and the following disclaimer.
59644 + * * Redistributions in binary form must reproduce the above copyright
59645 + * notice, this list of conditions and the following disclaimer in the
59646 + * documentation and/or other materials provided with the distribution.
59647 + * * Neither the name of Freescale Semiconductor nor the
59648 + * names of its contributors may be used to endorse or promote products
59649 + * derived from this software without specific prior written permission.
59650 + *
59651 + *
59652 + * ALTERNATIVELY, this software may be distributed under the terms of the
59653 + * GNU General Public License ("GPL") as published by the Free Software
59654 + * Foundation, either version 2 of that License or (at your option) any
59655 + * later version.
59656 + *
59657 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59658 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59659 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59660 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59661 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59662 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59663 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59664 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59665 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59666 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59667 + */
59668 +
59669 +
59670 +/******************************************************************************
59671 + @File fm_port.h
59672 +
59673 + @Description FM Port internal structures and definitions.
59674 +*//***************************************************************************/
59675 +#ifndef __FM_PORT_H
59676 +#define __FM_PORT_H
59677 +
59678 +#include "error_ext.h"
59679 +#include "std_ext.h"
59680 +#include "fm_port_ext.h"
59681 +
59682 +#include "fm_common.h"
59683 +#include "fm_sp_common.h"
59684 +#include "fsl_fman_sp.h"
59685 +#include "fm_port_ext.h"
59686 +#include "fsl_fman_port.h"
59687 +
59688 +#define __ERR_MODULE__ MODULE_FM_PORT
59689 +
59690 +
59691 +#define MIN_EXT_BUF_SIZE 64
59692 +#define DATA_ALIGNMENT 64
59693 +#define MAX_LIODN_OFFSET 64
59694 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
59695 +
59696 +/**************************************************************************//**
59697 + @Description Memory Map defines
59698 +*//***************************************************************************/
59699 +#define BMI_PORT_REGS_OFFSET 0
59700 +#define QMI_PORT_REGS_OFFSET 0x400
59701 +#define PRS_PORT_REGS_OFFSET 0x800
59702 +
59703 +/**************************************************************************//**
59704 + @Description defaults
59705 +*//***************************************************************************/
59706 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
59707 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
59708 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
59709 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
59710 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
59711 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
59712 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
59713 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
59714 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
59715 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
59716 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
59717 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
59718 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
59719 +#define DEFAULT_PORT_cutBytesFromEnd 4
59720 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
59721 +
59722 +#define DEFAULT_PORT_frmDiscardOverride FALSE
59723 +
59724 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
59725 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
59726 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
59727 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
59728 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
59729 +
59730 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
59731 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
59732 +#define DEFAULT_PORT_BufMargins_startMargins 32
59733 +#define DEFAULT_PORT_BufMargins_endMargins 0
59734 +#define DEFAULT_PORT_syncReq TRUE
59735 +#define DEFAULT_PORT_syncReqForHc FALSE
59736 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
59737 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
59738 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
59739 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
59740 +#define DEFAULT_PORT_exception IM_EV_BSY
59741 +#define DEFAULT_PORT_maxFrameLength 9600
59742 +
59743 +#define DEFAULT_notSupported 0xff
59744 +
59745 +#if (DPAA_VERSION < 11)
59746 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
59747 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
59748 +
59749 +#define DEFAULT_PORT_txFifoMinFillLevel 0
59750 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
59751 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
59752 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
59753 +
59754 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
59755 +
59756 +/* Host command port MUST NOT be changed to more than 1 !!! */
59757 +#define DEFAULT_PORT_numOfTasks(type) \
59758 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
59759 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
59760 + ((((type) == e_FM_PORT_TYPE_RX) || \
59761 + ((type) == e_FM_PORT_TYPE_TX) || \
59762 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
59763 +
59764 +#define DEFAULT_PORT_extraNumOfTasks(type) \
59765 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
59766 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
59767 +
59768 +#define DEFAULT_PORT_numOfOpenDmas(type) \
59769 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
59770 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
59771 +
59772 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
59773 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
59774 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
59775 +
59776 +#define DEFAULT_PORT_numOfFifoBufs(type) \
59777 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
59778 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
59779 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
59780 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
59781 +
59782 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
59783 +
59784 +#else /* (DPAA_VERSION < 11) */
59785 +/* Defaults are registers' reset values */
59786 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
59787 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
59788 +
59789 +#define DEFAULT_PORT_txFifoMinFillLevel 0
59790 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
59791 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
59792 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
59793 +
59794 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
59795 +
59796 +#define DEFAULT_PORT_numOfTasks(type) \
59797 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
59798 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
59799 + (((type) == e_FM_PORT_TYPE_RX) || \
59800 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
59801 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
59802 +
59803 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
59804 +
59805 +#define DEFAULT_PORT_numOfOpenDmas(type) \
59806 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
59807 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
59808 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
59809 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
59810 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
59811 +
59812 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
59813 +
59814 +#define DEFAULT_PORT_numOfFifoBufs(type) \
59815 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
59816 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
59817 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
59818 +
59819 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
59820 +
59821 +#endif /* (DPAA_VERSION < 11) */
59822 +
59823 +#define DEFAULT_PORT_txBdRingLength 16
59824 +#define DEFAULT_PORT_rxBdRingLength 128
59825 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
59826 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
59827 +
59828 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
59829 +
59830 +/**************************************************************************//**
59831 + @Collection PCD Engines
59832 +*//***************************************************************************/
59833 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
59834 +
59835 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
59836 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
59837 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
59838 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
59839 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
59840 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
59841 +/* @} */
59842 +
59843 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
59844 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
59845 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
59846 +
59847 +#define FM_OH_PORT_ID 0
59848 +
59849 +/***********************************************************************/
59850 +/* SW parser OFFLOAD labels (offsets) */
59851 +/***********************************************************************/
59852 +#if (DPAA_VERSION == 10)
59853 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
59854 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
59855 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
59856 +#else
59857 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
59858 +/* Will be used for:
59859 + * 1. identify fragments
59860 + * 2. udp-lite
59861 + */
59862 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
59863 +/* Will be used for:
59864 + * 1. will identify the fragmentable area
59865 + * 2. udp-lite
59866 + */
59867 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
59868 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
59869 +#endif /* (DPAA_VERSION == 10) */
59870 +
59871 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
59872 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
59873 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
59874 +
59875 +
59876 +/**************************************************************************//**
59877 + @Description Memory Mapped Registers
59878 +*//***************************************************************************/
59879 +
59880 +#if defined(__MWERKS__) && !defined(__GNUC__)
59881 +#pragma pack(push,1)
59882 +#endif /* defined(__MWERKS__) && ... */
59883 +
59884 +typedef struct
59885 +{
59886 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
59887 + volatile uint32_t fmbm_rst; /**< Rx Status */
59888 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
59889 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
59890 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
59891 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
59892 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
59893 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
59894 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
59895 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
59896 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
59897 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
59898 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
59899 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
59900 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
59901 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
59902 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
59903 + /**< Rx Parse Results Array Initialization*/
59904 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
59905 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
59906 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
59907 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
59908 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
59909 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
59910 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
59911 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
59912 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
59913 + /**< Buffer Manager pool Information-*/
59914 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
59915 + /**< Allocate Counter-*/
59916 + volatile uint32_t reserved4[0x08];
59917 + /**< 0x130/0x140 - 0x15F reserved -*/
59918 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
59919 + /**< Congestion Group Map*/
59920 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
59921 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
59922 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
59923 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
59924 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
59925 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
59926 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
59927 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
59928 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
59929 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
59930 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
59931 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
59932 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
59933 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
59934 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
59935 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
59936 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
59937 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
59938 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
59939 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
59940 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
59941 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
59942 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
59943 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
59944 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
59945 +} t_FmPortRxBmiRegs;
59946 +
59947 +typedef struct
59948 +{
59949 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
59950 + volatile uint32_t fmbm_tst; /**< Tx Status */
59951 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
59952 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
59953 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
59954 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
59955 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
59956 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
59957 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
59958 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
59959 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
59960 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
59961 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
59962 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
59963 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
59964 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
59965 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
59966 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
59967 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
59968 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
59969 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
59970 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
59971 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
59972 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
59973 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
59974 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
59975 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
59976 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
59977 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
59978 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
59979 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
59980 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
59981 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
59982 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
59983 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
59984 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
59985 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
59986 +} t_FmPortTxBmiRegs;
59987 +
59988 +typedef struct
59989 +{
59990 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
59991 + volatile uint32_t fmbm_ost; /**< O/H Status */
59992 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
59993 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
59994 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
59995 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
59996 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
59997 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
59998 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
59999 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
60000 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
60001 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
60002 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
60003 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
60004 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
60005 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
60006 + /**< O/H Parse Results Array Initialization */
60007 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
60008 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
60009 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
60010 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
60011 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
60012 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
60013 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
60014 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
60015 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
60016 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
60017 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
60018 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
60019 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
60020 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
60021 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
60022 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
60023 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
60024 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
60025 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
60026 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
60027 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
60028 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
60029 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
60030 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
60031 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
60032 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
60033 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
60034 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
60035 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
60036 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
60037 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
60038 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
60039 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
60040 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
60041 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
60042 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
60043 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
60044 +} t_FmPortOhBmiRegs;
60045 +
60046 +typedef union
60047 +{
60048 + t_FmPortRxBmiRegs rxPortBmiRegs;
60049 + t_FmPortTxBmiRegs txPortBmiRegs;
60050 + t_FmPortOhBmiRegs ohPortBmiRegs;
60051 +} u_FmPortBmiRegs;
60052 +
60053 +typedef struct
60054 +{
60055 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
60056 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
60057 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
60058 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
60059 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
60060 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
60061 +} t_FmPortNonRxQmiRegs;
60062 +
60063 +typedef struct
60064 +{
60065 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
60066 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
60067 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
60068 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
60069 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
60070 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
60071 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
60072 +} t_FmPortQmiRegs;
60073 +
60074 +typedef struct
60075 +{
60076 + struct
60077 + {
60078 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
60079 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
60080 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
60081 + volatile uint32_t reserved0[0xde];
60082 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
60083 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
60084 +} t_FmPortPrsRegs;
60085 +
60086 +/**************************************************************************//*
60087 + @Description Basic buffer descriptor (BD) structure
60088 +*//***************************************************************************/
60089 +typedef _Packed struct
60090 +{
60091 + volatile uint16_t status;
60092 + volatile uint16_t length;
60093 + volatile uint8_t reserved0[0x6];
60094 + volatile uint8_t reserved1[0x1];
60095 + volatile t_FmPhysAddr buff;
60096 +} _PackedType t_FmImBd;
60097 +
60098 +typedef _Packed struct
60099 +{
60100 + volatile uint16_t gen; /**< tbd */
60101 + volatile uint8_t reserved0[0x1];
60102 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
60103 + volatile uint16_t bdRingSize; /**< tbd */
60104 + volatile uint16_t offsetIn; /**< tbd */
60105 + volatile uint16_t offsetOut; /**< tbd */
60106 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
60107 +} _PackedType t_FmPortImQd;
60108 +
60109 +typedef _Packed struct
60110 +{
60111 + volatile uint32_t mode; /**< Mode register */
60112 + volatile uint32_t rxQdPtr; /**< tbd */
60113 + volatile uint32_t txQdPtr; /**< tbd */
60114 + volatile uint16_t mrblr; /**< tbd */
60115 + volatile uint16_t rxQdBsyCnt; /**< tbd */
60116 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
60117 + t_FmPortImQd rxQd;
60118 + t_FmPortImQd txQd;
60119 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
60120 +} _PackedType t_FmPortImPram;
60121 +
60122 +#if defined(__MWERKS__) && !defined(__GNUC__)
60123 +#pragma pack(pop)
60124 +#endif /* defined(__MWERKS__) && ... */
60125 +
60126 +
60127 +/**************************************************************************//**
60128 + @Description Registers bit fields
60129 +*//***************************************************************************/
60130 +
60131 +/**************************************************************************//**
60132 + @Description BMI defines
60133 +*//***************************************************************************/
60134 +#if (DPAA_VERSION >= 11)
60135 +#define BMI_SP_ID_MASK 0xff000000
60136 +#define BMI_SP_ID_SHIFT 24
60137 +#define BMI_SP_EN 0x01000000
60138 +#endif /* (DPAA_VERSION >= 11) */
60139 +
60140 +#define BMI_PORT_CFG_EN 0x80000000
60141 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
60142 +#define BMI_PORT_CFG_FDOVR 0x02000000
60143 +#define BMI_PORT_CFG_IM 0x01000000
60144 +#define BMI_PORT_CFG_AM 0x00000040
60145 +#define BMI_PORT_STATUS_BSY 0x80000000
60146 +#define BMI_COUNTERS_EN 0x80000000
60147 +
60148 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
60149 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
60150 +#define BMI_RFNE_FDCS_MASK 0xFF000000
60151 +#define BMI_RFNE_HXS_MASK 0x000000FF
60152 +
60153 +#define BMI_CMD_MR_LEAC 0x00200000
60154 +#define BMI_CMD_MR_SLEAC 0x00100000
60155 +#define BMI_CMD_MR_MA 0x00080000
60156 +#define BMI_CMD_MR_DEAS 0x00040000
60157 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
60158 + BMI_CMD_MR_SLEAC | \
60159 + BMI_CMD_MR_MA | \
60160 + BMI_CMD_MR_DEAS)
60161 +#define BMI_CMD_ATTR_ORDER 0x80000000
60162 +#define BMI_CMD_ATTR_SYNC 0x02000000
60163 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
60164 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
60165 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
60166 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
60167 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
60168 +
60169 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
60170 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
60171 + FM_PORT_FRM_ERR_PHYSICAL | \
60172 + FM_PORT_FRM_ERR_SIZE | \
60173 + FM_PORT_FRM_ERR_CLS_DISCARD | \
60174 + FM_PORT_FRM_ERR_EXTRACTION | \
60175 + FM_PORT_FRM_ERR_NO_SCHEME | \
60176 + FM_PORT_FRM_ERR_COLOR_RED | \
60177 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
60178 + FM_PORT_FRM_ERR_ILL_PLCR | \
60179 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
60180 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
60181 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
60182 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
60183 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
60184 + FM_PORT_FRM_ERR_IPRE | \
60185 + FM_PORT_FRM_ERR_IPR_NCSP | \
60186 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
60187 +
60188 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
60189 + ~(FM_PORT_FRM_ERR_LENGTH | \
60190 + FM_PORT_FRM_ERR_NON_FM | \
60191 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
60192 +
60193 +#define BMI_RATE_LIMIT_EN 0x80000000
60194 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
60195 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
60196 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
60197 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
60198 +
60199 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
60200 +
60201 +#define BMI_PRS_RESULT_HIGH 0x00000000
60202 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
60203 +
60204 +
60205 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
60206 + FM_PORT_FRM_ERR_PHYSICAL | \
60207 + FM_PORT_FRM_ERR_SIZE | \
60208 + FM_PORT_FRM_ERR_EXTRACTION | \
60209 + FM_PORT_FRM_ERR_NO_SCHEME | \
60210 + FM_PORT_FRM_ERR_ILL_PLCR | \
60211 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
60212 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
60213 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
60214 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
60215 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
60216 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
60217 + FM_PORT_FRM_ERR_IPRE)
60218 +
60219 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
60220 + FM_PORT_FRM_ERR_LENGTH | \
60221 + FM_PORT_FRM_ERR_NON_FM | \
60222 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
60223 +
60224 +
60225 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
60226 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
60227 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
60228 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
60229 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
60230 +
60231 +/* shifts */
60232 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
60233 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
60234 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
60235 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
60236 +
60237 +#define BMI_IM_FOF_SHIFT 28
60238 +#define BMI_PR_PORTID_SHIFT 24
60239 +
60240 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
60241 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
60242 +
60243 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
60244 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
60245 +
60246 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
60247 +
60248 +#define BMI_INT_BUF_MARG_SHIFT 28
60249 +
60250 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
60251 +
60252 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
60253 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
60254 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
60255 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
60256 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
60257 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
60258 +
60259 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
60260 +
60261 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
60262 +#define BMI_TX_LOW_COMF_SHIFT 0
60263 +
60264 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
60265 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
60266 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
60267 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
60268 +
60269 +#define BMI_MAX_BURST_SHIFT 16
60270 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
60271 +
60272 +/* sizes */
60273 +#define FRAME_END_DATA_SIZE 16
60274 +#define FRAME_OFFSET_UNITS 16
60275 +#define MIN_TX_INT_OFFSET 16
60276 +#define MAX_FRAME_OFFSET 64
60277 +#define MAX_FIFO_PIPELINE_DEPTH 8
60278 +#define MAX_PERFORMANCE_TASK_COMP 64
60279 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
60280 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
60281 +#define MAX_PERFORMANCE_DMA_COMP 16
60282 +#define MAX_NUM_OF_TASKS 64
60283 +#define MAX_NUM_OF_EXTRA_TASKS 8
60284 +#define MAX_NUM_OF_DMAS 16
60285 +#define MAX_NUM_OF_EXTRA_DMAS 8
60286 +#define MAX_BURST_SIZE 1024
60287 +#define MIN_NUM_OF_OP_DMAS 2
60288 +
60289 +
60290 +/**************************************************************************//**
60291 + @Description QMI defines
60292 +*//***************************************************************************/
60293 +/* masks */
60294 +#define QMI_PORT_CFG_EN 0x80000000
60295 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
60296 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
60297 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
60298 +
60299 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
60300 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
60301 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
60302 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
60303 +
60304 +#define QMI_DEQ_CFG_PRI 0x80000000
60305 +#define QMI_DEQ_CFG_TYPE1 0x10000000
60306 +#define QMI_DEQ_CFG_TYPE2 0x20000000
60307 +#define QMI_DEQ_CFG_TYPE3 0x30000000
60308 +
60309 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
60310 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
60311 +
60312 +/**************************************************************************//**
60313 + @Description PARSER defines
60314 +*//***************************************************************************/
60315 +/* masks */
60316 +#define PRS_HDR_ERROR_DIS 0x00000800
60317 +#define PRS_HDR_SW_PRS_EN 0x00000400
60318 +#define PRS_CP_OFFSET_MASK 0x0000000F
60319 +#define PRS_TPID1_MASK 0xFFFF0000
60320 +#define PRS_TPID2_MASK 0x0000FFFF
60321 +#define PRS_TPID_DFLT 0x91009100
60322 +
60323 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
60324 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
60325 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
60326 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
60327 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
60328 +#define PRS_CAC_STOP 0x00000001
60329 +#define PRS_CAC_ACTIVE 0x00000100
60330 +
60331 +/* shifts */
60332 +#define PRS_PCTPID_SHIFT 16
60333 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
60334 +#define PRS_HDR_ETH_BC_SHIFT 28
60335 +#define PRS_HDR_ETH_MC_SHIFT 24
60336 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
60337 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
60338 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
60339 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
60340 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
60341 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
60342 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
60343 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
60344 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
60345 +
60346 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
60347 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
60348 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
60349 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
60350 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
60351 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
60352 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
60353 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
60354 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
60355 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
60356 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
60357 +
60358 +/* others */
60359 +#define PRS_HDR_ENTRY_SIZE 8
60360 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
60361 +
60362 +#define IPSEC_SW_PATCH_START 0x20
60363 +#define SCTP_SW_PATCH_START 0x4D
60364 +#define DCCP_SW_PATCH_START 0x41
60365 +
60366 +/**************************************************************************//**
60367 + @Description IM defines
60368 +*//***************************************************************************/
60369 +#define BD_R_E 0x80000000
60370 +#define BD_L 0x08000000
60371 +
60372 +#define BD_RX_CRE 0x00080000
60373 +#define BD_RX_FTL 0x00040000
60374 +#define BD_RX_FTS 0x00020000
60375 +#define BD_RX_OV 0x00010000
60376 +
60377 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
60378 +
60379 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
60380 +
60381 +#define BD_STATUS_MASK 0xffff0000
60382 +#define BD_LENGTH_MASK 0x0000ffff
60383 +
60384 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
60385 +
60386 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
60387 +
60388 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
60389 +
60390 +#define IM_ILEGAL_BD_ID 0xffff
60391 +
60392 +/* others */
60393 +#define IM_PRAM_ALIGN 0x100
60394 +
60395 +/* masks */
60396 +#define IM_MODE_GBL 0x20000000
60397 +#define IM_MODE_BO_MASK 0x18000000
60398 +#define IM_MODE_BO_SHIFT 3
60399 +#define IM_MODE_GRC_STP 0x00800000
60400 +
60401 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
60402 +
60403 +#define IM_RXQD_BSYINTM 0x0008
60404 +#define IM_RXQD_RXFINTM 0x0010
60405 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
60406 +
60407 +#define IM_EV_BSY 0x40000000
60408 +#define IM_EV_RX 0x80000000
60409 +
60410 +
60411 +/**************************************************************************//**
60412 + @Description Additional defines
60413 +*//***************************************************************************/
60414 +
60415 +typedef struct {
60416 + t_Handle h_FmMuram;
60417 + t_FmPortImPram *p_FmPortImPram;
60418 + uint8_t fwExtStructsMemId;
60419 + uint32_t fwExtStructsMemAttr;
60420 + uint16_t bdRingSize;
60421 + t_FmImBd *p_BdRing;
60422 + t_Handle *p_BdShadow;
60423 + uint16_t currBdId;
60424 + uint16_t firstBdOfFrameId;
60425 +
60426 + /* Rx port parameters */
60427 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
60428 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
60429 + t_BufferPoolInfo rxPool;
60430 + uint16_t mrblr;
60431 + uint16_t rxFrameAccumLength;
60432 + t_FmPortImRxStoreCallback *f_RxStore;
60433 +
60434 + /* Tx port parameters */
60435 + uint32_t txFirstBdStatus;
60436 + t_FmPortImTxConfCallback *f_TxConf;
60437 +} t_FmMacIm;
60438 +
60439 +
60440 +typedef struct {
60441 + struct fman_port_cfg dfltCfg;
60442 + uint32_t dfltFqid;
60443 + uint32_t confFqid;
60444 + uint32_t errFqid;
60445 + uintptr_t baseAddr;
60446 + uint8_t deqSubPortal;
60447 + bool deqHighPriority;
60448 + e_FmPortDeqType deqType;
60449 + e_FmPortDeqPrefetchOption deqPrefetchOption;
60450 + uint16_t deqByteCnt;
60451 + uint8_t cheksumLastBytesIgnore;
60452 + uint8_t cutBytesFromEnd;
60453 + t_FmBufPoolDepletion bufPoolDepletion;
60454 + uint8_t pipelineDepth;
60455 + uint16_t fifoLowComfLevel;
60456 + bool frmDiscardOverride;
60457 + bool enRateLimit;
60458 + t_FmPortRateLimit rateLimit;
60459 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
60460 + bool enBufPoolDepletion;
60461 + uint16_t liodnOffset;
60462 + uint16_t liodnBase;
60463 + t_FmExtPools extBufPools;
60464 + e_FmDmaSwapOption dmaSwapData;
60465 + e_FmDmaCacheOption dmaIntContextCacheAttr;
60466 + e_FmDmaCacheOption dmaHeaderCacheAttr;
60467 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
60468 + bool dmaReadOptimize;
60469 + bool dmaWriteOptimize;
60470 + uint32_t txFifoMinFillLevel;
60471 + uint32_t txFifoLowComfLevel;
60472 + uint32_t rxFifoPriElevationLevel;
60473 + uint32_t rxFifoThreshold;
60474 + t_FmSpBufMargins bufMargins;
60475 + t_FmSpIntContextDataCopy intContext;
60476 + bool syncReq;
60477 + e_FmPortColor color;
60478 + fmPortFrameErrSelect_t errorsToDiscard;
60479 + fmPortFrameErrSelect_t errorsToEnq;
60480 + bool forwardReuseIntContext;
60481 + t_FmBufferPrefixContent bufferPrefixContent;
60482 + t_FmBackupBmPools *p_BackupBmPools;
60483 + bool dontReleaseBuf;
60484 + bool setNumOfTasks;
60485 + bool setNumOfOpenDmas;
60486 + bool setSizeOfFifo;
60487 +#if (DPAA_VERSION >= 11)
60488 + bool noScatherGather;
60489 +#endif /* (DPAA_VERSION >= 11) */
60490 +
60491 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
60492 + bool bcbWorkaround;
60493 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
60494 +} t_FmPortDriverParam;
60495 +
60496 +
60497 +typedef struct t_FmPortRxPoolsParams
60498 +{
60499 + uint8_t numOfPools;
60500 + uint16_t secondLargestBufSize;
60501 + uint16_t largestBufSize;
60502 +} t_FmPortRxPoolsParams;
60503 +
60504 +typedef struct t_FmPortDsarVars {
60505 + t_Handle *autoResOffsets;
60506 + t_FmPortDsarTablesSizes *autoResMaxSizes;
60507 + uint32_t fmbm_tcfg;
60508 + uint32_t fmbm_tcmne;
60509 + uint32_t fmbm_rfne;
60510 + uint32_t fmbm_rfpne;
60511 + uint32_t fmbm_rcfg;
60512 + bool dsarEnabledParser;
60513 +} t_FmPortDsarVars;
60514 +typedef struct {
60515 + struct fman_port port;
60516 + t_Handle h_Fm;
60517 + t_Handle h_FmPcd;
60518 + t_Handle h_FmMuram;
60519 + t_FmRevisionInfo fmRevInfo;
60520 + uint8_t portId;
60521 + e_FmPortType portType;
60522 + int enabled;
60523 + char name[MODULE_NAME_SIZE];
60524 + uint8_t hardwarePortId;
60525 + uint16_t fmClkFreq;
60526 + t_FmPortQmiRegs *p_FmPortQmiRegs;
60527 + u_FmPortBmiRegs *p_FmPortBmiRegs;
60528 + t_FmPortPrsRegs *p_FmPortPrsRegs;
60529 + fmPcdEngines_t pcdEngines;
60530 + uint32_t savedBmiNia;
60531 + uint8_t netEnvId;
60532 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
60533 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
60534 + uint8_t privateInfo;
60535 + uint32_t schemesPerPortVector;
60536 + bool useClsPlan;
60537 + uint8_t clsPlanGrpId;
60538 + t_Handle ccTreeId;
60539 + t_Handle completeArg;
60540 + void (*f_Complete)(t_Handle arg);
60541 + t_FmSpBufferOffsets bufferOffsets;
60542 + /* Independent-Mode parameters support */
60543 + bool imEn;
60544 + t_FmMacIm im;
60545 + volatile bool lock;
60546 + t_Handle h_Spinlock;
60547 + t_FmPortExceptionCallback *f_Exception;
60548 + t_Handle h_App;
60549 + uint8_t internalBufferOffset;
60550 + uint8_t fmanCtrlEventId;
60551 + uint32_t exceptions;
60552 + bool polling;
60553 + t_FmExtPools extBufPools;
60554 + uint32_t requiredAction;
60555 + uint32_t savedQmiPnen;
60556 + uint32_t savedBmiFene;
60557 + uint32_t savedBmiFpne;
60558 + uint32_t savedBmiCmne;
60559 + uint32_t savedBmiOfp;
60560 + uint32_t savedNonRxQmiRegsPndn;
60561 + uint32_t origNonRxQmiRegsPndn;
60562 + int savedPrsStartOffset;
60563 + bool includeInPrsStatistics;
60564 + uint16_t maxFrameLength;
60565 + t_FmFmanCtrl orFmanCtrl;
60566 + t_FmPortRsrc openDmas;
60567 + t_FmPortRsrc tasks;
60568 + t_FmPortRsrc fifoBufs;
60569 + t_FmPortRxPoolsParams rxPoolsParams;
60570 +// bool explicitUserSizeOfFifo;
60571 + t_Handle h_IpReassemblyManip;
60572 + t_Handle h_CapwapReassemblyManip;
60573 + t_Handle h_ReassemblyTree;
60574 + uint64_t fmMuramPhysBaseAddr;
60575 +#if (DPAA_VERSION >= 11)
60576 + bool vspe;
60577 + uint8_t dfltRelativeId;
60578 + e_FmPortGprFuncType gprFunc;
60579 + t_FmPcdCtrlParamsPage *p_ParamsPage;
60580 +#endif /* (DPAA_VERSION >= 11) */
60581 + t_FmPortDsarVars deepSleepVars;
60582 + t_FmPortDriverParam *p_FmPortDriverParam;
60583 +} t_FmPort;
60584 +
60585 +
60586 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
60587 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
60588 +
60589 +t_Error FmPortImInit(t_FmPort *p_FmPort);
60590 +void FmPortImFree(t_FmPort *p_FmPort);
60591 +
60592 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
60593 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
60594 +t_Error FmPortImRx (t_FmPort *p_FmPort);
60595 +
60596 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
60597 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
60598 +
60599 +
60600 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
60601 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
60602 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
60603 +
60604 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
60605 +{
60606 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
60607 + physAddr |= GET_UINT32(p_Bd->buff.low);
60608 +
60609 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
60610 +}
60611 +
60612 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
60613 +{
60614 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
60615 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
60616 +}
60617 +
60618 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
60619 +{
60620 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
60621 + SET_ADDR(&p_Bd->buff, physAddr);
60622 +}
60623 +
60624 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
60625 +{
60626 + if (id < p_FmPort->im.bdRingSize-1)
60627 + return (uint16_t)(id+1);
60628 + else
60629 + return 0;
60630 +}
60631 +
60632 +void FM_PORT_Dsar_DumpRegs(void);
60633 +
60634 +
60635 +#endif /* __FM_PORT_H */
60636 --- /dev/null
60637 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
60638 @@ -0,0 +1,494 @@
60639 +/*
60640 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60641 + *
60642 + * Redistribution and use in source and binary forms, with or without
60643 + * modification, are permitted provided that the following conditions are met:
60644 + * * Redistributions of source code must retain the above copyright
60645 + * notice, this list of conditions and the following disclaimer.
60646 + * * Redistributions in binary form must reproduce the above copyright
60647 + * notice, this list of conditions and the following disclaimer in the
60648 + * documentation and/or other materials provided with the distribution.
60649 + * * Neither the name of Freescale Semiconductor nor the
60650 + * names of its contributors may be used to endorse or promote products
60651 + * derived from this software without specific prior written permission.
60652 + *
60653 + *
60654 + * ALTERNATIVELY, this software may be distributed under the terms of the
60655 + * GNU General Public License ("GPL") as published by the Free Software
60656 + * Foundation, either version 2 of that License or (at your option) any
60657 + * later version.
60658 + *
60659 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60660 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60661 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60662 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60663 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60664 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60665 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60666 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60667 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60668 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60669 + */
60670 +
60671 +/**************************************************************************//**
60672 + @File fm_port_dsar.h
60673 +
60674 + @Description Deep Sleep Auto Response project - common module header file.
60675 +
60676 + Author - Eyal Harari
60677 +
60678 + @Cautions See the FMan Controller spec and design document for more information.
60679 +*//***************************************************************************/
60680 +
60681 +#ifndef __FM_PORT_DSAR_H_
60682 +#define __FM_PORT_DSAR_H_
60683 +
60684 +#define DSAR_GETSER_MASK 0xFF0000FF
60685 +
60686 +#if defined(__MWERKS__) && !defined(__GNUC__)
60687 +#pragma pack(push,1)
60688 +#endif /* defined(__MWERKS__) && ... */
60689 +
60690 +/**************************************************************************//**
60691 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
60692 + Refer to the FMan Controller spec for more details.
60693 +*//***************************************************************************/
60694 +typedef _Packed struct
60695 +{
60696 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
60697 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
60698 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
60699 + uint16_t reserved;
60700 +} _PackedType t_DsarArpBindingEntry;
60701 +
60702 +/**************************************************************************//**
60703 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
60704 + Refer to the FMan Controller spec for more details.
60705 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
60706 + 0x04 ECHO_CNT Echo counter
60707 + 0x08 CD_CNT Conflict Detection counter
60708 + 0x0C AR_CNT Auto-Response counter
60709 + 0x10 RATM_CNT Replies Addressed To Me counter
60710 + 0x14 UKOP_CNT Unknown Operation counter
60711 + 0x18 NMTP_CNT Not my TPA counter
60712 + 0x1C NMVLAN_CNT Not My VLAN counter
60713 +*//***************************************************************************/
60714 +typedef _Packed struct
60715 +{
60716 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
60717 + uint32_t echoCnt; /**< Echo counter. */
60718 + uint32_t cdCnt; /**< Conflict Detection counter. */
60719 + uint32_t arCnt; /**< Auto-Response counter. */
60720 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
60721 + uint32_t ukopCnt; /**< Unknown Operation counter. */
60722 + uint32_t nmtpCnt; /**< Not my TPA counter. */
60723 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
60724 +} _PackedType t_DsarArpStatistics;
60725 +
60726 +
60727 +/**************************************************************************//**
60728 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
60729 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
60730 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
60731 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
60732 + 0x6 0-15
60733 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
60734 + 0xA 0-15
60735 + 0xC 0-15 Reserved Reserved. Must be cleared.
60736 + 0xE 015
60737 +
60738 +*//***************************************************************************/
60739 +typedef _Packed struct
60740 +{
60741 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
60742 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
60743 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
60744 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
60745 + uint32_t reserved1; /**< Reserved. */
60746 +} _PackedType t_DsarArpDescriptor;
60747 +
60748 +
60749 +/**************************************************************************//**
60750 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
60751 + Refer to the FMan Controller spec for more details.
60752 +*//***************************************************************************/
60753 +typedef _Packed struct
60754 +{
60755 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
60756 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
60757 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
60758 + uint16_t reserved;
60759 +} _PackedType t_DsarIcmpV4BindingEntry;
60760 +
60761 +/**************************************************************************//**
60762 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
60763 + Refer to the FMan Controller spec for more details.
60764 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
60765 + 0x04 NMVLAN_CNT Not My VLAN counter
60766 + 0x08 NMIP_CNT Not My IP counter
60767 + 0x0C AR_CNT Auto-Response counter
60768 + 0x10 CSERR_CNT Checksum Error counter
60769 + 0x14 Reserved Reserved
60770 + 0x18 Reserved Reserved
60771 + 0x1C Reserved Reserved
60772 +
60773 +*//***************************************************************************/
60774 +typedef _Packed struct
60775 +{
60776 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
60777 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
60778 + uint32_t nmIpCnt; /**< Not My IP counter */
60779 + uint32_t arCnt; /**< Auto-Response counter */
60780 + uint32_t cserrCnt; /**< Checksum Error counter */
60781 + uint32_t reserved0; /**< Reserved */
60782 + uint32_t reserved1; /**< Reserved */
60783 + uint32_t reserved2; /**< Reserved */
60784 +} _PackedType t_DsarIcmpV4Statistics;
60785 +
60786 +
60787 +
60788 +/**************************************************************************//**
60789 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
60790 + 0x0 0-15 Control bits [0-15]
60791 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
60792 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
60793 + 0x6 0-15
60794 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
60795 + 0xA 0-15
60796 + 0xC 0-15 Reserved Reserved. Must be cleared.
60797 + 0xE 015
60798 +
60799 +*//***************************************************************************/
60800 +typedef _Packed struct
60801 +{
60802 + uint16_t control; /** Control bits [0-15]. */
60803 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
60804 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
60805 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
60806 + uint32_t reserved1; /**< Reserved. */
60807 +} _PackedType t_DsarIcmpV4Descriptor;
60808 +
60809 +/**************************************************************************//**
60810 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
60811 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
60812 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
60813 + Flags[0] (VlanId[12]): Temporary address.
60814 + \95 0 - Assigned IP address.
60815 + \95 1- Temporary (tentative) IP address.
60816 + Refer to the FMan Controller spec for more details.
60817 +*//***************************************************************************/
60818 +typedef _Packed struct
60819 +{
60820 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
60821 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
60822 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
60823 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
60824 + uint16_t reserved;
60825 +} _PackedType t_DsarIcmpV6BindingEntry;
60826 +
60827 +/**************************************************************************//**
60828 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
60829 + Refer to the FMan Controller spec for more details.
60830 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
60831 + 0x04 NMVLAN_CNT Not My VLAN counter
60832 + 0x08 NMIP_CNT Not My IP counter
60833 + 0x0C AR_CNT Auto-Response counter
60834 + 0x10 CSERR_CNT Checksum Error counter
60835 + 0x14 MCAST_CNT Multicast counter
60836 + 0x18 Reserved Reserved
60837 + 0x1C Reserved Reserved
60838 +
60839 +*//***************************************************************************/
60840 +typedef _Packed struct
60841 +{
60842 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
60843 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
60844 + uint32_t nmIpCnt; /**< Not My IP counter */
60845 + uint32_t arCnt; /**< Auto-Response counter */
60846 + uint32_t reserved1; /**< Reserved */
60847 + uint32_t reserved2; /**< Reserved */
60848 + uint32_t reserved3; /**< Reserved */
60849 + uint32_t reserved4; /**< Reserved */
60850 +} _PackedType t_DsarIcmpV6Statistics;
60851 +
60852 +/**************************************************************************//**
60853 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
60854 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
60855 + 0x04 NMVLAN_CNT Not My VLAN counter
60856 + 0x08 NMIP_CNT Not My IP counter
60857 + 0x0C AR_CNT Auto-Response counter
60858 + 0x10 CSERR_CNT Checksum Error counter
60859 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
60860 + 0x18 NMMCAST_CNT Not My Multicast group counter
60861 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
60862 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
60863 + Source Link-layer Address option is omitted
60864 +*//***************************************************************************/
60865 +typedef _Packed struct
60866 +{
60867 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
60868 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
60869 + uint32_t nmIpCnt; /**< Not My IP counter */
60870 + uint32_t arCnt; /**< Auto-Response counter */
60871 + uint32_t reserved1; /**< Reserved */
60872 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
60873 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
60874 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
60875 +} _PackedType t_NdStatistics;
60876 +
60877 +/**************************************************************************//**
60878 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
60879 + 0x0 0-15 Control bits [0-15]
60880 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
60881 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
60882 + 0x6 0-15
60883 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
60884 + 0xA 0-15
60885 + 0xC 0-15 Reserved Reserved. Must be cleared.
60886 + 0xE 015
60887 +
60888 +*//***************************************************************************/
60889 +typedef _Packed struct
60890 +{
60891 + uint16_t control; /** Control bits [0-15]. */
60892 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
60893 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
60894 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
60895 + uint32_t reserved1; /**< Reserved. */
60896 +} _PackedType t_DsarIcmpV6Descriptor;
60897 +
60898 +
60899 +/**************************************************************************//**
60900 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
60901 + The fields names are taken from RFC 4443.
60902 +*//***************************************************************************/
60903 +/* 0 1 2 3 */
60904 +/* 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 */
60905 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
60906 +/* | Type | Code | Checksum | */
60907 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
60908 +/* | Identifier | Sequence Number | */
60909 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
60910 +/* | Data ... */
60911 +/* +-+-+-+-+- */
60912 +typedef _Packed struct
60913 +{
60914 + uint8_t type;
60915 + uint8_t code;
60916 + uint16_t checksum;
60917 + uint16_t identifier;
60918 + uint16_t sequenceNumber;
60919 +} _PackedType t_IcmpV6EchoHdr;
60920 +
60921 +/**************************************************************************//**
60922 + @Description Internet Control Message Protocol (ICMPv6)
60923 + Neighbor Solicitation/Advertisement header
60924 + The fields names are taken from RFC 4861.
60925 + The R/S/O fields are valid for Neighbor Advertisement only
60926 +*//***************************************************************************/
60927 +/* 0 1 2 3
60928 + * 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
60929 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60930 + * | Type | Code | Checksum |
60931 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60932 + * |R|S|O| Reserved |
60933 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60934 + * | |
60935 + * + +
60936 + * | |
60937 + * + Target Address +
60938 + * | |
60939 + * + +
60940 + * | |
60941 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60942 + * | Options ...
60943 + * +-+-+-+-+-+-+-+-+-+-+-+-
60944 + *
60945 + * Options Format:
60946 + * 0 1 2 3
60947 + * 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
60948 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60949 + * | Type | Length | Link-Layer Address ... |
60950 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60951 + * | Link-Layer Address |
60952 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60953 +*/
60954 +typedef _Packed struct
60955 +{
60956 + uint8_t type;
60957 + uint8_t code;
60958 + uint16_t checksum;
60959 + uint32_t router:1;
60960 + uint32_t solicited:1;
60961 + uint32_t override:1;
60962 + uint32_t reserved:29;
60963 + uint32_t targetAddr[4];
60964 + uint8_t optionType;
60965 + uint8_t optionLength;
60966 + uint8_t linkLayerAddr[6];
60967 +} _PackedType t_IcmpV6NdHdr;
60968 +
60969 +/**************************************************************************//**
60970 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
60971 + 0x0 0-15 Control bits [0-15]
60972 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
60973 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
60974 + 0x6 0-15
60975 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
60976 + 0xA 0-15
60977 + 0xC 0-15 Reserved Reserved. Must be cleared.
60978 + 0xE 015
60979 +
60980 +*//***************************************************************************/
60981 +typedef _Packed struct
60982 +{
60983 + uint16_t control; /** Control bits [0-15]. */
60984 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
60985 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
60986 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
60987 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
60988 +} _PackedType t_DsarNdDescriptor;
60989 +
60990 +/**************************************************************************//**
60991 +@Description Deep Sleep Auto Response SNMP OIDs table entry
60992 +
60993 +*//***************************************************************************/
60994 +typedef struct {
60995 + uint16_t oidSize; /**< Size in octets of the OID. */
60996 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
60997 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
60998 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
60999 + uint32_t reserved;
61000 +} t_OidsTblEntry;
61001 +
61002 +/**************************************************************************//**
61003 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
61004 + Refer to the FMan Controller spec for more details.
61005 +*//***************************************************************************/
61006 +typedef struct
61007 +{
61008 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
61009 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
61010 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
61011 + uint16_t reserved;
61012 +} t_DsarSnmpIpv4AddrTblEntry;
61013 +
61014 +/**************************************************************************//**
61015 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
61016 + Refer to the FMan Controller spec for more details.
61017 +*//***************************************************************************/
61018 +#pragma pack(push,1)
61019 +typedef struct
61020 +{
61021 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
61022 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
61023 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
61024 + uint16_t reserved;
61025 +} t_DsarSnmpIpv6AddrTblEntry;
61026 +#pragma pack(pop)
61027 +
61028 +/**************************************************************************//**
61029 +@Description Deep Sleep Auto Response SNMP statistics table
61030 +
61031 +*//***************************************************************************/
61032 +typedef struct {
61033 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
61034 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
61035 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
61036 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
61037 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
61038 +} t_DsarSnmpStatistics;
61039 +
61040 +/**************************************************************************//**
61041 + @Description Deep Sleep Auto Response SNMP Descriptor
61042 +
61043 +*//***************************************************************************/
61044 +typedef struct
61045 +{
61046 + uint16_t control; /**< Control bits [0-15]. */
61047 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
61048 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
61049 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
61050 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
61051 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
61052 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
61053 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
61054 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
61055 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
61056 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
61057 +} t_DsarSnmpDescriptor;
61058 +
61059 +/**************************************************************************//**
61060 +@Description Deep Sleep Auto Response (Common) Statistics
61061 +
61062 +*//***************************************************************************/
61063 +typedef _Packed struct {
61064 + uint32_t dsarDiscarded;
61065 + uint32_t dsarErrDiscarded;
61066 + uint32_t dsarFragDiscarded;
61067 + uint32_t dsarTunnelDiscarded;
61068 + uint32_t dsarArpDiscarded;
61069 + uint32_t dsarIpDiscarded;
61070 + uint32_t dsarTcpDiscarded;
61071 + uint32_t dsarUdpDiscarded;
61072 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
61073 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
61074 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
61075 +} _PackedType t_ArStatistics;
61076 +
61077 +
61078 +/**************************************************************************//**
61079 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
61080 +
61081 +*//***************************************************************************/
61082 +typedef _Packed struct {
61083 + uint32_t Ports;
61084 + uint32_t PortsMask;
61085 +} _PackedType t_PortTblEntry;
61086 +
61087 +
61088 +
61089 +/**************************************************************************//**
61090 +@Description Deep Sleep Auto Response Common Parameters Descriptor
61091 +
61092 +*//***************************************************************************/
61093 +typedef _Packed struct {
61094 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
61095 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
61096 + uint16_t res1; /* 0x00 16-31 Reserved */
61097 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
61098 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
61099 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
61100 + uint8_t res2; /* 0x10 0-7 Reserved */
61101 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
61102 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
61103 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
61104 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
61105 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
61106 + uint8_t res3; /* 0x14 24-31 Reserved */
61107 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
61108 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
61109 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
61110 + uint32_t res4; /* 0x24 Reserved */
61111 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
61112 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
61113 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
61114 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
61115 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
61116 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
61117 +} _PackedType t_ArCommonDesc;
61118 +
61119 +#if defined(__MWERKS__) && !defined(__GNUC__)
61120 +#pragma pack(pop)
61121 +#endif /* defined(__MWERKS__) && ... */
61122 +
61123 +/* t_ArCommonDesc.filterControl bits */
61124 +#define IP_PROT_TBL_PASS_MASK 0x08
61125 +#define UDP_PORT_TBL_PASS_MASK 0x04
61126 +#define TCP_PORT_TBL_PASS_MASK 0x02
61127 +
61128 +/* Offset of TCF flags within TCP packet */
61129 +#define TCP_FLAGS_OFFSET 12
61130 +
61131 +
61132 +#endif /* __FM_PORT_DSAR_H_ */
61133 --- /dev/null
61134 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
61135 @@ -0,0 +1,753 @@
61136 +/*
61137 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61138 + *
61139 + * Redistribution and use in source and binary forms, with or without
61140 + * modification, are permitted provided that the following conditions are met:
61141 + * * Redistributions of source code must retain the above copyright
61142 + * notice, this list of conditions and the following disclaimer.
61143 + * * Redistributions in binary form must reproduce the above copyright
61144 + * notice, this list of conditions and the following disclaimer in the
61145 + * documentation and/or other materials provided with the distribution.
61146 + * * Neither the name of Freescale Semiconductor nor the
61147 + * names of its contributors may be used to endorse or promote products
61148 + * derived from this software without specific prior written permission.
61149 + *
61150 + *
61151 + * ALTERNATIVELY, this software may be distributed under the terms of the
61152 + * GNU General Public License ("GPL") as published by the Free Software
61153 + * Foundation, either version 2 of that License or (at your option) any
61154 + * later version.
61155 + *
61156 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
61157 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
61158 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61159 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
61160 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61161 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61162 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61163 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61164 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61165 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61166 + */
61167 +
61168 +
61169 +/******************************************************************************
61170 + @File fm_port_im.c
61171 +
61172 + @Description FM Port Independent-Mode ...
61173 +*//***************************************************************************/
61174 +#include "std_ext.h"
61175 +#include "string_ext.h"
61176 +#include "error_ext.h"
61177 +#include "memcpy_ext.h"
61178 +#include "fm_muram_ext.h"
61179 +
61180 +#include "fm_port.h"
61181 +
61182 +
61183 +#define TX_CONF_STATUS_UNSENT 0x1
61184 +
61185 +
61186 +typedef enum e_TxConfType
61187 +{
61188 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
61189 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
61190 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
61191 +} e_TxConfType;
61192 +
61193 +
61194 +static void ImException(t_Handle h_FmPort, uint32_t event)
61195 +{
61196 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61197 +
61198 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
61199 + !FmIsMaster(p_FmPort->h_Fm));
61200 +
61201 + if (event & IM_EV_RX)
61202 + FmPortImRx(p_FmPort);
61203 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
61204 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
61205 +}
61206 +
61207 +
61208 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
61209 +{
61210 + t_Error retVal = E_BUSY;
61211 + uint32_t bdStatus;
61212 + uint16_t savedStartBdId, confBdId;
61213 +
61214 + ASSERT_COND(p_FmPort);
61215 +
61216 + /*
61217 + if (confType==e_TX_CONF_TYPE_CHECK)
61218 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
61219 + */
61220 +
61221 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
61222 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
61223 +
61224 + /* If R bit is set, we don't enter, or we break.
61225 + we run till we get to R, or complete the loop */
61226 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
61227 + {
61228 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
61229 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
61230 +
61231 + /* case 1: R bit is 0 and Length is set -> confirm! */
61232 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
61233 + {
61234 + if (p_FmPort->im.f_TxConf)
61235 + {
61236 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
61237 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
61238 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
61239 + TX_CONF_STATUS_UNSENT,
61240 + p_FmPort->im.p_BdShadow[confBdId]);
61241 + else
61242 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
61243 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
61244 + 0,
61245 + p_FmPort->im.p_BdShadow[confBdId]);
61246 + }
61247 + }
61248 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
61249 +
61250 + confBdId = GetNextBdId(p_FmPort, confBdId);
61251 + if (confBdId == savedStartBdId)
61252 + retVal = E_OK;
61253 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
61254 + }
61255 +
61256 + return retVal;
61257 +}
61258 +
61259 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
61260 +{
61261 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
61262 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
61263 + return E_OK;
61264 +}
61265 +
61266 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
61267 +{
61268 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
61269 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
61270 + return E_OK;
61271 +}
61272 +
61273 +t_Error FmPortImRx(t_FmPort *p_FmPort)
61274 +{
61275 + t_Handle h_CurrUserPriv, h_NewUserPriv;
61276 + uint32_t bdStatus;
61277 + volatile uint8_t buffPos;
61278 + uint16_t length;
61279 + uint16_t errors;
61280 + uint8_t *p_CurData, *p_Data;
61281 + uint32_t flags;
61282 +
61283 + ASSERT_COND(p_FmPort);
61284 +
61285 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
61286 + if (p_FmPort->lock)
61287 + {
61288 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
61289 + return E_OK;
61290 + }
61291 + p_FmPort->lock = TRUE;
61292 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
61293 +
61294 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61295 +
61296 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
61297 + {
61298 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
61299 + {
61300 + p_FmPort->lock = FALSE;
61301 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
61302 + }
61303 +
61304 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
61305 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
61306 +
61307 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
61308 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
61309 + length = (uint16_t)((bdStatus & BD_L) ?
61310 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
61311 + (bdStatus & BD_LENGTH_MASK));
61312 + p_FmPort->im.rxFrameAccumLength += length;
61313 +
61314 + /* determine whether buffer is first, last, first and last (single */
61315 + /* buffer frame) or middle (not first and not last) */
61316 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
61317 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
61318 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
61319 +
61320 + if (bdStatus & BD_L)
61321 + {
61322 + p_FmPort->im.rxFrameAccumLength = 0;
61323 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
61324 + }
61325 +
61326 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
61327 +
61328 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
61329 +
61330 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
61331 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
61332 +
61333 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
61334 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
61335 + /* Pass the buffer if one of the conditions is true:
61336 + - There are no errors
61337 + - This is a part of a larger frame ( the application has already received some buffers ) */
61338 + if ((buffPos != SINGLE_BUF) || !errors)
61339 + {
61340 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
61341 + p_CurData,
61342 + length,
61343 + errors,
61344 + buffPos,
61345 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
61346 + break;
61347 + }
61348 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
61349 + p_CurData,
61350 + h_CurrUserPriv))
61351 + {
61352 + p_FmPort->lock = FALSE;
61353 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
61354 + }
61355 +
61356 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61357 + }
61358 + p_FmPort->lock = FALSE;
61359 + return E_OK;
61360 +}
61361 +
61362 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
61363 +{
61364 + ASSERT_COND(p_FmPort);
61365 +
61366 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61367 +
61368 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
61369 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
61370 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
61371 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
61372 +
61373 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
61374 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
61375 +
61376 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61377 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61378 + {
61379 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
61380 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
61381 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
61382 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
61383 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
61384 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
61385 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
61386 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
61387 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
61388 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
61389 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
61390 +
61391 + p_FmPort->im.mrblr = 0x8000;
61392 + while (p_FmPort->im.mrblr)
61393 + {
61394 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
61395 + break;
61396 + p_FmPort->im.mrblr >>= 1;
61397 + }
61398 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
61399 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
61400 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
61401 + p_FmPort->exceptions = DEFAULT_PORT_exception;
61402 + if (FmIsMaster(p_FmPort->h_Fm))
61403 + p_FmPort->polling = FALSE;
61404 + else
61405 + p_FmPort->polling = TRUE;
61406 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
61407 + }
61408 + else
61409 + {
61410 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
61411 +
61412 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
61413 + }
61414 +}
61415 +
61416 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
61417 +{
61418 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
61419 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
61420 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
61421 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
61422 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
61423 +
61424 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61425 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61426 + {
61427 + if (!POWER_OF_2(p_FmPort->im.mrblr))
61428 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
61429 + if (p_FmPort->im.mrblr < 256)
61430 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
61431 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
61432 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
61433 + }
61434 +
61435 + return E_OK;
61436 +}
61437 +
61438 +t_Error FmPortImInit(t_FmPort *p_FmPort)
61439 +{
61440 + t_FmImBd *p_Bd=NULL;
61441 + t_Handle h_BufContext;
61442 + uint64_t tmpPhysBase;
61443 + uint16_t log2Num;
61444 + uint8_t *p_Data/*, *p_Tmp*/;
61445 + int i;
61446 + t_Error err;
61447 + uint16_t tmpReg16;
61448 + uint32_t tmpReg32;
61449 +
61450 + ASSERT_COND(p_FmPort);
61451 +
61452 + p_FmPort->im.p_FmPortImPram =
61453 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
61454 + if (!p_FmPort->im.p_FmPortImPram)
61455 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
61456 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
61457 +
61458 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61459 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61460 + {
61461 + p_FmPort->im.p_BdRing =
61462 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
61463 + p_FmPort->im.fwExtStructsMemId,
61464 + 4);
61465 + if (!p_FmPort->im.p_BdRing)
61466 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
61467 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61468 +
61469 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61470 + if (!p_FmPort->im.p_BdShadow)
61471 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
61472 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61473 +
61474 + /* Initialize the Rx-BD ring */
61475 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
61476 + {
61477 + p_Bd = BD_GET(i);
61478 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
61479 +
61480 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
61481 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
61482 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
61483 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
61484 + }
61485 +
61486 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
61487 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
61488 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
61489 + else
61490 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
61491 +
61492 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
61493 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61494 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
61495 +
61496 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
61497 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
61498 +
61499 + /* Initialize Rx QD */
61500 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
61501 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
61502 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61503 +
61504 + /* Update the IM PRAM address in the BMI */
61505 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
61506 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61507 + p_FmPort->fmMuramPhysBaseAddr));
61508 + if (!p_FmPort->polling || p_FmPort->exceptions)
61509 + {
61510 + /* Allocate, configure and register interrupts */
61511 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
61512 + if (err)
61513 + RETURN_ERROR(MAJOR, err, NO_MSG);
61514 +
61515 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
61516 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
61517 + tmpReg32 = 0;
61518 +
61519 + if (p_FmPort->exceptions & IM_EV_BSY)
61520 + {
61521 + tmpReg16 |= IM_RXQD_BSYINTM;
61522 + tmpReg32 |= IM_EV_BSY;
61523 + }
61524 + if (!p_FmPort->polling)
61525 + {
61526 + tmpReg16 |= IM_RXQD_RXFINTM;
61527 + tmpReg32 |= IM_EV_RX;
61528 + }
61529 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
61530 +
61531 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
61532 +
61533 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
61534 + }
61535 + else
61536 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
61537 + }
61538 + else
61539 + {
61540 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
61541 + if (!p_FmPort->im.p_BdRing)
61542 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
61543 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61544 +
61545 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61546 + if (!p_FmPort->im.p_BdShadow)
61547 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
61548 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61549 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
61550 +
61551 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
61552 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
61553 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
61554 + else
61555 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
61556 +
61557 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
61558 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61559 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
61560 +
61561 + /* Initialize Tx QD */
61562 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
61563 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
61564 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61565 +
61566 + /* Update the IM PRAM address in the BMI */
61567 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
61568 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61569 + p_FmPort->fmMuramPhysBaseAddr));
61570 + }
61571 +
61572 +
61573 + return E_OK;
61574 +}
61575 +
61576 +void FmPortImFree(t_FmPort *p_FmPort)
61577 +{
61578 + uint32_t bdStatus;
61579 + uint8_t *p_CurData;
61580 +
61581 + ASSERT_COND(p_FmPort);
61582 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
61583 +
61584 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61585 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61586 + {
61587 + if (!p_FmPort->polling || p_FmPort->exceptions)
61588 + {
61589 + /* Deallocate and unregister interrupts */
61590 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
61591 +
61592 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
61593 +
61594 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
61595 +
61596 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
61597 + }
61598 + /* Try first clean what has received */
61599 + FmPortImRx(p_FmPort);
61600 +
61601 + /* Now, get rid of the the empty buffer! */
61602 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61603 +
61604 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
61605 + {
61606 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
61607 +
61608 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
61609 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
61610 +
61611 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
61612 + p_CurData,
61613 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
61614 +
61615 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
61616 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61617 + }
61618 + }
61619 + else
61620 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
61621 +
61622 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
61623 +
61624 + if (p_FmPort->im.p_BdShadow)
61625 + XX_Free(p_FmPort->im.p_BdShadow);
61626 +
61627 + if (p_FmPort->im.p_BdRing)
61628 + XX_FreeSmart(p_FmPort->im.p_BdRing);
61629 +}
61630 +
61631 +
61632 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
61633 +{
61634 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61635 +
61636 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61637 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61638 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61639 +
61640 + p_FmPort->im.mrblr = newVal;
61641 +
61642 + return E_OK;
61643 +}
61644 +
61645 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
61646 +{
61647 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61648 +
61649 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61650 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61651 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61652 +
61653 + p_FmPort->im.bdRingSize = newVal;
61654 +
61655 + return E_OK;
61656 +}
61657 +
61658 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
61659 +{
61660 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61661 +
61662 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61663 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61664 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61665 +
61666 + p_FmPort->im.bdRingSize = newVal;
61667 +
61668 + return E_OK;
61669 +}
61670 +
61671 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
61672 + uint8_t memId,
61673 + uint32_t memAttributes)
61674 +{
61675 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61676 +
61677 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61678 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61679 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61680 +
61681 + p_FmPort->im.fwExtStructsMemId = memId;
61682 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
61683 +
61684 + return E_OK;
61685 +}
61686 +
61687 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
61688 +{
61689 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61690 +
61691 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61692 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61693 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61694 +
61695 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
61696 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
61697 +
61698 + if (!FmIsMaster(p_FmPort->h_Fm))
61699 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
61700 + "in guest-partitions, IM is always in polling!"));
61701 +
61702 + p_FmPort->polling = TRUE;
61703 +
61704 + return E_OK;
61705 +}
61706 +
61707 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
61708 +{
61709 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61710 + t_Error err;
61711 + uint16_t tmpReg16;
61712 + uint32_t tmpReg32;
61713 +
61714 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61715 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61716 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61717 +
61718 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
61719 + {
61720 + if (enable)
61721 + {
61722 + p_FmPort->exceptions |= IM_EV_BSY;
61723 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
61724 + {
61725 + /* Allocate, configure and register interrupts */
61726 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
61727 + if (err)
61728 + RETURN_ERROR(MAJOR, err, NO_MSG);
61729 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
61730 +
61731 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
61732 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
61733 + tmpReg32 = IM_EV_BSY;
61734 + }
61735 + else
61736 + {
61737 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
61738 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
61739 + }
61740 +
61741 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
61742 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
61743 + }
61744 + else
61745 + {
61746 + p_FmPort->exceptions &= ~IM_EV_BSY;
61747 + if (!p_FmPort->exceptions && p_FmPort->polling)
61748 + {
61749 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
61750 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
61751 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
61752 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
61753 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
61754 + }
61755 + else
61756 + {
61757 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
61758 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
61759 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
61760 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
61761 + }
61762 + }
61763 + }
61764 + else
61765 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
61766 +
61767 + return E_OK;
61768 +}
61769 +
61770 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
61771 + uint8_t *p_Data,
61772 + uint16_t length,
61773 + bool lastBuffer,
61774 + t_Handle h_BufContext)
61775 +{
61776 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61777 + uint16_t nextBdId;
61778 + uint32_t bdStatus, nextBdStatus;
61779 + bool firstBuffer;
61780 +
61781 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61782 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61783 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61784 +
61785 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61786 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
61787 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
61788 +
61789 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
61790 + {
61791 + /* Confirm the current BD - BD is available */
61792 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
61793 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
61794 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
61795 + 0,
61796 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
61797 +
61798 + bdStatus = length;
61799 +
61800 + /* if this is the first BD of a frame */
61801 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
61802 + {
61803 + firstBuffer = TRUE;
61804 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
61805 +
61806 + if (!lastBuffer)
61807 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
61808 + }
61809 + else
61810 + firstBuffer = FALSE;
61811 +
61812 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
61813 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
61814 +
61815 + /* deal with last */
61816 + if (lastBuffer)
61817 + {
61818 + /* if single buffer frame */
61819 + if (firstBuffer)
61820 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
61821 + else
61822 + {
61823 + /* Set the last BD of the frame */
61824 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
61825 + /* Set the first BD of the frame */
61826 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
61827 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
61828 + }
61829 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
61830 + }
61831 + else if (!firstBuffer) /* mid frame buffer */
61832 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
61833 +
61834 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
61835 + }
61836 + else
61837 + {
61838 + /* Discard current frame. Return error. */
61839 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
61840 + {
61841 + /* Error: No free BD */
61842 + /* Response: Discard current frame. Return error. */
61843 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
61844 +
61845 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
61846 +
61847 + /* Since firstInFrame is not NULL, one buffer at least has already been
61848 + inserted into the BD ring. Using do-while covers the situation of a
61849 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
61850 + prior to testing whether or not it's equal to TxBd). */
61851 + do
61852 + {
61853 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
61854 + /* Advance BD pointer */
61855 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
61856 + } while (cleanBdId != p_FmPort->im.currBdId);
61857 +
61858 + p_FmPort->im.currBdId = cleanBdId;
61859 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
61860 + }
61861 +
61862 + return ERROR_CODE(E_FULL);
61863 + }
61864 +
61865 + return E_OK;
61866 +}
61867 +
61868 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
61869 +{
61870 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61871 +
61872 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
61873 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
61874 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61875 +
61876 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
61877 +}
61878 +
61879 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
61880 +{
61881 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61882 +
61883 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
61884 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
61885 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61886 +
61887 + return FmPortImRx(p_FmPort);
61888 +}
61889 --- /dev/null
61890 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
61891 @@ -0,0 +1,1570 @@
61892 +/*
61893 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61894 + *
61895 + * Redistribution and use in source and binary forms, with or without
61896 + * modification, are permitted provided that the following conditions are met:
61897 + * * Redistributions of source code must retain the above copyright
61898 + * notice, this list of conditions and the following disclaimer.
61899 + * * Redistributions in binary form must reproduce the above copyright
61900 + * notice, this list of conditions and the following disclaimer in the
61901 + * documentation and/or other materials provided with the distribution.
61902 + * * Neither the name of Freescale Semiconductor nor the
61903 + * names of its contributors may be used to endorse or promote products
61904 + * derived from this software without specific prior written permission.
61905 + *
61906 + *
61907 + * ALTERNATIVELY, this software may be distributed under the terms of the
61908 + * GNU General Public License ("GPL") as published by the Free Software
61909 + * Foundation, either version 2 of that License or (at your option) any
61910 + * later version.
61911 + *
61912 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
61913 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
61914 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61915 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
61916 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61917 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61918 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61919 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61920 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61921 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61922 + */
61923 +
61924 +
61925 +#include "std_ext.h"
61926 +#include "error_ext.h"
61927 +#include "common/general.h"
61928 +
61929 +#include "fman_common.h"
61930 +#include "fsl_fman_port.h"
61931 +
61932 +
61933 +/* problem Eyal: the following should not be here*/
61934 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
61935 +
61936 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
61937 +{
61938 + if (cfg->errata_A006675)
61939 + return NIA_ENG_FM_CTL |
61940 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
61941 + else
61942 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
61943 +}
61944 +
61945 +static int init_bmi_rx(struct fman_port *port,
61946 + struct fman_port_cfg *cfg,
61947 + struct fman_port_params *params)
61948 +{
61949 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
61950 + uint32_t tmp;
61951 +
61952 + /* Rx Configuration register */
61953 + tmp = 0;
61954 + if (port->im_en)
61955 + tmp |= BMI_PORT_CFG_IM;
61956 + else if (cfg->discard_override)
61957 + tmp |= BMI_PORT_CFG_FDOVR;
61958 + iowrite32be(tmp, &regs->fmbm_rcfg);
61959 +
61960 + /* DMA attributes */
61961 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
61962 + if (cfg->dma_ic_stash_on)
61963 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
61964 + if (cfg->dma_header_stash_on)
61965 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
61966 + if (cfg->dma_sg_stash_on)
61967 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
61968 + if (cfg->dma_write_optimize)
61969 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
61970 + iowrite32be(tmp, &regs->fmbm_rda);
61971 +
61972 + /* Rx FIFO parameters */
61973 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
61974 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
61975 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
61976 + iowrite32be(tmp, &regs->fmbm_rfp);
61977 +
61978 + if (cfg->excessive_threshold_register)
61979 + /* always allow access to the extra resources */
61980 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
61981 +
61982 + /* Frame end data */
61983 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
61984 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
61985 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
61986 + BMI_RX_FRAME_END_CUT_SHIFT;
61987 + if (cfg->errata_A006320)
61988 + tmp &= 0xffe0ffff;
61989 + iowrite32be(tmp, &regs->fmbm_rfed);
61990 +
61991 + /* Internal context parameters */
61992 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
61993 + BMI_IC_TO_EXT_SHIFT;
61994 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
61995 + BMI_IC_FROM_INT_SHIFT;
61996 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
61997 + iowrite32be(tmp, &regs->fmbm_ricp);
61998 +
61999 + /* Internal buffer offset */
62000 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
62001 + << BMI_INT_BUF_MARG_SHIFT;
62002 + iowrite32be(tmp, &regs->fmbm_rim);
62003 +
62004 + /* External buffer margins */
62005 + if (!port->im_en)
62006 + {
62007 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
62008 + BMI_EXT_BUF_MARG_START_SHIFT;
62009 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
62010 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
62011 + tmp |= BMI_SG_DISABLE;
62012 + iowrite32be(tmp, &regs->fmbm_rebm);
62013 + }
62014 +
62015 + /* Frame attributes */
62016 + tmp = BMI_CMD_RX_MR_DEF;
62017 + if (!port->im_en)
62018 + {
62019 + tmp |= BMI_CMD_ATTR_ORDER;
62020 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
62021 + if (cfg->sync_req)
62022 + tmp |= BMI_CMD_ATTR_SYNC;
62023 + }
62024 + iowrite32be(tmp, &regs->fmbm_rfca);
62025 +
62026 + /* NIA */
62027 + if (port->im_en)
62028 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
62029 + else
62030 + {
62031 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
62032 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
62033 + }
62034 + iowrite32be(tmp, &regs->fmbm_rfne);
62035 +
62036 + /* Enqueue NIA */
62037 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
62038 +
62039 + /* Default/error queues */
62040 + if (!port->im_en)
62041 + {
62042 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
62043 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
62044 + }
62045 +
62046 + /* Discard/error masks */
62047 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
62048 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
62049 +
62050 + /* Statistics counters */
62051 + tmp = 0;
62052 + if (cfg->stats_counters_enable)
62053 + tmp = BMI_COUNTERS_EN;
62054 + iowrite32be(tmp, &regs->fmbm_rstc);
62055 +
62056 + /* Performance counters */
62057 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
62058 + tmp = 0;
62059 + if (cfg->perf_counters_enable)
62060 + tmp = BMI_COUNTERS_EN;
62061 + iowrite32be(tmp, &regs->fmbm_rpc);
62062 +
62063 + return 0;
62064 +}
62065 +
62066 +static int init_bmi_tx(struct fman_port *port,
62067 + struct fman_port_cfg *cfg,
62068 + struct fman_port_params *params)
62069 +{
62070 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
62071 + uint32_t tmp;
62072 +
62073 + /* Tx Configuration register */
62074 + tmp = 0;
62075 + if (port->im_en)
62076 + tmp |= BMI_PORT_CFG_IM;
62077 + iowrite32be(tmp, &regs->fmbm_tcfg);
62078 +
62079 + /* DMA attributes */
62080 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
62081 + if (cfg->dma_ic_stash_on)
62082 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
62083 + if (cfg->dma_header_stash_on)
62084 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
62085 + if (cfg->dma_sg_stash_on)
62086 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
62087 + iowrite32be(tmp, &regs->fmbm_tda);
62088 +
62089 + /* Tx FIFO parameters */
62090 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
62091 + BMI_TX_FIFO_MIN_FILL_SHIFT;
62092 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
62093 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
62094 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
62095 + FMAN_PORT_BMI_FIFO_UNITS - 1);
62096 + iowrite32be(tmp, &regs->fmbm_tfp);
62097 +
62098 + /* Frame end data */
62099 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
62100 + BMI_FRAME_END_CS_IGNORE_SHIFT;
62101 + iowrite32be(tmp, &regs->fmbm_tfed);
62102 +
62103 + /* Internal context parameters */
62104 + if (!port->im_en)
62105 + {
62106 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62107 + BMI_IC_TO_EXT_SHIFT;
62108 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62109 + BMI_IC_FROM_INT_SHIFT;
62110 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
62111 + iowrite32be(tmp, &regs->fmbm_ticp);
62112 + }
62113 + /* Frame attributes */
62114 + tmp = BMI_CMD_TX_MR_DEF;
62115 + if (port->im_en)
62116 + tmp |= BMI_CMD_MR_DEAS;
62117 + else
62118 + {
62119 + tmp |= BMI_CMD_ATTR_ORDER;
62120 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
62121 + }
62122 + iowrite32be(tmp, &regs->fmbm_tfca);
62123 +
62124 + /* Dequeue NIA + enqueue NIA */
62125 + if (port->im_en)
62126 + {
62127 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
62128 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
62129 + }
62130 + else
62131 + {
62132 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
62133 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
62134 + if (cfg->fmbm_tfne_has_features)
62135 + iowrite32be(!params->dflt_fqid ?
62136 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
62137 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
62138 + if (!params->dflt_fqid && params->dont_release_buf)
62139 + {
62140 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
62141 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
62142 + if (cfg->fmbm_tfne_has_features)
62143 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
62144 + }
62145 + }
62146 +
62147 + /* Confirmation/error queues */
62148 + if (!port->im_en)
62149 + {
62150 + if (params->dflt_fqid || !params->dont_release_buf)
62151 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
62152 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
62153 + }
62154 + /* Statistics counters */
62155 + tmp = 0;
62156 + if (cfg->stats_counters_enable)
62157 + tmp = BMI_COUNTERS_EN;
62158 + iowrite32be(tmp, &regs->fmbm_tstc);
62159 +
62160 + /* Performance counters */
62161 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
62162 + tmp = 0;
62163 + if (cfg->perf_counters_enable)
62164 + tmp = BMI_COUNTERS_EN;
62165 + iowrite32be(tmp, &regs->fmbm_tpc);
62166 +
62167 + return 0;
62168 +}
62169 +
62170 +static int init_bmi_oh(struct fman_port *port,
62171 + struct fman_port_cfg *cfg,
62172 + struct fman_port_params *params)
62173 +{
62174 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
62175 + uint32_t tmp;
62176 +
62177 + /* OP Configuration register */
62178 + tmp = 0;
62179 + if (cfg->discard_override)
62180 + tmp |= BMI_PORT_CFG_FDOVR;
62181 + iowrite32be(tmp, &regs->fmbm_ocfg);
62182 +
62183 + /* DMA attributes */
62184 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
62185 + if (cfg->dma_ic_stash_on)
62186 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
62187 + if (cfg->dma_header_stash_on)
62188 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
62189 + if (cfg->dma_sg_stash_on)
62190 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
62191 + if (cfg->dma_write_optimize)
62192 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
62193 + iowrite32be(tmp, &regs->fmbm_oda);
62194 +
62195 + /* Tx FIFO parameters */
62196 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
62197 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
62198 + iowrite32be(tmp, &regs->fmbm_ofp);
62199 +
62200 + /* Internal context parameters */
62201 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62202 + BMI_IC_TO_EXT_SHIFT;
62203 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62204 + BMI_IC_FROM_INT_SHIFT;
62205 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
62206 + iowrite32be(tmp, &regs->fmbm_oicp);
62207 +
62208 + /* Frame attributes */
62209 + tmp = BMI_CMD_OP_MR_DEF;
62210 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
62211 + if (cfg->sync_req)
62212 + tmp |= BMI_CMD_ATTR_SYNC;
62213 + if (port->type == E_FMAN_PORT_TYPE_OP)
62214 + tmp |= BMI_CMD_ATTR_ORDER;
62215 + iowrite32be(tmp, &regs->fmbm_ofca);
62216 +
62217 + /* Internal buffer offset */
62218 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
62219 + << BMI_INT_BUF_MARG_SHIFT;
62220 + iowrite32be(tmp, &regs->fmbm_oim);
62221 +
62222 + /* Dequeue NIA */
62223 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
62224 +
62225 + /* NIA and Enqueue NIA */
62226 + if (port->type == E_FMAN_PORT_TYPE_HC) {
62227 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
62228 + &regs->fmbm_ofne);
62229 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
62230 + } else {
62231 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
62232 + &regs->fmbm_ofne);
62233 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
62234 + &regs->fmbm_ofene);
62235 + }
62236 +
62237 + /* Default/error queues */
62238 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
62239 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
62240 +
62241 + /* Discard/error masks */
62242 + if (port->type == E_FMAN_PORT_TYPE_OP) {
62243 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
62244 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
62245 + }
62246 +
62247 + /* Statistics counters */
62248 + tmp = 0;
62249 + if (cfg->stats_counters_enable)
62250 + tmp = BMI_COUNTERS_EN;
62251 + iowrite32be(tmp, &regs->fmbm_ostc);
62252 +
62253 + /* Performance counters */
62254 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
62255 + tmp = 0;
62256 + if (cfg->perf_counters_enable)
62257 + tmp = BMI_COUNTERS_EN;
62258 + iowrite32be(tmp, &regs->fmbm_opc);
62259 +
62260 + return 0;
62261 +}
62262 +
62263 +static int init_qmi(struct fman_port *port,
62264 + struct fman_port_cfg *cfg,
62265 + struct fman_port_params *params)
62266 +{
62267 + struct fman_port_qmi_regs *regs = port->qmi_regs;
62268 + uint32_t tmp;
62269 +
62270 + tmp = 0;
62271 + if (cfg->queue_counters_enable)
62272 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
62273 + iowrite32be(tmp, &regs->fmqm_pnc);
62274 +
62275 + /* Rx port configuration */
62276 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62277 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
62278 + /* Enqueue NIA */
62279 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
62280 + return 0;
62281 + }
62282 +
62283 + /* Continue with Tx and O/H port configuration */
62284 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
62285 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
62286 + /* Enqueue NIA */
62287 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
62288 + &regs->fmqm_pnen);
62289 + /* Dequeue NIA */
62290 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
62291 + } else {
62292 + /* Enqueue NIA */
62293 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
62294 + /* Dequeue NIA */
62295 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
62296 + }
62297 +
62298 + /* Dequeue Configuration register */
62299 + tmp = 0;
62300 + if (cfg->deq_high_pri)
62301 + tmp |= QMI_DEQ_CFG_PRI;
62302 +
62303 + switch (cfg->deq_type) {
62304 + case E_FMAN_PORT_DEQ_BY_PRI:
62305 + tmp |= QMI_DEQ_CFG_TYPE1;
62306 + break;
62307 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
62308 + tmp |= QMI_DEQ_CFG_TYPE2;
62309 + break;
62310 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
62311 + tmp |= QMI_DEQ_CFG_TYPE3;
62312 + break;
62313 + default:
62314 + return -EINVAL;
62315 + }
62316 +
62317 + if (cfg->qmi_deq_options_support) {
62318 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
62319 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
62320 + return -EINVAL;
62321 +
62322 + switch (cfg->deq_prefetch_opt) {
62323 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
62324 + break;
62325 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
62326 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
62327 + break;
62328 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
62329 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
62330 + break;
62331 + default:
62332 + return -EINVAL;
62333 + }
62334 + }
62335 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
62336 + QMI_DEQ_CFG_SP_SHIFT;
62337 + tmp |= cfg->deq_byte_cnt;
62338 + iowrite32be(tmp, &regs->fmqm_pndc);
62339 +
62340 + return 0;
62341 +}
62342 +
62343 +static void get_rx_stats_reg(struct fman_port *port,
62344 + enum fman_port_stats_counters counter,
62345 + uint32_t **stats_reg)
62346 +{
62347 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
62348 +
62349 + switch (counter) {
62350 + case E_FMAN_PORT_STATS_CNT_FRAME:
62351 + *stats_reg = &regs->fmbm_rfrc;
62352 + break;
62353 + case E_FMAN_PORT_STATS_CNT_DISCARD:
62354 + *stats_reg = &regs->fmbm_rfdc;
62355 + break;
62356 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
62357 + *stats_reg = &regs->fmbm_rbdc;
62358 + break;
62359 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
62360 + *stats_reg = &regs->fmbm_rfbc;
62361 + break;
62362 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
62363 + *stats_reg = &regs->fmbm_rlfc;
62364 + break;
62365 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
62366 + *stats_reg = &regs->fmbm_rodc;
62367 + break;
62368 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
62369 + *stats_reg = &regs->fmbm_rffc;
62370 + break;
62371 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
62372 + *stats_reg = &regs->fmbm_rfldec;
62373 + break;
62374 + default:
62375 + *stats_reg = NULL;
62376 + }
62377 +}
62378 +
62379 +static void get_tx_stats_reg(struct fman_port *port,
62380 + enum fman_port_stats_counters counter,
62381 + uint32_t **stats_reg)
62382 +{
62383 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
62384 +
62385 + switch (counter) {
62386 + case E_FMAN_PORT_STATS_CNT_FRAME:
62387 + *stats_reg = &regs->fmbm_tfrc;
62388 + break;
62389 + case E_FMAN_PORT_STATS_CNT_DISCARD:
62390 + *stats_reg = &regs->fmbm_tfdc;
62391 + break;
62392 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
62393 + *stats_reg = &regs->fmbm_tbdc;
62394 + break;
62395 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
62396 + *stats_reg = &regs->fmbm_tfledc;
62397 + break;
62398 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
62399 + *stats_reg = &regs->fmbm_tfufdc;
62400 + break;
62401 + default:
62402 + *stats_reg = NULL;
62403 + }
62404 +}
62405 +
62406 +static void get_oh_stats_reg(struct fman_port *port,
62407 + enum fman_port_stats_counters counter,
62408 + uint32_t **stats_reg)
62409 +{
62410 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
62411 +
62412 + switch (counter) {
62413 + case E_FMAN_PORT_STATS_CNT_FRAME:
62414 + *stats_reg = &regs->fmbm_ofrc;
62415 + break;
62416 + case E_FMAN_PORT_STATS_CNT_DISCARD:
62417 + *stats_reg = &regs->fmbm_ofdc;
62418 + break;
62419 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
62420 + *stats_reg = &regs->fmbm_obdc;
62421 + break;
62422 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
62423 + *stats_reg = &regs->fmbm_offc;
62424 + break;
62425 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
62426 + *stats_reg = &regs->fmbm_ofldec;
62427 + break;
62428 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
62429 + *stats_reg = &regs->fmbm_ofledc;
62430 + break;
62431 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
62432 + *stats_reg = &regs->fmbm_ofufdc;
62433 + break;
62434 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
62435 + *stats_reg = &regs->fmbm_ofwdc;
62436 + break;
62437 + default:
62438 + *stats_reg = NULL;
62439 + }
62440 +}
62441 +
62442 +static void get_rx_perf_reg(struct fman_port *port,
62443 + enum fman_port_perf_counters counter,
62444 + uint32_t **perf_reg)
62445 +{
62446 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
62447 +
62448 + switch (counter) {
62449 + case E_FMAN_PORT_PERF_CNT_CYCLE:
62450 + *perf_reg = &regs->fmbm_rccn;
62451 + break;
62452 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
62453 + *perf_reg = &regs->fmbm_rtuc;
62454 + break;
62455 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
62456 + *perf_reg = &regs->fmbm_rrquc;
62457 + break;
62458 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
62459 + *perf_reg = &regs->fmbm_rduc;
62460 + break;
62461 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
62462 + *perf_reg = &regs->fmbm_rfuc;
62463 + break;
62464 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
62465 + *perf_reg = &regs->fmbm_rpac;
62466 + break;
62467 + default:
62468 + *perf_reg = NULL;
62469 + }
62470 +}
62471 +
62472 +static void get_tx_perf_reg(struct fman_port *port,
62473 + enum fman_port_perf_counters counter,
62474 + uint32_t **perf_reg)
62475 +{
62476 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
62477 +
62478 + switch (counter) {
62479 + case E_FMAN_PORT_PERF_CNT_CYCLE:
62480 + *perf_reg = &regs->fmbm_tccn;
62481 + break;
62482 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
62483 + *perf_reg = &regs->fmbm_ttuc;
62484 + break;
62485 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
62486 + *perf_reg = &regs->fmbm_ttcquc;
62487 + break;
62488 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
62489 + *perf_reg = &regs->fmbm_tduc;
62490 + break;
62491 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
62492 + *perf_reg = &regs->fmbm_tfuc;
62493 + break;
62494 + default:
62495 + *perf_reg = NULL;
62496 + }
62497 +}
62498 +
62499 +static void get_oh_perf_reg(struct fman_port *port,
62500 + enum fman_port_perf_counters counter,
62501 + uint32_t **perf_reg)
62502 +{
62503 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
62504 +
62505 + switch (counter) {
62506 + case E_FMAN_PORT_PERF_CNT_CYCLE:
62507 + *perf_reg = &regs->fmbm_occn;
62508 + break;
62509 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
62510 + *perf_reg = &regs->fmbm_otuc;
62511 + break;
62512 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
62513 + *perf_reg = &regs->fmbm_oduc;
62514 + break;
62515 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
62516 + *perf_reg = &regs->fmbm_ofuc;
62517 + break;
62518 + default:
62519 + *perf_reg = NULL;
62520 + }
62521 +}
62522 +
62523 +static void get_qmi_counter_reg(struct fman_port *port,
62524 + enum fman_port_qmi_counters counter,
62525 + uint32_t **queue_reg)
62526 +{
62527 + struct fman_port_qmi_regs *regs = port->qmi_regs;
62528 +
62529 + switch (counter) {
62530 + case E_FMAN_PORT_ENQ_TOTAL:
62531 + *queue_reg = &regs->fmqm_pnetfc;
62532 + break;
62533 + case E_FMAN_PORT_DEQ_TOTAL:
62534 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62535 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
62536 + /* Counter not available for Rx ports */
62537 + *queue_reg = NULL;
62538 + else
62539 + *queue_reg = &regs->fmqm_pndtfc;
62540 + break;
62541 + case E_FMAN_PORT_DEQ_FROM_DFLT:
62542 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62543 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
62544 + /* Counter not available for Rx ports */
62545 + *queue_reg = NULL;
62546 + else
62547 + *queue_reg = &regs->fmqm_pndfdc;
62548 + break;
62549 + case E_FMAN_PORT_DEQ_CONFIRM:
62550 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62551 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
62552 + /* Counter not available for Rx ports */
62553 + *queue_reg = NULL;
62554 + else
62555 + *queue_reg = &regs->fmqm_pndcc;
62556 + break;
62557 + default:
62558 + *queue_reg = NULL;
62559 + }
62560 +}
62561 +
62562 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
62563 +{
62564 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
62565 + cfg->dma_ic_stash_on = FALSE;
62566 + cfg->dma_header_stash_on = FALSE;
62567 + cfg->dma_sg_stash_on = FALSE;
62568 + cfg->dma_write_optimize = TRUE;
62569 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
62570 + cfg->discard_override = FALSE;
62571 + cfg->checksum_bytes_ignore = 0;
62572 + cfg->rx_cut_end_bytes = 4;
62573 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
62574 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
62575 + cfg->rx_fd_bits = 0;
62576 + cfg->ic_ext_offset = 0;
62577 + cfg->ic_int_offset = 0;
62578 + cfg->ic_size = 0;
62579 + cfg->int_buf_start_margin = 0;
62580 + cfg->ext_buf_start_margin = 0;
62581 + cfg->ext_buf_end_margin = 0;
62582 + cfg->tx_fifo_min_level = 0;
62583 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
62584 + cfg->stats_counters_enable = TRUE;
62585 + cfg->perf_counters_enable = TRUE;
62586 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
62587 +
62588 + if (type == E_FMAN_PORT_TYPE_HC) {
62589 + cfg->sync_req = FALSE;
62590 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
62591 + } else {
62592 + cfg->sync_req = TRUE;
62593 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
62594 + }
62595 +
62596 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
62597 + cfg->tx_fifo_deq_pipeline_depth = 4;
62598 + cfg->deq_high_pri = TRUE;
62599 + cfg->deq_byte_cnt = 0x1400;
62600 + } else {
62601 + if ((type == E_FMAN_PORT_TYPE_HC) ||
62602 + (type == E_FMAN_PORT_TYPE_OP))
62603 + cfg->tx_fifo_deq_pipeline_depth = 2;
62604 + else
62605 + cfg->tx_fifo_deq_pipeline_depth = 1;
62606 +
62607 + cfg->deq_high_pri = FALSE;
62608 + cfg->deq_byte_cnt = 0x400;
62609 + }
62610 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
62611 +}
62612 +
62613 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
62614 +{
62615 + uint32_t *bp_reg, tmp;
62616 + uint8_t i, id;
62617 +
62618 + /* Find the pool */
62619 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
62620 + for (i = 0;
62621 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
62622 + i++) {
62623 + tmp = ioread32be(&bp_reg[i]);
62624 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
62625 + BMI_EXT_BUF_POOL_ID_SHIFT);
62626 +
62627 + if (id == bpid)
62628 + break;
62629 + }
62630 +
62631 + return i;
62632 +}
62633 +
62634 +int fman_port_init(struct fman_port *port,
62635 + struct fman_port_cfg *cfg,
62636 + struct fman_port_params *params)
62637 +{
62638 + int err;
62639 +
62640 + /* Init BMI registers */
62641 + switch (port->type) {
62642 + case E_FMAN_PORT_TYPE_RX:
62643 + case E_FMAN_PORT_TYPE_RX_10G:
62644 + err = init_bmi_rx(port, cfg, params);
62645 + break;
62646 + case E_FMAN_PORT_TYPE_TX:
62647 + case E_FMAN_PORT_TYPE_TX_10G:
62648 + err = init_bmi_tx(port, cfg, params);
62649 + break;
62650 + case E_FMAN_PORT_TYPE_OP:
62651 + case E_FMAN_PORT_TYPE_HC:
62652 + err = init_bmi_oh(port, cfg, params);
62653 + break;
62654 + default:
62655 + return -EINVAL;
62656 + }
62657 +
62658 + if (err)
62659 + return err;
62660 +
62661 + /* Init QMI registers */
62662 + if (!port->im_en)
62663 + {
62664 + err = init_qmi(port, cfg, params);
62665 + return err;
62666 + }
62667 + return 0;
62668 +}
62669 +
62670 +int fman_port_enable(struct fman_port *port)
62671 +{
62672 + uint32_t *bmi_cfg_reg, tmp;
62673 + bool rx_port;
62674 +
62675 + switch (port->type) {
62676 + case E_FMAN_PORT_TYPE_RX:
62677 + case E_FMAN_PORT_TYPE_RX_10G:
62678 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
62679 + rx_port = TRUE;
62680 + break;
62681 + case E_FMAN_PORT_TYPE_TX:
62682 + case E_FMAN_PORT_TYPE_TX_10G:
62683 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
62684 + rx_port = FALSE;
62685 + break;
62686 + case E_FMAN_PORT_TYPE_OP:
62687 + case E_FMAN_PORT_TYPE_HC:
62688 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
62689 + rx_port = FALSE;
62690 + break;
62691 + default:
62692 + return -EINVAL;
62693 + }
62694 +
62695 + /* Enable QMI */
62696 + if (!rx_port) {
62697 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
62698 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
62699 + }
62700 +
62701 + /* Enable BMI */
62702 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
62703 + iowrite32be(tmp, bmi_cfg_reg);
62704 +
62705 + return 0;
62706 +}
62707 +
62708 +int fman_port_disable(const struct fman_port *port)
62709 +{
62710 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
62711 + bool rx_port, failure = FALSE;
62712 + int count;
62713 +
62714 + switch (port->type) {
62715 + case E_FMAN_PORT_TYPE_RX:
62716 + case E_FMAN_PORT_TYPE_RX_10G:
62717 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
62718 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
62719 + rx_port = TRUE;
62720 + break;
62721 + case E_FMAN_PORT_TYPE_TX:
62722 + case E_FMAN_PORT_TYPE_TX_10G:
62723 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
62724 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
62725 + rx_port = FALSE;
62726 + break;
62727 + case E_FMAN_PORT_TYPE_OP:
62728 + case E_FMAN_PORT_TYPE_HC:
62729 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
62730 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
62731 + rx_port = FALSE;
62732 + break;
62733 + default:
62734 + return -EINVAL;
62735 + }
62736 +
62737 + /* Disable QMI */
62738 + if (!rx_port) {
62739 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
62740 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
62741 +
62742 + /* Wait for QMI to finish FD handling */
62743 + count = 100;
62744 + do {
62745 + udelay(10);
62746 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
62747 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
62748 +
62749 + if (count == 0)
62750 + {
62751 + /* Timeout */
62752 + failure = TRUE;
62753 + }
62754 + }
62755 +
62756 + /* Disable BMI */
62757 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
62758 + iowrite32be(tmp, bmi_cfg_reg);
62759 +
62760 + /* Wait for graceful stop end */
62761 + count = 500;
62762 + do {
62763 + udelay(10);
62764 + tmp = ioread32be(bmi_status_reg);
62765 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
62766 +
62767 + if (count == 0)
62768 + {
62769 + /* Timeout */
62770 + failure = TRUE;
62771 + }
62772 +
62773 + if (failure)
62774 + return -EBUSY;
62775 +
62776 + return 0;
62777 +}
62778 +
62779 +int fman_port_set_bpools(const struct fman_port *port,
62780 + const struct fman_port_bpools *bp)
62781 +{
62782 + uint32_t tmp, *bp_reg, *bp_depl_reg;
62783 + uint8_t i, max_bp_num;
62784 + bool grp_depl_used = FALSE, rx_port;
62785 +
62786 + switch (port->type) {
62787 + case E_FMAN_PORT_TYPE_RX:
62788 + case E_FMAN_PORT_TYPE_RX_10G:
62789 + max_bp_num = port->ext_pools_num;
62790 + rx_port = TRUE;
62791 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
62792 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
62793 + break;
62794 + case E_FMAN_PORT_TYPE_OP:
62795 + if (port->fm_rev_maj != 4)
62796 + return -EINVAL;
62797 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
62798 + rx_port = FALSE;
62799 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
62800 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
62801 + break;
62802 + default:
62803 + return -EINVAL;
62804 + }
62805 +
62806 + if (rx_port) {
62807 + /* Check buffers are provided in ascending order */
62808 + for (i = 0;
62809 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
62810 + i++) {
62811 + if (bp->bpool[i].size > bp->bpool[i+1].size)
62812 + return -EINVAL;
62813 + }
62814 + }
62815 +
62816 + /* Set up external buffers pools */
62817 + for (i = 0; i < bp->count; i++) {
62818 + tmp = BMI_EXT_BUF_POOL_VALID;
62819 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
62820 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
62821 +
62822 + if (rx_port) {
62823 + if (bp->counters_enable)
62824 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
62825 +
62826 + if (bp->bpool[i].is_backup)
62827 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
62828 +
62829 + tmp |= (uint32_t)bp->bpool[i].size;
62830 + }
62831 +
62832 + iowrite32be(tmp, &bp_reg[i]);
62833 + }
62834 +
62835 + /* Clear unused pools */
62836 + for (i = bp->count; i < max_bp_num; i++)
62837 + iowrite32be(0, &bp_reg[i]);
62838 +
62839 + /* Pools depletion */
62840 + tmp = 0;
62841 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
62842 + if (bp->bpool[i].grp_bp_depleted) {
62843 + grp_depl_used = TRUE;
62844 + tmp |= 0x80000000 >> i;
62845 + }
62846 +
62847 + if (bp->bpool[i].single_bp_depleted)
62848 + tmp |= 0x80 >> i;
62849 +
62850 + if (bp->bpool[i].pfc_priorities_en)
62851 + tmp |= 0x0100 << i;
62852 + }
62853 +
62854 + if (grp_depl_used)
62855 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
62856 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
62857 +
62858 + iowrite32be(tmp, bp_depl_reg);
62859 + return 0;
62860 +}
62861 +
62862 +int fman_port_set_rate_limiter(struct fman_port *port,
62863 + struct fman_port_rate_limiter *rate_limiter)
62864 +{
62865 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
62866 + uint32_t granularity, tmp;
62867 + uint8_t usec_bit, factor;
62868 +
62869 + switch (port->type) {
62870 + case E_FMAN_PORT_TYPE_TX:
62871 + case E_FMAN_PORT_TYPE_TX_10G:
62872 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
62873 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
62874 + granularity = BMI_RATE_LIMIT_GRAN_TX;
62875 + break;
62876 + case E_FMAN_PORT_TYPE_OP:
62877 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
62878 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
62879 + granularity = BMI_RATE_LIMIT_GRAN_OP;
62880 + break;
62881 + default:
62882 + return -EINVAL;
62883 + }
62884 +
62885 + /* Factor is per 1 usec count */
62886 + factor = 1;
62887 + usec_bit = rate_limiter->count_1micro_bit;
62888 +
62889 + /* If rate limit is too small for an 1usec factor, adjust timestamp
62890 + * scale and multiply the factor */
62891 + while (rate_limiter->rate < (granularity / factor)) {
62892 + if (usec_bit == 31)
62893 + /* Can't configure rate limiter - rate is too small */
62894 + return -EINVAL;
62895 +
62896 + usec_bit++;
62897 + factor <<= 1;
62898 + }
62899 +
62900 + /* Figure out register value. The "while" above quarantees that
62901 + * (rate_limiter->rate * factor / granularity) >= 1 */
62902 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
62903 +
62904 + /* Check rate limit isn't too large */
62905 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
62906 + return -EINVAL;
62907 +
62908 + /* Check burst size is in allowed range */
62909 + if ((rate_limiter->burst_size == 0) ||
62910 + (rate_limiter->burst_size >
62911 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
62912 + return -EINVAL;
62913 +
62914 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
62915 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
62916 +
62917 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
62918 + (port->fm_rev_maj == 4)) {
62919 + if (rate_limiter->high_burst_size_gran)
62920 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
62921 + }
62922 +
62923 + iowrite32be(tmp, rate_limit_reg);
62924 +
62925 + /* Set up rate limiter scale register */
62926 + tmp = BMI_RATE_LIMIT_SCALE_EN;
62927 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
62928 +
62929 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
62930 + (port->fm_rev_maj == 4))
62931 + tmp |= rate_limiter->rate_factor;
62932 +
62933 + iowrite32be(tmp, rate_limit_scale_reg);
62934 +
62935 + return 0;
62936 +}
62937 +
62938 +int fman_port_delete_rate_limiter(struct fman_port *port)
62939 +{
62940 + uint32_t *rate_limit_scale_reg;
62941 +
62942 + switch (port->type) {
62943 + case E_FMAN_PORT_TYPE_TX:
62944 + case E_FMAN_PORT_TYPE_TX_10G:
62945 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
62946 + break;
62947 + case E_FMAN_PORT_TYPE_OP:
62948 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
62949 + break;
62950 + default:
62951 + return -EINVAL;
62952 + }
62953 +
62954 + iowrite32be(0, rate_limit_scale_reg);
62955 + return 0;
62956 +}
62957 +
62958 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
62959 +{
62960 + uint32_t *err_mask_reg;
62961 +
62962 + /* Obtain register address */
62963 + switch (port->type) {
62964 + case E_FMAN_PORT_TYPE_RX:
62965 + case E_FMAN_PORT_TYPE_RX_10G:
62966 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
62967 + break;
62968 + case E_FMAN_PORT_TYPE_OP:
62969 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
62970 + break;
62971 + default:
62972 + return -EINVAL;
62973 + }
62974 +
62975 + iowrite32be(err_mask, err_mask_reg);
62976 + return 0;
62977 +}
62978 +
62979 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
62980 +{
62981 + uint32_t *discard_mask_reg;
62982 +
62983 + /* Obtain register address */
62984 + switch (port->type) {
62985 + case E_FMAN_PORT_TYPE_RX:
62986 + case E_FMAN_PORT_TYPE_RX_10G:
62987 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
62988 + break;
62989 + case E_FMAN_PORT_TYPE_OP:
62990 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
62991 + break;
62992 + default:
62993 + return -EINVAL;
62994 + }
62995 +
62996 + iowrite32be(discard_mask, discard_mask_reg);
62997 + return 0;
62998 +}
62999 +
63000 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
63001 + uint8_t rx_fd_bits,
63002 + bool add)
63003 +{
63004 + uint32_t tmp;
63005 +
63006 + switch (port->type) {
63007 + case E_FMAN_PORT_TYPE_RX:
63008 + case E_FMAN_PORT_TYPE_RX_10G:
63009 + break;
63010 + default:
63011 + return -EINVAL;
63012 + }
63013 +
63014 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
63015 +
63016 + if (add)
63017 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
63018 + else
63019 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
63020 +
63021 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
63022 + return 0;
63023 +}
63024 +
63025 +int fman_port_set_perf_cnt_params(struct fman_port *port,
63026 + struct fman_port_perf_cnt_params *params)
63027 +{
63028 + uint32_t *pcp_reg, tmp;
63029 +
63030 + /* Obtain register address and check parameters are in range */
63031 + switch (port->type) {
63032 + case E_FMAN_PORT_TYPE_RX:
63033 + case E_FMAN_PORT_TYPE_RX_10G:
63034 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
63035 + if ((params->queue_val == 0) ||
63036 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
63037 + return -EINVAL;
63038 + break;
63039 + case E_FMAN_PORT_TYPE_TX:
63040 + case E_FMAN_PORT_TYPE_TX_10G:
63041 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
63042 + if ((params->queue_val == 0) ||
63043 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
63044 + return -EINVAL;
63045 + break;
63046 + case E_FMAN_PORT_TYPE_OP:
63047 + case E_FMAN_PORT_TYPE_HC:
63048 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
63049 + if (params->queue_val != 0)
63050 + return -EINVAL;
63051 + break;
63052 + default:
63053 + return -EINVAL;
63054 + }
63055 +
63056 + if ((params->task_val == 0) ||
63057 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
63058 + return -EINVAL;
63059 + if ((params->dma_val == 0) ||
63060 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
63061 + return -EINVAL;
63062 + if ((params->fifo_val == 0) ||
63063 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
63064 + MAX_PERFORMANCE_FIFO_COMP))
63065 + return -EINVAL;
63066 + tmp = (uint32_t)(params->task_val - 1) <<
63067 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
63068 + tmp |= (uint32_t)(params->dma_val - 1) <<
63069 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
63070 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
63071 +
63072 + switch (port->type) {
63073 + case E_FMAN_PORT_TYPE_RX:
63074 + case E_FMAN_PORT_TYPE_RX_10G:
63075 + case E_FMAN_PORT_TYPE_TX:
63076 + case E_FMAN_PORT_TYPE_TX_10G:
63077 + tmp |= (uint32_t)(params->queue_val - 1) <<
63078 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
63079 + break;
63080 + default:
63081 + break;
63082 + }
63083 +
63084 +
63085 + iowrite32be(tmp, pcp_reg);
63086 + return 0;
63087 +}
63088 +
63089 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
63090 +{
63091 + uint32_t *stats_reg, tmp;
63092 +
63093 + switch (port->type) {
63094 + case E_FMAN_PORT_TYPE_RX:
63095 + case E_FMAN_PORT_TYPE_RX_10G:
63096 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
63097 + break;
63098 + case E_FMAN_PORT_TYPE_TX:
63099 + case E_FMAN_PORT_TYPE_TX_10G:
63100 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
63101 + break;
63102 + case E_FMAN_PORT_TYPE_OP:
63103 + case E_FMAN_PORT_TYPE_HC:
63104 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
63105 + break;
63106 + default:
63107 + return -EINVAL;
63108 + }
63109 +
63110 + tmp = ioread32be(stats_reg);
63111 +
63112 + if (enable)
63113 + tmp |= BMI_COUNTERS_EN;
63114 + else
63115 + tmp &= ~BMI_COUNTERS_EN;
63116 +
63117 + iowrite32be(tmp, stats_reg);
63118 + return 0;
63119 +}
63120 +
63121 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
63122 +{
63123 + uint32_t *stats_reg, tmp;
63124 +
63125 + switch (port->type) {
63126 + case E_FMAN_PORT_TYPE_RX:
63127 + case E_FMAN_PORT_TYPE_RX_10G:
63128 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
63129 + break;
63130 + case E_FMAN_PORT_TYPE_TX:
63131 + case E_FMAN_PORT_TYPE_TX_10G:
63132 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
63133 + break;
63134 + case E_FMAN_PORT_TYPE_OP:
63135 + case E_FMAN_PORT_TYPE_HC:
63136 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
63137 + break;
63138 + default:
63139 + return -EINVAL;
63140 + }
63141 +
63142 + tmp = ioread32be(stats_reg);
63143 +
63144 + if (enable)
63145 + tmp |= BMI_COUNTERS_EN;
63146 + else
63147 + tmp &= ~BMI_COUNTERS_EN;
63148 +
63149 + iowrite32be(tmp, stats_reg);
63150 + return 0;
63151 +}
63152 +
63153 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
63154 +{
63155 + uint32_t tmp;
63156 +
63157 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
63158 +
63159 + if (enable)
63160 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
63161 + else
63162 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
63163 +
63164 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
63165 + return 0;
63166 +}
63167 +
63168 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
63169 + uint8_t bpid,
63170 + bool enable)
63171 +{
63172 + uint8_t index;
63173 + uint32_t tmp;
63174 +
63175 + switch (port->type) {
63176 + case E_FMAN_PORT_TYPE_RX:
63177 + case E_FMAN_PORT_TYPE_RX_10G:
63178 + break;
63179 + default:
63180 + return -EINVAL;
63181 + }
63182 +
63183 + /* Find the pool */
63184 + index = fman_port_find_bpool(port, bpid);
63185 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
63186 + /* Not found */
63187 + return -EINVAL;
63188 +
63189 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
63190 +
63191 + if (enable)
63192 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
63193 + else
63194 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
63195 +
63196 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
63197 + return 0;
63198 +}
63199 +
63200 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
63201 + enum fman_port_stats_counters counter)
63202 +{
63203 + uint32_t *stats_reg, ret_val;
63204 +
63205 + switch (port->type) {
63206 + case E_FMAN_PORT_TYPE_RX:
63207 + case E_FMAN_PORT_TYPE_RX_10G:
63208 + get_rx_stats_reg(port, counter, &stats_reg);
63209 + break;
63210 + case E_FMAN_PORT_TYPE_TX:
63211 + case E_FMAN_PORT_TYPE_TX_10G:
63212 + get_tx_stats_reg(port, counter, &stats_reg);
63213 + break;
63214 + case E_FMAN_PORT_TYPE_OP:
63215 + case E_FMAN_PORT_TYPE_HC:
63216 + get_oh_stats_reg(port, counter, &stats_reg);
63217 + break;
63218 + default:
63219 + stats_reg = NULL;
63220 + }
63221 +
63222 + if (stats_reg == NULL)
63223 + return 0;
63224 +
63225 + ret_val = ioread32be(stats_reg);
63226 + return ret_val;
63227 +}
63228 +
63229 +void fman_port_set_stats_counter(struct fman_port *port,
63230 + enum fman_port_stats_counters counter,
63231 + uint32_t value)
63232 +{
63233 + uint32_t *stats_reg;
63234 +
63235 + switch (port->type) {
63236 + case E_FMAN_PORT_TYPE_RX:
63237 + case E_FMAN_PORT_TYPE_RX_10G:
63238 + get_rx_stats_reg(port, counter, &stats_reg);
63239 + break;
63240 + case E_FMAN_PORT_TYPE_TX:
63241 + case E_FMAN_PORT_TYPE_TX_10G:
63242 + get_tx_stats_reg(port, counter, &stats_reg);
63243 + break;
63244 + case E_FMAN_PORT_TYPE_OP:
63245 + case E_FMAN_PORT_TYPE_HC:
63246 + get_oh_stats_reg(port, counter, &stats_reg);
63247 + break;
63248 + default:
63249 + stats_reg = NULL;
63250 + }
63251 +
63252 + if (stats_reg == NULL)
63253 + return;
63254 +
63255 + iowrite32be(value, stats_reg);
63256 +}
63257 +
63258 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
63259 + enum fman_port_perf_counters counter)
63260 +{
63261 + uint32_t *perf_reg, ret_val;
63262 +
63263 + switch (port->type) {
63264 + case E_FMAN_PORT_TYPE_RX:
63265 + case E_FMAN_PORT_TYPE_RX_10G:
63266 + get_rx_perf_reg(port, counter, &perf_reg);
63267 + break;
63268 + case E_FMAN_PORT_TYPE_TX:
63269 + case E_FMAN_PORT_TYPE_TX_10G:
63270 + get_tx_perf_reg(port, counter, &perf_reg);
63271 + break;
63272 + case E_FMAN_PORT_TYPE_OP:
63273 + case E_FMAN_PORT_TYPE_HC:
63274 + get_oh_perf_reg(port, counter, &perf_reg);
63275 + break;
63276 + default:
63277 + perf_reg = NULL;
63278 + }
63279 +
63280 + if (perf_reg == NULL)
63281 + return 0;
63282 +
63283 + ret_val = ioread32be(perf_reg);
63284 + return ret_val;
63285 +}
63286 +
63287 +void fman_port_set_perf_counter(struct fman_port *port,
63288 + enum fman_port_perf_counters counter,
63289 + uint32_t value)
63290 +{
63291 + uint32_t *perf_reg;
63292 +
63293 + switch (port->type) {
63294 + case E_FMAN_PORT_TYPE_RX:
63295 + case E_FMAN_PORT_TYPE_RX_10G:
63296 + get_rx_perf_reg(port, counter, &perf_reg);
63297 + break;
63298 + case E_FMAN_PORT_TYPE_TX:
63299 + case E_FMAN_PORT_TYPE_TX_10G:
63300 + get_tx_perf_reg(port, counter, &perf_reg);
63301 + break;
63302 + case E_FMAN_PORT_TYPE_OP:
63303 + case E_FMAN_PORT_TYPE_HC:
63304 + get_oh_perf_reg(port, counter, &perf_reg);
63305 + break;
63306 + default:
63307 + perf_reg = NULL;
63308 + }
63309 +
63310 + if (perf_reg == NULL)
63311 + return;
63312 +
63313 + iowrite32be(value, perf_reg);
63314 +}
63315 +
63316 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
63317 + enum fman_port_qmi_counters counter)
63318 +{
63319 + uint32_t *queue_reg, ret_val;
63320 +
63321 + get_qmi_counter_reg(port, counter, &queue_reg);
63322 +
63323 + if (queue_reg == NULL)
63324 + return 0;
63325 +
63326 + ret_val = ioread32be(queue_reg);
63327 + return ret_val;
63328 +}
63329 +
63330 +void fman_port_set_qmi_counter(struct fman_port *port,
63331 + enum fman_port_qmi_counters counter,
63332 + uint32_t value)
63333 +{
63334 + uint32_t *queue_reg;
63335 +
63336 + get_qmi_counter_reg(port, counter, &queue_reg);
63337 +
63338 + if (queue_reg == NULL)
63339 + return;
63340 +
63341 + iowrite32be(value, queue_reg);
63342 +}
63343 +
63344 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
63345 +{
63346 + uint8_t index;
63347 + uint32_t ret_val;
63348 +
63349 + switch (port->type) {
63350 + case E_FMAN_PORT_TYPE_RX:
63351 + case E_FMAN_PORT_TYPE_RX_10G:
63352 + break;
63353 + default:
63354 + return 0;
63355 + }
63356 +
63357 + /* Find the pool */
63358 + index = fman_port_find_bpool(port, bpid);
63359 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
63360 + /* Not found */
63361 + return 0;
63362 +
63363 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
63364 + return ret_val;
63365 +}
63366 +
63367 +void fman_port_set_bpool_counter(struct fman_port *port,
63368 + uint8_t bpid,
63369 + uint32_t value)
63370 +{
63371 + uint8_t index;
63372 +
63373 + switch (port->type) {
63374 + case E_FMAN_PORT_TYPE_RX:
63375 + case E_FMAN_PORT_TYPE_RX_10G:
63376 + break;
63377 + default:
63378 + return;
63379 + }
63380 +
63381 + /* Find the pool */
63382 + index = fman_port_find_bpool(port, bpid);
63383 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
63384 + /* Not found */
63385 + return;
63386 +
63387 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
63388 +}
63389 +
63390 +int fman_port_add_congestion_grps(struct fman_port *port,
63391 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
63392 +{
63393 + int i;
63394 + uint32_t tmp, *grp_map_reg;
63395 + uint8_t max_grp_map_num;
63396 +
63397 + switch (port->type) {
63398 + case E_FMAN_PORT_TYPE_RX:
63399 + case E_FMAN_PORT_TYPE_RX_10G:
63400 + if (port->fm_rev_maj == 4)
63401 + max_grp_map_num = 1;
63402 + else
63403 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
63404 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
63405 + break;
63406 + case E_FMAN_PORT_TYPE_OP:
63407 + max_grp_map_num = 1;
63408 + if (port->fm_rev_maj != 4)
63409 + return -EINVAL;
63410 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
63411 + break;
63412 + default:
63413 + return -EINVAL;
63414 + }
63415 +
63416 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
63417 + if (grps_map[i] == 0)
63418 + continue;
63419 + tmp = ioread32be(&grp_map_reg[i]);
63420 + tmp |= grps_map[i];
63421 + iowrite32be(tmp, &grp_map_reg[i]);
63422 + }
63423 +
63424 + return 0;
63425 +}
63426 +
63427 +int fman_port_remove_congestion_grps(struct fman_port *port,
63428 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
63429 +{
63430 + int i;
63431 + uint32_t tmp, *grp_map_reg;
63432 + uint8_t max_grp_map_num;
63433 +
63434 + switch (port->type) {
63435 + case E_FMAN_PORT_TYPE_RX:
63436 + case E_FMAN_PORT_TYPE_RX_10G:
63437 + if (port->fm_rev_maj == 4)
63438 + max_grp_map_num = 1;
63439 + else
63440 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
63441 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
63442 + break;
63443 + case E_FMAN_PORT_TYPE_OP:
63444 + max_grp_map_num = 1;
63445 + if (port->fm_rev_maj != 4)
63446 + return -EINVAL;
63447 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
63448 + break;
63449 + default:
63450 + return -EINVAL;
63451 + }
63452 +
63453 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
63454 + if (grps_map[i] == 0)
63455 + continue;
63456 + tmp = ioread32be(&grp_map_reg[i]);
63457 + tmp &= ~grps_map[i];
63458 + iowrite32be(tmp, &grp_map_reg[i]);
63459 + }
63460 + return 0;
63461 +}
63462 --- /dev/null
63463 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
63464 @@ -0,0 +1,15 @@
63465 +#
63466 +# Makefile for the Freescale Ethernet controllers
63467 +#
63468 +ccflags-y += -DVERSION=\"\"
63469 +#
63470 +#Include netcomm SW specific definitions
63471 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63472 +
63473 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63474 +
63475 +ccflags-y += -I$(NCSW_FM_INC)
63476 +
63477 +obj-y += fsl-ncsw-RTC.o
63478 +
63479 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
63480 --- /dev/null
63481 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
63482 @@ -0,0 +1,692 @@
63483 +/*
63484 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63485 + *
63486 + * Redistribution and use in source and binary forms, with or without
63487 + * modification, are permitted provided that the following conditions are met:
63488 + * * Redistributions of source code must retain the above copyright
63489 + * notice, this list of conditions and the following disclaimer.
63490 + * * Redistributions in binary form must reproduce the above copyright
63491 + * notice, this list of conditions and the following disclaimer in the
63492 + * documentation and/or other materials provided with the distribution.
63493 + * * Neither the name of Freescale Semiconductor nor the
63494 + * names of its contributors may be used to endorse or promote products
63495 + * derived from this software without specific prior written permission.
63496 + *
63497 + *
63498 + * ALTERNATIVELY, this software may be distributed under the terms of the
63499 + * GNU General Public License ("GPL") as published by the Free Software
63500 + * Foundation, either version 2 of that License or (at your option) any
63501 + * later version.
63502 + *
63503 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63504 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63505 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63506 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63507 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63508 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63509 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63510 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63511 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63512 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63513 + */
63514 +
63515 +
63516 +/******************************************************************************
63517 + @File fm_rtc.c
63518 +
63519 + @Description FM RTC driver implementation.
63520 +
63521 + @Cautions None
63522 +*//***************************************************************************/
63523 +#include <linux/math64.h>
63524 +#include "error_ext.h"
63525 +#include "debug_ext.h"
63526 +#include "string_ext.h"
63527 +#include "part_ext.h"
63528 +#include "xx_ext.h"
63529 +#include "ncsw_ext.h"
63530 +
63531 +#include "fm_rtc.h"
63532 +#include "fm_common.h"
63533 +
63534 +
63535 +
63536 +/*****************************************************************************/
63537 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
63538 +{
63539 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
63540 + int i;
63541 +
63542 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
63543 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
63544 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
63545 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
63546 +
63547 + if (p_Rtc->outputClockDivisor == 0)
63548 + {
63549 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63550 + ("Divisor for output clock (should be positive)"));
63551 + }
63552 +
63553 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
63554 + {
63555 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
63556 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
63557 + {
63558 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
63559 + }
63560 + }
63561 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
63562 + {
63563 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
63564 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
63565 + {
63566 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
63567 + }
63568 + }
63569 +
63570 + return E_OK;
63571 +}
63572 +
63573 +/*****************************************************************************/
63574 +static void RtcExceptions(t_Handle h_FmRtc)
63575 +{
63576 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63577 + struct rtc_regs *p_MemMap;
63578 + register uint32_t events;
63579 +
63580 + ASSERT_COND(p_Rtc);
63581 + p_MemMap = p_Rtc->p_MemMap;
63582 +
63583 + events = fman_rtc_check_and_clear_event(p_MemMap);
63584 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
63585 + {
63586 + if (p_Rtc->alarmParams[0].clearOnExpiration)
63587 + {
63588 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
63589 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
63590 + }
63591 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
63592 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
63593 + }
63594 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
63595 + {
63596 + if (p_Rtc->alarmParams[1].clearOnExpiration)
63597 + {
63598 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
63599 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
63600 + }
63601 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
63602 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
63603 + }
63604 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
63605 + {
63606 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
63607 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
63608 + }
63609 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
63610 + {
63611 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
63612 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
63613 + }
63614 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
63615 + {
63616 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
63617 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
63618 + }
63619 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
63620 + {
63621 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
63622 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
63623 + }
63624 +}
63625 +
63626 +
63627 +/*****************************************************************************/
63628 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
63629 +{
63630 + t_FmRtc *p_Rtc;
63631 +
63632 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
63633 +
63634 + /* Allocate memory for the FM RTC driver parameters */
63635 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
63636 + if (!p_Rtc)
63637 + {
63638 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
63639 + return NULL;
63640 + }
63641 +
63642 + memset(p_Rtc, 0, sizeof(t_FmRtc));
63643 +
63644 + /* Allocate memory for the FM RTC driver parameters */
63645 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
63646 + if (!p_Rtc->p_RtcDriverParam)
63647 + {
63648 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
63649 + XX_Free(p_Rtc);
63650 + return NULL;
63651 + }
63652 +
63653 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
63654 +
63655 + /* Store RTC configuration parameters */
63656 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
63657 +
63658 + /* Set default RTC configuration parameters */
63659 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
63660 +
63661 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
63662 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
63663 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
63664 +
63665 +
63666 + /* Store RTC parameters in the RTC control structure */
63667 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
63668 + p_Rtc->h_App = p_FmRtcParam->h_App;
63669 +
63670 + return p_Rtc;
63671 +}
63672 +
63673 +/*****************************************************************************/
63674 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
63675 +{
63676 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63677 + struct rtc_cfg *p_RtcDriverParam;
63678 + struct rtc_regs *p_MemMap;
63679 + uint32_t freqCompensation = 0;
63680 + uint64_t tmpDouble;
63681 + bool init_freq_comp = FALSE;
63682 +
63683 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
63684 + p_MemMap = p_Rtc->p_MemMap;
63685 +
63686 + if (CheckInitParameters(p_Rtc)!=E_OK)
63687 + RETURN_ERROR(MAJOR, E_CONFLICT,
63688 + ("Init Parameters are not Valid"));
63689 +
63690 + /* TODO check that no timestamping MACs are working in this stage. */
63691 +
63692 + /* find source clock frequency in Mhz */
63693 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
63694 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
63695 + else
63696 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
63697 +
63698 + /* if timer in Master mode Initialize TMR_CTRL */
63699 + /* We want the counter (TMR_CNT) to count in nano-seconds */
63700 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
63701 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
63702 + else
63703 + {
63704 + /* Initialize TMR_ADD with the initial frequency compensation value:
63705 + freqCompensation = (2^32 / frequency ratio) */
63706 + /* frequency ratio = sorce clock/rtc clock =
63707 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
63708 + init_freq_comp = TRUE;
63709 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
63710 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
63711 + }
63712 +
63713 + /* check the legality of the relation between source and destination clocks */
63714 + /* should be larger than 1.0001 */
63715 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
63716 + if ((tmpDouble) <= 10001)
63717 + RETURN_ERROR(MAJOR, E_CONFLICT,
63718 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
63719 +
63720 + fman_rtc_init(p_RtcDriverParam,
63721 + p_MemMap,
63722 + FM_RTC_NUM_OF_ALARMS,
63723 + FM_RTC_NUM_OF_PERIODIC_PULSES,
63724 + FM_RTC_NUM_OF_EXT_TRIGGERS,
63725 + init_freq_comp,
63726 + freqCompensation,
63727 + p_Rtc->outputClockDivisor);
63728 +
63729 + /* Register the FM RTC interrupt */
63730 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
63731 +
63732 + /* Free parameters structures */
63733 + XX_Free(p_Rtc->p_RtcDriverParam);
63734 + p_Rtc->p_RtcDriverParam = NULL;
63735 +
63736 + return E_OK;
63737 +}
63738 +
63739 +/*****************************************************************************/
63740 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
63741 +{
63742 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63743 +
63744 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63745 +
63746 + if (p_Rtc->p_RtcDriverParam)
63747 + {
63748 + XX_Free(p_Rtc->p_RtcDriverParam);
63749 + }
63750 + else
63751 + {
63752 + FM_RTC_Disable(h_FmRtc);
63753 + }
63754 +
63755 + /* Unregister FM RTC interrupt */
63756 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
63757 + XX_Free(p_Rtc);
63758 +
63759 + return E_OK;
63760 +}
63761 +
63762 +/*****************************************************************************/
63763 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
63764 + e_FmSrcClk srcClk,
63765 + uint32_t freqInMhz)
63766 +{
63767 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63768 +
63769 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63770 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63771 +
63772 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
63773 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
63774 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
63775 +
63776 + return E_OK;
63777 +}
63778 +
63779 +/*****************************************************************************/
63780 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
63781 +{
63782 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63783 +
63784 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63785 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63786 +
63787 + p_Rtc->clockPeriodNanoSec = period;
63788 +
63789 + return E_OK;
63790 +}
63791 +
63792 +/*****************************************************************************/
63793 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
63794 +{
63795 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63796 +
63797 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63798 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63799 +
63800 + p_Rtc->p_RtcDriverParam->bypass = enabled;
63801 +
63802 + return E_OK;
63803 +}
63804 +
63805 +/*****************************************************************************/
63806 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
63807 +{
63808 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63809 +
63810 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63811 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63812 +
63813 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
63814 +
63815 + return E_OK;
63816 +}
63817 +
63818 +/*****************************************************************************/
63819 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
63820 +{
63821 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63822 +
63823 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63824 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63825 +
63826 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
63827 +
63828 + return E_OK;
63829 +}
63830 +
63831 +/*****************************************************************************/
63832 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
63833 +{
63834 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63835 +
63836 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63837 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63838 +
63839 + p_Rtc->outputClockDivisor = divisor;
63840 +
63841 + return E_OK;
63842 +}
63843 +
63844 +/*****************************************************************************/
63845 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
63846 +{
63847 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63848 +
63849 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63850 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63851 +
63852 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
63853 +
63854 + return E_OK;
63855 +}
63856 +
63857 +/*****************************************************************************/
63858 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
63859 + uint8_t alarmId,
63860 + e_FmRtcAlarmPolarity alarmPolarity)
63861 +{
63862 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63863 +
63864 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63865 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63866 +
63867 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
63868 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
63869 +
63870 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
63871 + (enum fman_rtc_alarm_polarity)alarmPolarity;
63872 +
63873 + return E_OK;
63874 +}
63875 +
63876 +/*****************************************************************************/
63877 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
63878 + uint8_t triggerId,
63879 + e_FmRtcTriggerPolarity triggerPolarity)
63880 +{
63881 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63882 +
63883 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63884 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63885 +
63886 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
63887 + {
63888 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
63889 + }
63890 +
63891 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
63892 + (enum fman_rtc_trigger_polarity)triggerPolarity;
63893 +
63894 + return E_OK;
63895 +}
63896 +
63897 +/*****************************************************************************/
63898 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
63899 +{
63900 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63901 +
63902 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63903 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63904 +
63905 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
63906 + return E_OK;
63907 +}
63908 +
63909 +/*****************************************************************************/
63910 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
63911 +{
63912 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63913 +
63914 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63915 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63916 +
63917 + /* TODO A check must be added here, that no timestamping MAC's
63918 + * are working in this stage. */
63919 + fman_rtc_disable(p_Rtc->p_MemMap);
63920 +
63921 + return E_OK;
63922 +}
63923 +
63924 +/*****************************************************************************/
63925 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
63926 +{
63927 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63928 +
63929 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63930 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63931 +
63932 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
63933 + return E_OK;
63934 +}
63935 +
63936 +/*****************************************************************************/
63937 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
63938 +{
63939 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63940 + uint64_t tmpAlarm;
63941 + bool enable = FALSE;
63942 +
63943 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63944 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63945 +
63946 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
63947 + {
63948 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
63949 + }
63950 +
63951 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
63952 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
63953 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
63954 + p_Rtc->clockPeriodNanoSec));
63955 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
63956 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
63957 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
63958 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
63959 + p_Rtc->clockPeriodNanoSec));
63960 +
63961 + if (p_FmRtcAlarmParams->f_AlarmCallback)
63962 + {
63963 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
63964 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
63965 + enable = TRUE;
63966 + }
63967 +
63968 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
63969 +
63970 + return E_OK;
63971 +}
63972 +
63973 +/*****************************************************************************/
63974 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
63975 +{
63976 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63977 + bool enable = FALSE;
63978 + uint64_t tmpFiper;
63979 +
63980 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
63981 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
63982 +
63983 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
63984 + {
63985 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
63986 + }
63987 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
63988 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
63989 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
63990 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
63991 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
63992 + p_Rtc->clockPeriodNanoSec));
63993 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
63994 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
63995 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
63996 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
63997 + p_Rtc->clockPeriodNanoSec));
63998 + if (tmpFiper & 0xffffffff00000000LL)
63999 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
64000 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
64001 + p_Rtc->clockPeriodNanoSec));
64002 +
64003 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
64004 + {
64005 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
64006 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
64007 + enable = TRUE;
64008 + }
64009 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
64010 + return E_OK;
64011 +}
64012 +
64013 +/*****************************************************************************/
64014 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
64015 +{
64016 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64017 +
64018 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64019 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64020 +
64021 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
64022 + {
64023 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
64024 + }
64025 +
64026 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
64027 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
64028 +
64029 + return E_OK;
64030 +}
64031 +
64032 +/*****************************************************************************/
64033 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
64034 +{
64035 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64036 + bool enable = FALSE;
64037 +
64038 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64039 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64040 +
64041 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64042 + {
64043 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
64044 + }
64045 +
64046 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
64047 + {
64048 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
64049 + enable = TRUE;
64050 + }
64051 +
64052 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
64053 + return E_OK;
64054 +}
64055 +
64056 +/*****************************************************************************/
64057 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
64058 +{
64059 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64060 +
64061 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64062 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64063 +
64064 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64065 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
64066 +
64067 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
64068 +
64069 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
64070 +
64071 + return E_OK;
64072 +}
64073 +
64074 +/*****************************************************************************/
64075 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
64076 + uint8_t triggerId,
64077 + uint64_t *p_TimeStamp)
64078 +{
64079 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64080 +
64081 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64082 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64083 +
64084 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64085 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
64086 +
64087 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
64088 +
64089 + return E_OK;
64090 +}
64091 +
64092 +/*****************************************************************************/
64093 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
64094 +{
64095 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64096 +
64097 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64098 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64099 +
64100 + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
64101 +
64102 + return E_OK;
64103 +}
64104 +
64105 +/*****************************************************************************/
64106 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
64107 +{
64108 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64109 +
64110 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64111 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64112 +
64113 + do_div(ts, p_Rtc->clockPeriodNanoSec);
64114 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
64115 +
64116 + return E_OK;
64117 +}
64118 +
64119 +/*****************************************************************************/
64120 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
64121 +{
64122 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64123 +
64124 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64125 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64126 +
64127 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
64128 +
64129 + return E_OK;
64130 +}
64131 +
64132 +/*****************************************************************************/
64133 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
64134 +{
64135 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64136 +
64137 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64138 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64139 +
64140 + /* set the new freqCompensation */
64141 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
64142 +
64143 + return E_OK;
64144 +}
64145 +
64146 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
64147 +/*****************************************************************************/
64148 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
64149 +{
64150 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64151 +
64152 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64153 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64154 +
64155 + /* enable interrupt */
64156 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
64157 +
64158 + return E_OK;
64159 +}
64160 +
64161 +/*****************************************************************************/
64162 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
64163 +{
64164 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64165 +
64166 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64167 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64168 +
64169 + /* disable interrupt */
64170 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
64171 +
64172 + return E_OK;
64173 +}
64174 +#endif
64175 --- /dev/null
64176 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
64177 @@ -0,0 +1,96 @@
64178 +/*
64179 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64180 + *
64181 + * Redistribution and use in source and binary forms, with or without
64182 + * modification, are permitted provided that the following conditions are met:
64183 + * * Redistributions of source code must retain the above copyright
64184 + * notice, this list of conditions and the following disclaimer.
64185 + * * Redistributions in binary form must reproduce the above copyright
64186 + * notice, this list of conditions and the following disclaimer in the
64187 + * documentation and/or other materials provided with the distribution.
64188 + * * Neither the name of Freescale Semiconductor nor the
64189 + * names of its contributors may be used to endorse or promote products
64190 + * derived from this software without specific prior written permission.
64191 + *
64192 + *
64193 + * ALTERNATIVELY, this software may be distributed under the terms of the
64194 + * GNU General Public License ("GPL") as published by the Free Software
64195 + * Foundation, either version 2 of that License or (at your option) any
64196 + * later version.
64197 + *
64198 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64199 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64200 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64201 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64202 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64203 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64204 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64205 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64206 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64207 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64208 + */
64209 +
64210 +
64211 +/******************************************************************************
64212 + @File fm_rtc.h
64213 +
64214 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
64215 +
64216 + @Cautions None
64217 +*//***************************************************************************/
64218 +
64219 +#ifndef __FM_RTC_H__
64220 +#define __FM_RTC_H__
64221 +
64222 +#include "std_ext.h"
64223 +#include "fm_rtc_ext.h"
64224 +
64225 +
64226 +#define __ERR_MODULE__ MODULE_FM_RTC
64227 +
64228 +/* General definitions */
64229 +
64230 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
64231 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
64232 +#define DEFAULT_BYPASS FALSE
64233 +#define DEFAULT_CLOCK_PERIOD 1000
64234 +
64235 +
64236 +
64237 +typedef struct t_FmRtcAlarm
64238 +{
64239 + t_FmRtcExceptionsCallback *f_AlarmCallback;
64240 + bool clearOnExpiration;
64241 +} t_FmRtcAlarm;
64242 +
64243 +typedef struct t_FmRtcPeriodicPulse
64244 +{
64245 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
64246 +} t_FmRtcPeriodicPulse;
64247 +
64248 +typedef struct t_FmRtcExternalTrigger
64249 +{
64250 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
64251 +} t_FmRtcExternalTrigger;
64252 +
64253 +
64254 +/**************************************************************************//**
64255 + @Description RTC FM driver control structure.
64256 +*//***************************************************************************/
64257 +typedef struct t_FmRtc
64258 +{
64259 + t_Part *p_Part; /**< Pointer to the integration device */
64260 + t_Handle h_Fm;
64261 + t_Handle h_App; /**< Application handle */
64262 + struct rtc_regs *p_MemMap;
64263 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
64264 + uint32_t srcClkFreqMhz;
64265 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
64266 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
64267 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
64268 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
64269 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
64270 +} t_FmRtc;
64271 +
64272 +
64273 +#endif /* __FM_RTC_H__ */
64274 --- /dev/null
64275 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
64276 @@ -0,0 +1,334 @@
64277 +/*
64278 + * Copyright 2008-2013 Freescale Semiconductor Inc.
64279 + *
64280 + * Redistribution and use in source and binary forms, with or without
64281 + * modification, are permitted provided that the following conditions are met:
64282 + * * Redistributions of source code must retain the above copyright
64283 + * notice, this list of conditions and the following disclaimer.
64284 + * * Redistributions in binary form must reproduce the above copyright
64285 + * notice, this list of conditions and the following disclaimer in the
64286 + * documentation and/or other materials provided with the distribution.
64287 + * * Neither the name of Freescale Semiconductor nor the
64288 + * names of its contributors may be used to endorse or promote products
64289 + * derived from this software without specific prior written permission.
64290 + *
64291 + *
64292 + * ALTERNATIVELY, this software may be distributed under the terms of the
64293 + * GNU General Public License ("GPL") as published by the Free Software
64294 + * Foundation, either version 2 of that License or (at your option) any
64295 + * later version.
64296 + *
64297 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64298 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64299 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64300 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64301 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64302 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64303 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64304 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64305 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64306 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64307 + */
64308 +
64309 +#include "fsl_fman_rtc.h"
64310 +
64311 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
64312 +{
64313 + int i;
64314 + cfg->src_clk = DEFAULT_SRC_CLOCK;
64315 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
64316 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
64317 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
64318 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
64319 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
64320 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
64321 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
64322 +}
64323 +
64324 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
64325 +{
64326 + return ioread32be(&regs->tmr_tevent);
64327 +}
64328 +
64329 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
64330 +{
64331 + return ioread32be(&regs->tmr_tevent) & ev_mask;
64332 +}
64333 +
64334 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
64335 +{
64336 + return ioread32be(&regs->tmr_temask);
64337 +}
64338 +
64339 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
64340 +{
64341 + iowrite32be(mask, &regs->tmr_temask);
64342 +}
64343 +
64344 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
64345 +{
64346 + iowrite32be(events, &regs->tmr_tevent);
64347 +}
64348 +
64349 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
64350 +{
64351 + uint32_t event;
64352 +
64353 + event = ioread32be(&regs->tmr_tevent);
64354 + event &= ioread32be(&regs->tmr_temask);
64355 +
64356 + if (event)
64357 + iowrite32be(event, &regs->tmr_tevent);
64358 + return event;
64359 +}
64360 +
64361 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
64362 +{
64363 + return ioread32be(&regs->tmr_add);
64364 +}
64365 +
64366 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
64367 +{
64368 + iowrite32be(val, &regs->tmr_add);
64369 +}
64370 +
64371 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
64372 +{
64373 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
64374 +}
64375 +
64376 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
64377 +{
64378 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
64379 +}
64380 +
64381 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
64382 +{
64383 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
64384 +}
64385 +
64386 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
64387 +{
64388 + iowrite32be(val, &regs->tmr_fiper[index]);
64389 +}
64390 +
64391 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
64392 +{
64393 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
64394 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
64395 +}
64396 +
64397 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
64398 +{
64399 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
64400 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
64401 +}
64402 +
64403 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
64404 +{
64405 + uint64_t time;
64406 + /* TMR_CNT_L must be read first to get an accurate value */
64407 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
64408 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
64409 + << 32);
64410 +
64411 + return time;
64412 +}
64413 +
64414 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
64415 +{
64416 + return ioread32be(&regs->tmr_ctrl);
64417 +}
64418 +
64419 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
64420 +{
64421 + iowrite32be(val, &regs->tmr_ctrl);
64422 +}
64423 +
64424 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
64425 +{
64426 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
64427 + udelay(10);
64428 + fman_rtc_set_timer_ctrl(regs, 0);
64429 +}
64430 +
64431 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
64432 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
64433 + uint32_t freq_compensation, uint32_t output_clock_divisor)
64434 +{
64435 + uint32_t tmr_ctrl;
64436 + int i;
64437 +
64438 + fman_rtc_timers_soft_reset(regs);
64439 +
64440 + /* Set the source clock */
64441 + switch (cfg->src_clk) {
64442 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
64443 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
64444 + break;
64445 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
64446 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
64447 + break;
64448 + default:
64449 + /* Use a clock from the External TMR reference clock.*/
64450 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
64451 + break;
64452 + }
64453 +
64454 + /* whatever period the user picked, the timestamp will advance in '1'
64455 + * every time the period passed. */
64456 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
64457 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
64458 +
64459 + if (cfg->invert_input_clk_phase)
64460 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
64461 + if (cfg->invert_output_clk_phase)
64462 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
64463 +
64464 + for (i = 0; i < num_alarms; i++) {
64465 + if (cfg->alarm_polarity[i] ==
64466 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
64467 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
64468 + }
64469 +
64470 + for (i = 0; i < num_ext_triggers; i++)
64471 + if (cfg->trigger_polarity[i] ==
64472 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
64473 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
64474 +
64475 + if (!cfg->timer_slave_mode && cfg->bypass)
64476 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
64477 +
64478 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
64479 + if (init_freq_comp)
64480 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
64481 +
64482 + /* Clear TMR_ALARM registers */
64483 + for (i = 0; i < num_alarms; i++)
64484 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
64485 +
64486 + /* Clear TMR_TEVENT */
64487 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
64488 +
64489 + /* Initialize TMR_TEMASK */
64490 + fman_rtc_set_interrupt_mask(regs, 0);
64491 +
64492 + /* Clear TMR_FIPER registers */
64493 + for (i = 0; i < num_fipers; i++)
64494 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
64495 +
64496 + /* Initialize TMR_PRSC */
64497 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
64498 +
64499 + /* Clear TMR_OFF */
64500 + fman_rtc_set_timer_offset(regs, 0);
64501 +}
64502 +
64503 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
64504 +{
64505 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
64506 +}
64507 +
64508 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
64509 +{
64510 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
64511 +
64512 + /* TODO check that no timestamping MACs are working in this stage. */
64513 + if (reset_clock) {
64514 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
64515 +
64516 + udelay(10);
64517 + /* Clear TMR_OFF */
64518 + fman_rtc_set_timer_offset(regs, 0);
64519 + }
64520 +
64521 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
64522 +}
64523 +
64524 +void fman_rtc_disable(struct rtc_regs *regs)
64525 +{
64526 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
64527 + & ~(FMAN_RTC_TMR_CTRL_TE)));
64528 +}
64529 +
64530 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
64531 +{
64532 + uint32_t tmp_reg;
64533 + if (id == 0)
64534 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
64535 + else
64536 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
64537 + fman_rtc_disable_interupt(regs, tmp_reg);
64538 +
64539 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
64540 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
64541 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
64542 +
64543 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
64544 +}
64545 +
64546 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
64547 +{
64548 + uint32_t tmpReg, tmp_ctrl;
64549 +
64550 + if (id == 0)
64551 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
64552 + else
64553 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
64554 + fman_rtc_disable_interupt(regs, tmpReg);
64555 +
64556 + if (id == 0)
64557 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
64558 + else
64559 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
64560 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
64561 + if (tmp_ctrl & tmpReg)
64562 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
64563 +}
64564 +
64565 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
64566 +{
64567 + uint32_t tmpReg;
64568 + fman_rtc_set_timer_alarm(regs, id, val);
64569 + if (enable) {
64570 + if (id == 0)
64571 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
64572 + else
64573 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
64574 + fman_rtc_enable_interupt(regs, tmpReg);
64575 + }
64576 +}
64577 +
64578 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
64579 + bool enable)
64580 +{
64581 + uint32_t tmpReg;
64582 + fman_rtc_set_timer_fiper(regs, id, val);
64583 + if (enable) {
64584 + if (id == 0)
64585 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
64586 + else
64587 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
64588 + fman_rtc_enable_interupt(regs, tmpReg);
64589 + }
64590 +}
64591 +
64592 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
64593 + bool use_pulse_as_input)
64594 +{
64595 + uint32_t tmpReg;
64596 + if (enable) {
64597 + if (id == 0)
64598 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
64599 + else
64600 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
64601 + fman_rtc_enable_interupt(regs, tmpReg);
64602 + }
64603 + if (use_pulse_as_input) {
64604 + if (id == 0)
64605 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
64606 + else
64607 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
64608 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
64609 + }
64610 +}
64611 --- /dev/null
64612 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
64613 @@ -0,0 +1,15 @@
64614 +#
64615 +# Makefile for the Freescale Ethernet controllers
64616 +#
64617 +ccflags-y += -DVERSION=\"\"
64618 +#
64619 +#Include netcomm SW specific definitions
64620 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
64621 +
64622 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
64623 +
64624 +ccflags-y += -I$(NCSW_FM_INC)
64625 +
64626 +obj-y += fsl-ncsw-sp.o
64627 +
64628 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
64629 --- /dev/null
64630 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
64631 @@ -0,0 +1,757 @@
64632 +/*
64633 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64634 + *
64635 + * Redistribution and use in source and binary forms, with or without
64636 + * modification, are permitted provided that the following conditions are met:
64637 + * * Redistributions of source code must retain the above copyright
64638 + * notice, this list of conditions and the following disclaimer.
64639 + * * Redistributions in binary form must reproduce the above copyright
64640 + * notice, this list of conditions and the following disclaimer in the
64641 + * documentation and/or other materials provided with the distribution.
64642 + * * Neither the name of Freescale Semiconductor nor the
64643 + * names of its contributors may be used to endorse or promote products
64644 + * derived from this software without specific prior written permission.
64645 + *
64646 + *
64647 + * ALTERNATIVELY, this software may be distributed under the terms of the
64648 + * GNU General Public License ("GPL") as published by the Free Software
64649 + * Foundation, either version 2 of that License or (at your option) any
64650 + * later version.
64651 + *
64652 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64653 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64654 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64655 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64656 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64657 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64658 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64659 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64660 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64661 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64662 + */
64663 +
64664 +
64665 +/******************************************************************************
64666 + @File fm_sp.c
64667 +
64668 + @Description FM PCD Storage profile ...
64669 +*//***************************************************************************/
64670 +
64671 +#include "std_ext.h"
64672 +#include "error_ext.h"
64673 +#include "string_ext.h"
64674 +#include "debug_ext.h"
64675 +#include "net_ext.h"
64676 +
64677 +#include "fm_vsp_ext.h"
64678 +#include "fm_sp.h"
64679 +#include "fm_common.h"
64680 +#include "fsl_fman_sp.h"
64681 +
64682 +
64683 +#if (DPAA_VERSION >= 11)
64684 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
64685 +{
64686 + t_Error err = E_OK;
64687 +
64688 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
64689 + RETURN_ERROR(MAJOR, err, NO_MSG);
64690 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
64691 + RETURN_ERROR(MAJOR, err, NO_MSG);
64692 + return err;
64693 +
64694 +}
64695 +
64696 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
64697 +{
64698 + t_Error err = E_OK;
64699 +
64700 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
64701 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
64702 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
64703 +
64704 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
64705 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
64706 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
64707 +
64708 + RETURN_ERROR(MAJOR, err, NO_MSG);
64709 +
64710 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
64711 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
64712 +
64713 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
64714 + p_FmVspEntry->portType,
64715 + p_FmVspEntry->portId,
64716 + p_FmVspEntry->relativeProfileId);
64717 +
64718 + return err;
64719 +}
64720 +#endif /* (DPAA_VERSION >= 11) */
64721 +
64722 +
64723 +/*****************************************************************************/
64724 +/* Inter-module API routines */
64725 +/*****************************************************************************/
64726 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
64727 + uint8_t *orderedArray,
64728 + uint16_t *sizesArray)
64729 +{
64730 + uint16_t bufSize = 0;
64731 + int i=0, j=0, k=0;
64732 +
64733 + /* First we copy the external buffers pools information to an ordered local array */
64734 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
64735 + {
64736 + /* get pool size */
64737 + bufSize = p_FmExtPools->extBufPool[i].size;
64738 +
64739 + /* keep sizes in an array according to poolId for direct access */
64740 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
64741 +
64742 + /* save poolId in an ordered array according to size */
64743 + for (j=0;j<=i;j++)
64744 + {
64745 + /* this is the next free place in the array */
64746 + if (j==i)
64747 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
64748 + else
64749 + {
64750 + /* find the right place for this poolId */
64751 + if (bufSize < sizesArray[orderedArray[j]])
64752 + {
64753 + /* move the poolIds one place ahead to make room for this poolId */
64754 + for (k=i;k>j;k--)
64755 + orderedArray[k] = orderedArray[k-1];
64756 +
64757 + /* now k==j, this is the place for the new size */
64758 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
64759 + break;
64760 + }
64761 + }
64762 + }
64763 + }
64764 +}
64765 +
64766 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
64767 + t_FmBackupBmPools *p_FmBackupBmPools,
64768 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
64769 +{
64770 +
64771 + int i = 0, j = 0;
64772 + bool found;
64773 + uint8_t count = 0;
64774 +
64775 + if (p_FmExtPools)
64776 + {
64777 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
64778 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
64779 +
64780 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
64781 + {
64782 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
64783 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
64784 + if (!p_FmExtPools->extBufPool[i].size)
64785 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
64786 + }
64787 + }
64788 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
64789 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
64790 +
64791 + /* backup BM pools indication is valid only for some chip derivatives
64792 + (limited by the config routine) */
64793 + if (p_FmBackupBmPools)
64794 + {
64795 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
64796 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
64797 + found = FALSE;
64798 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
64799 + {
64800 +
64801 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
64802 + {
64803 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
64804 + {
64805 + found = TRUE;
64806 + break;
64807 + }
64808 + }
64809 + if (!found)
64810 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
64811 + else
64812 + found = FALSE;
64813 + }
64814 + }
64815 +
64816 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
64817 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
64818 + {
64819 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
64820 + 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));
64821 +
64822 + if (!p_FmBufPoolDepletion->numOfPools)
64823 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
64824 +
64825 + found = FALSE;
64826 + count = 0;
64827 + /* for each pool that is in poolsToConsider, check if it is defined
64828 + in extBufPool */
64829 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
64830 + {
64831 + if (p_FmBufPoolDepletion->poolsToConsider[i])
64832 + {
64833 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
64834 + {
64835 + if (i == p_FmExtPools->extBufPool[j].id)
64836 + {
64837 + found = TRUE;
64838 + count++;
64839 + break;
64840 + }
64841 + }
64842 + if (!found)
64843 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
64844 + else
64845 + found = FALSE;
64846 + }
64847 + }
64848 + /* check that the number of pools that we have checked is equal to the number announced by the user */
64849 + if (count != p_FmBufPoolDepletion->numOfPools)
64850 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
64851 + }
64852 +
64853 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
64854 + {
64855 + /* calculate vector for number of pools depletion */
64856 + found = FALSE;
64857 + count = 0;
64858 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
64859 + {
64860 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
64861 + {
64862 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
64863 + {
64864 + if (i == p_FmExtPools->extBufPool[j].id)
64865 + {
64866 + found = TRUE;
64867 + count++;
64868 + break;
64869 + }
64870 + }
64871 + if (!found)
64872 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
64873 + else
64874 + found = FALSE;
64875 + }
64876 + }
64877 + if (!count)
64878 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
64879 + }
64880 +
64881 + return E_OK;
64882 +}
64883 +
64884 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
64885 +{
64886 + /* Check that divisible by 16 and not larger than 240 */
64887 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
64888 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
64889 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
64890 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
64891 +
64892 + /* check that ic size+ic internal offset, does not exceed ic block size */
64893 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
64894 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
64895 + /* Check that divisible by 16 and not larger than 256 */
64896 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
64897 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
64898 +
64899 + /* Check that divisible by 16 and not larger than 4K */
64900 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
64901 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
64902 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
64903 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
64904 +
64905 + return E_OK;
64906 +}
64907 +
64908 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
64909 +{
64910 + /* Check the margin definition */
64911 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
64912 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
64913 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
64914 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
64915 +
64916 + return E_OK;
64917 +}
64918 +
64919 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
64920 + t_FmBufferPrefixContent *p_BufferPrefixContent,
64921 + t_FmSpBufMargins *p_FmSpBufMargins,
64922 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
64923 + uint8_t *internalBufferOffset)
64924 +{
64925 + uint32_t tmp;
64926 +
64927 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
64928 + ASSERT_COND(p_FmSpIntContextDataCopy);
64929 + ASSERT_COND(p_BufferPrefixContent);
64930 + ASSERT_COND(p_FmSpBufMargins);
64931 + ASSERT_COND(p_FmSpBufferOffsets);
64932 +
64933 + /* Align start of internal context data to 16 byte */
64934 + p_FmSpIntContextDataCopy->extBufOffset =
64935 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
64936 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
64937 + p_BufferPrefixContent->privDataSize);
64938 +
64939 + /* Translate margin and intContext params to FM parameters */
64940 + /* Initialize with illegal value. Later we'll set legal values. */
64941 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
64942 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
64943 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
64944 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
64945 +
64946 + /* Internally the driver supports 4 options
64947 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
64948 + relate to it as 1).
64949 + 2. All IC context (from AD) not including debug.*/
64950 +
64951 + /* This 'if' covers option 2. We copy from beginning of context. */
64952 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
64953 + {
64954 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
64955 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
64956 + p_FmSpIntContextDataCopy->intContextOffset = 16;
64957 +
64958 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
64959 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
64960 + if (p_BufferPrefixContent->passPrsResult)
64961 + p_FmSpBufferOffsets->prsResultOffset =
64962 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
64963 + if (p_BufferPrefixContent->passTimeStamp)
64964 + p_FmSpBufferOffsets->timeStampOffset =
64965 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
64966 + if (p_BufferPrefixContent->passHashResult)
64967 + p_FmSpBufferOffsets->hashResultOffset =
64968 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
64969 + }
64970 + else
64971 + {
64972 + /* This case covers the options under 1 */
64973 + /* Copy size must be in 16-byte granularity. */
64974 + p_FmSpIntContextDataCopy->size =
64975 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
64976 + ((p_BufferPrefixContent->passTimeStamp ||
64977 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
64978 +
64979 + /* Align start of internal context data to 16 byte */
64980 + p_FmSpIntContextDataCopy->intContextOffset =
64981 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
64982 + ((p_BufferPrefixContent->passTimeStamp ||
64983 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
64984 +
64985 + if (p_BufferPrefixContent->passPrsResult)
64986 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
64987 + if (p_BufferPrefixContent->passTimeStamp)
64988 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
64989 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
64990 + p_FmSpIntContextDataCopy->extBufOffset;
64991 + if (p_BufferPrefixContent->passHashResult)
64992 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
64993 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
64994 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
64995 + p_FmSpIntContextDataCopy->extBufOffset + 8;
64996 + }
64997 +
64998 + if (p_FmSpIntContextDataCopy->size)
64999 + p_FmSpBufMargins->startMargins =
65000 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
65001 + p_FmSpIntContextDataCopy->size);
65002 + else
65003 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
65004 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
65005 +
65006 + /* save extra space for manip in both external and internal buffers */
65007 + if (p_BufferPrefixContent->manipExtraSpace)
65008 + {
65009 + uint8_t extraSpace;
65010 +#ifdef FM_CAPWAP_SUPPORT
65011 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
65012 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65013 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
65014 + 256-CAPWAP_FRAG_EXTRA_SPACE));
65015 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
65016 +#else
65017 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
65018 +#endif /* FM_CAPWAP_SUPPORT */
65019 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
65020 + p_FmSpBufMargins->startMargins += extraSpace;
65021 + *internalBufferOffset = extraSpace;
65022 + }
65023 +
65024 + /* align data start */
65025 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
65026 + if (tmp)
65027 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
65028 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
65029 +
65030 + return E_OK;
65031 +}
65032 +/*********************** End of inter-module routines ************************/
65033 +
65034 +
65035 +#if (DPAA_VERSION >= 11)
65036 +/*****************************************************************************/
65037 +/* API routines */
65038 +/*****************************************************************************/
65039 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
65040 +{
65041 + t_FmVspEntry *p_FmVspEntry = NULL;
65042 + struct fm_storage_profile_params fm_vsp_params;
65043 +
65044 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
65045 + if (!p_FmVspEntry)
65046 + {
65047 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
65048 + return NULL;
65049 + }
65050 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
65051 +
65052 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
65053 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
65054 + {
65055 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
65056 + XX_Free(p_FmVspEntry);
65057 + return NULL;
65058 + }
65059 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
65060 + fman_vsp_defconfig(&fm_vsp_params);
65061 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
65062 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
65063 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
65064 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
65065 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
65066 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
65067 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
65068 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
65069 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
65070 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
65071 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
65072 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
65073 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
65074 +
65075 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
65076 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
65077 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
65078 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
65079 +
65080 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
65081 +
65082 + return p_FmVspEntry;
65083 +}
65084 +
65085 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
65086 +{
65087 +
65088 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
65089 + struct fm_storage_profile_params fm_vsp_params;
65090 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
65091 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
65092 + t_Error err;
65093 + uint16_t absoluteProfileId = 0;
65094 + int i = 0;
65095 +
65096 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65097 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
65098 +
65099 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
65100 +
65101 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
65102 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
65103 +
65104 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
65105 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
65106 + &p_FmVspEntry->bufMargins,
65107 + &p_FmVspEntry->bufferOffsets,
65108 + &p_FmVspEntry->internalBufferOffset);
65109 + if (err != E_OK)
65110 + RETURN_ERROR(MAJOR, err, NO_MSG);
65111 +
65112 +
65113 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
65114 + if (err != E_OK)
65115 + RETURN_ERROR(MAJOR, err, NO_MSG);
65116 +
65117 +
65118 + p_FmVspEntry->p_FmSpRegsBase =
65119 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
65120 + if (!p_FmVspEntry->p_FmSpRegsBase)
65121 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
65122 +
65123 + /* order external buffer pools in ascending order of buffer pools sizes */
65124 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
65125 + orderedArray,
65126 + sizesArray);
65127 +
65128 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
65129 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
65130 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
65131 + {
65132 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
65133 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
65134 + }
65135 +
65136 + /* on user responsibility to fill it according requirement */
65137 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
65138 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
65139 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
65140 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
65141 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
65142 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
65143 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
65144 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
65145 +
65146 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
65147 + {
65148 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
65149 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
65150 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
65151 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
65152 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
65153 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
65154 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
65155 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
65156 + }
65157 + else
65158 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
65159 +
65160 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
65161 + {
65162 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
65163 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
65164 + }
65165 + else
65166 + fm_vsp_params.backup_pools.num_backup_pools = 0;
65167 +
65168 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
65169 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
65170 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
65171 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
65172 +
65173 + /* no check on err - it was checked earlier */
65174 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
65175 + p_FmVspEntry->portType,
65176 + p_FmVspEntry->portId,
65177 + p_FmVspEntry->relativeProfileId,
65178 + &absoluteProfileId);
65179 +
65180 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
65181 + ASSERT_COND(fm_vsp_params.int_context);
65182 + ASSERT_COND(fm_vsp_params.buf_margins);
65183 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
65184 +
65185 + /* Set all registers related to VSP */
65186 + 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);
65187 +
65188 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
65189 +
65190 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
65191 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
65192 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
65193 +
65194 + return E_OK;
65195 +}
65196 +
65197 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
65198 +{
65199 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
65200 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
65201 + XX_Free(p_FmVspEntry);
65202 + return E_OK;
65203 +}
65204 +
65205 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
65206 +{
65207 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65208 +
65209 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65210 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65211 +
65212 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
65213 + /* if dataAlign was not initialized by user, we return to driver's default */
65214 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
65215 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
65216 +
65217 + return E_OK;
65218 +}
65219 +
65220 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
65221 +{
65222 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65223 +
65224 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65225 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65226 +
65227 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
65228 +
65229 + return E_OK;
65230 +}
65231 +
65232 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
65233 +{
65234 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65235 +
65236 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65237 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65238 +
65239 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
65240 +
65241 + return E_OK;
65242 +}
65243 +
65244 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
65245 +{
65246 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65247 +
65248 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65249 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65250 +
65251 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
65252 +
65253 + return E_OK;
65254 +}
65255 +
65256 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
65257 +{
65258 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65259 +
65260 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65261 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65262 +
65263 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
65264 +
65265 + return E_OK;
65266 +}
65267 +
65268 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
65269 +{
65270 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65271 +
65272 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65273 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65274 +
65275 +
65276 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
65277 +
65278 + return E_OK;
65279 +}
65280 +
65281 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
65282 +{
65283 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65284 +
65285 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65286 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65287 +
65288 +
65289 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
65290 +
65291 + return E_OK;
65292 +}
65293 +
65294 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
65295 +{
65296 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65297 +
65298 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
65299 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65300 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
65301 +
65302 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
65303 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
65304 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
65305 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
65306 +
65307 + return E_OK;
65308 +}
65309 +
65310 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
65311 +{
65312 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65313 +
65314 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
65315 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65316 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
65317 +
65318 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
65319 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
65320 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
65321 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
65322 +
65323 + return E_OK;
65324 +}
65325 +
65326 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
65327 +{
65328 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65329 +
65330 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
65331 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
65332 +
65333 + return p_FmVspEntry->bufferOffsets.dataOffset;
65334 +}
65335 +
65336 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
65337 +{
65338 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65339 +
65340 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65341 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65342 +
65343 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
65344 + return NULL;
65345 +
65346 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
65347 +}
65348 +
65349 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
65350 +{
65351 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65352 +
65353 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65354 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65355 +
65356 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
65357 + return NULL;
65358 +
65359 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
65360 +}
65361 +
65362 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
65363 +{
65364 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65365 +
65366 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65367 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65368 +
65369 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
65370 + return NULL;
65371 +
65372 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
65373 +}
65374 +
65375 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
65376 +{
65377 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65378 +
65379 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65380 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65381 +
65382 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
65383 + return NULL;
65384 +
65385 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
65386 +}
65387 +
65388 +#endif /* (DPAA_VERSION >= 11) */
65389 --- /dev/null
65390 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
65391 @@ -0,0 +1,85 @@
65392 +/*
65393 + * Copyright 2008-2012 Freescale Semiconductor Inc.
65394 + *
65395 + * Redistribution and use in source and binary forms, with or without
65396 + * modification, are permitted provided that the following conditions are met:
65397 + * * Redistributions of source code must retain the above copyright
65398 + * notice, this list of conditions and the following disclaimer.
65399 + * * Redistributions in binary form must reproduce the above copyright
65400 + * notice, this list of conditions and the following disclaimer in the
65401 + * documentation and/or other materials provided with the distribution.
65402 + * * Neither the name of Freescale Semiconductor nor the
65403 + * names of its contributors may be used to endorse or promote products
65404 + * derived from this software without specific prior written permission.
65405 + *
65406 + *
65407 + * ALTERNATIVELY, this software may be distributed under the terms of the
65408 + * GNU General Public License ("GPL") as published by the Free Software
65409 + * Foundation, either version 2 of that License or (at your option) any
65410 + * later version.
65411 + *
65412 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
65413 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65414 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65415 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
65416 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65417 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65418 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65419 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65420 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65421 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65422 + */
65423 +
65424 +
65425 +/******************************************************************************
65426 + @File fm_sp.h
65427 +
65428 + @Description FM SP ...
65429 +*//***************************************************************************/
65430 +#ifndef __FM_SP_H
65431 +#define __FM_SP_H
65432 +
65433 +#include "std_ext.h"
65434 +#include "error_ext.h"
65435 +#include "list_ext.h"
65436 +
65437 +#include "fm_sp_common.h"
65438 +#include "fm_common.h"
65439 +
65440 +
65441 +#define __ERR_MODULE__ MODULE_FM_SP
65442 +
65443 +typedef struct {
65444 + t_FmBufferPrefixContent bufferPrefixContent;
65445 + e_FmDmaSwapOption dmaSwapData;
65446 + e_FmDmaCacheOption dmaIntContextCacheAttr;
65447 + e_FmDmaCacheOption dmaHeaderCacheAttr;
65448 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
65449 + bool dmaWriteOptimize;
65450 + uint16_t liodnOffset;
65451 + bool noScatherGather;
65452 + t_FmBufPoolDepletion *p_BufPoolDepletion;
65453 + t_FmBackupBmPools *p_BackupBmPools;
65454 + t_FmExtPools extBufPools;
65455 +} t_FmVspEntryDriverParams;
65456 +
65457 +typedef struct {
65458 + bool valid;
65459 + volatile bool lock;
65460 + uint8_t pointedOwners;
65461 + uint16_t absoluteSpId;
65462 + uint8_t internalBufferOffset;
65463 + t_FmSpBufMargins bufMargins;
65464 + t_FmSpIntContextDataCopy intContext;
65465 + t_FmSpBufferOffsets bufferOffsets;
65466 + t_Handle h_Fm;
65467 + e_FmPortType portType; /**< Port type */
65468 + uint8_t portId; /**< Port Id - relative to type */
65469 + uint8_t relativeProfileId;
65470 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
65471 + t_FmExtPools extBufPools;
65472 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
65473 +} t_FmVspEntry;
65474 +
65475 +
65476 +#endif /* __FM_SP_H */
65477 --- /dev/null
65478 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
65479 @@ -0,0 +1,197 @@
65480 +/*
65481 + * Copyright 2013 Freescale Semiconductor Inc.
65482 + *
65483 + * Redistribution and use in source and binary forms, with or without
65484 + * modification, are permitted provided that the following conditions are met:
65485 + * * Redistributions of source code must retain the above copyright
65486 + * notice, this list of conditions and the following disclaimer.
65487 + * * Redistributions in binary form must reproduce the above copyright
65488 + * notice, this list of conditions and the following disclaimer in the
65489 + * documentation and/or other materials provided with the distribution.
65490 + * * Neither the name of Freescale Semiconductor nor the
65491 + * names of its contributors may be used to endorse or promote products
65492 + * derived from this software without specific prior written permission.
65493 + *
65494 + *
65495 + * ALTERNATIVELY, this software may be distributed under the terms of the
65496 + * GNU General Public License ("GPL") as published by the Free Software
65497 + * Foundation, either version 2 of that License or (at your option) any
65498 + * later version.
65499 + *
65500 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
65501 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65502 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65503 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
65504 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65505 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65506 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65507 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65508 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65509 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65510 + */
65511 +
65512 +#include "fsl_fman_sp.h"
65513 +
65514 +
65515 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
65516 + uint16_t index)
65517 +{
65518 + struct fm_pcd_storage_profile_regs *sp_regs;
65519 + sp_regs = &regs[index];
65520 + return ioread32be(&sp_regs->fm_sp_acnt);
65521 +}
65522 +
65523 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
65524 + uint16_t index, uint32_t value)
65525 +{
65526 + struct fm_pcd_storage_profile_regs *sp_regs;
65527 + sp_regs = &regs[index];
65528 + iowrite32be(value, &sp_regs->fm_sp_acnt);
65529 +}
65530 +
65531 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
65532 +{
65533 + cfg->dma_swap_data =
65534 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
65535 + cfg->int_context_cache_attr =
65536 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
65537 + cfg->header_cache_attr =
65538 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
65539 + cfg->scatter_gather_cache_attr =
65540 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
65541 + cfg->dma_write_optimize =
65542 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
65543 + cfg->no_scather_gather =
65544 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
65545 +}
65546 +
65547 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
65548 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
65549 +{
65550 + int i, j;
65551 + uint32_t vector = 0;
65552 + for (i = 0; i < max_pools; i++)
65553 + if (pools[i])
65554 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
65555 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
65556 + vector |= mask >> j;
65557 + break;
65558 + }
65559 + return vector;
65560 +}
65561 +
65562 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
65563 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
65564 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
65565 + int max_num_of_pfc_priorities)
65566 +{
65567 + int i = 0, j = 0;
65568 + struct fm_pcd_storage_profile_regs *sp_regs;
65569 + uint32_t tmp_reg, vector;
65570 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
65571 + struct fman_buf_pool_depletion *buf_pool_depletion =
65572 + &fm_vsp_params->buf_pool_depletion;
65573 + struct fman_backup_bm_pools *backup_pools =
65574 + &fm_vsp_params->backup_pools;
65575 + struct fman_sp_int_context_data_copy *int_context_data_copy =
65576 + fm_vsp_params->int_context;
65577 + struct fman_sp_buf_margins *external_buffer_margins =
65578 + fm_vsp_params->buf_margins;
65579 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
65580 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
65581 +
65582 + sp_regs = &regs[index];
65583 +
65584 + /* fill external buffers manager pool information register*/
65585 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
65586 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
65587 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
65588 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
65589 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
65590 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
65591 + /* functionality available only for some deriviatives
65592 + (limited by config) */
65593 + for (j = 0; j < backup_pools->num_backup_pools; j++)
65594 + if (ext_buf_pools->ext_buf_pool[i].id ==
65595 + backup_pools->pool_ids[j]) {
65596 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
65597 + break;
65598 + }
65599 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
65600 + }
65601 +
65602 + /* clear unused pools */
65603 + for (i = ext_buf_pools->num_pools_used;
65604 + i < port_max_num_of_ext_pools; i++)
65605 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
65606 +
65607 + /* fill pool depletion register*/
65608 + tmp_reg = 0;
65609 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
65610 + /* calculate vector for number of pools depletion */
65611 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
65612 + pools_to_consider, ext_buf_pools, 0x80000000);
65613 +
65614 + /* configure num of pools and vector for number of pools mode */
65615 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
65616 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
65617 + tmp_reg |= vector;
65618 + }
65619 +
65620 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
65621 + /* calculate vector for number of pools depletion */
65622 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
65623 + pools_to_consider_for_single_mode,
65624 + ext_buf_pools, 0x00000080);
65625 +
65626 + /* configure num of pools and vector for number of pools mode */
65627 + tmp_reg |= vector;
65628 + }
65629 +
65630 + /* fill QbbPEV */
65631 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
65632 + vector = 0;
65633 + for (i = 0; i < max_num_of_pfc_priorities; i++)
65634 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
65635 + vector |= 0x00000100 << i;
65636 + tmp_reg |= vector;
65637 + }
65638 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
65639 +
65640 + /* fill dma attributes register */
65641 + tmp_reg = 0;
65642 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
65643 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
65644 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
65645 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
65646 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
65647 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
65648 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
65649 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
65650 + if (fm_vsp_params->dma_write_optimize)
65651 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
65652 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
65653 +
65654 + /* IC parameters - fill internal context parameters register */
65655 + tmp_reg = 0;
65656 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
65657 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
65658 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
65659 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
65660 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
65661 + FMAN_SP_IC_SIZE_SHIFT);
65662 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
65663 +
65664 + /* buffer margins - fill external buffer margins register */
65665 + tmp_reg = 0;
65666 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
65667 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
65668 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
65669 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
65670 + if (no_scather_gather)
65671 + tmp_reg |= FMAN_SP_SG_DISABLE;
65672 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
65673 +
65674 + /* buffer margins - fill spliodn register */
65675 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
65676 +}
65677 --- /dev/null
65678 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
65679 @@ -0,0 +1,5216 @@
65680 +/*
65681 + * Copyright 2008-2012 Freescale Semiconductor Inc.
65682 + *
65683 + * Redistribution and use in source and binary forms, with or without
65684 + * modification, are permitted provided that the following conditions are met:
65685 + * * Redistributions of source code must retain the above copyright
65686 + * notice, this list of conditions and the following disclaimer.
65687 + * * Redistributions in binary form must reproduce the above copyright
65688 + * notice, this list of conditions and the following disclaimer in the
65689 + * documentation and/or other materials provided with the distribution.
65690 + * * Neither the name of Freescale Semiconductor nor the
65691 + * names of its contributors may be used to endorse or promote products
65692 + * derived from this software without specific prior written permission.
65693 + *
65694 + *
65695 + * ALTERNATIVELY, this software may be distributed under the terms of the
65696 + * GNU General Public License ("GPL") as published by the Free Software
65697 + * Foundation, either version 2 of that License or (at your option) any
65698 + * later version.
65699 + *
65700 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
65701 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65702 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65703 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
65704 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65705 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65706 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65707 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65708 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65709 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65710 + */
65711 +
65712 +
65713 +/******************************************************************************
65714 + @File fm.c
65715 +
65716 + @Description FM driver routines implementation.
65717 +*//***************************************************************************/
65718 +#include "std_ext.h"
65719 +#include "error_ext.h"
65720 +#include "xx_ext.h"
65721 +#include "string_ext.h"
65722 +#include "sprint_ext.h"
65723 +#include "debug_ext.h"
65724 +#include "fm_muram_ext.h"
65725 +#include <linux/math64.h>
65726 +
65727 +#include "fm_common.h"
65728 +#include "fm_ipc.h"
65729 +#include "fm.h"
65730 +#ifndef CONFIG_FMAN_ARM
65731 +#include <linux/fsl/svr.h>
65732 +#endif
65733 +#include "fsl_fman.h"
65734 +
65735 +
65736 +/****************************************/
65737 +/* static functions */
65738 +/****************************************/
65739 +
65740 +static volatile bool blockingFlag = FALSE;
65741 +static void IpcMsgCompletionCB(t_Handle h_Fm,
65742 + uint8_t *p_Msg,
65743 + uint8_t *p_Reply,
65744 + uint32_t replyLength,
65745 + t_Error status)
65746 +{
65747 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
65748 + blockingFlag = FALSE;
65749 +}
65750 +
65751 +static void FreeInitResources(t_Fm *p_Fm)
65752 +{
65753 + if (p_Fm->camBaseAddr)
65754 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
65755 + if (p_Fm->fifoBaseAddr)
65756 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
65757 + if (p_Fm->resAddr)
65758 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
65759 +}
65760 +
65761 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
65762 +{
65763 + t_FMIramRegs *p_Iram;
65764 +
65765 + ASSERT_COND(p_Fm);
65766 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
65767 +
65768 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
65769 +}
65770 +
65771 +static t_Error CheckFmParameters(t_Fm *p_Fm)
65772 +{
65773 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
65774 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
65775 +#if (DPAA_VERSION < 11)
65776 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
65777 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
65778 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65779 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
65780 +#endif /* (DPAA_VERSION < 11) */
65781 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
65782 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
65783 +// 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))
65784 +// 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));
65785 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
65786 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
65787 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
65788 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
65789 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
65790 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
65791 +#if (DPAA_VERSION < 11)
65792 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
65793 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
65794 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
65795 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
65796 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
65797 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
65798 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
65799 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
65800 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
65801 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
65802 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
65803 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
65804 +#else /* (DPAA_VERSION >= 11) */
65805 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
65806 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
65807 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
65808 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
65809 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
65810 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
65811 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
65812 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
65813 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
65814 +#ifdef FM_AID_MODE_NO_TNUM_SW005
65815 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
65816 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
65817 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
65818 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
65819 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
65820 +#endif /* (DPAA_VERSION < 11) */
65821 +
65822 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
65823 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
65824 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
65825 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65826 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
65827 +
65828 +#if (DPAA_VERSION >= 11)
65829 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
65830 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
65831 +#endif /* (DPAA_VERSION >= 11) */
65832 +
65833 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
65834 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
65835 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
65836 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
65837 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65838 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
65839 + p_Fm->p_FmStateStruct->totalFifoSize,
65840 + BMI_MAX_FIFO_SIZE));
65841 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
65842 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
65843 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
65844 +
65845 +#ifdef FM_HAS_TOTAL_DMAS
65846 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
65847 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
65848 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
65849 +#endif /* FM_HAS_TOTAL_DMAS */
65850 +
65851 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
65852 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
65853 +
65854 + if (!p_Fm->f_Exception)
65855 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
65856 + if (!p_Fm->f_BusError)
65857 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
65858 +
65859 +#ifdef FM_NO_WATCHDOG
65860 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
65861 + (p_Fm->p_FmDriverParam->dma_watchdog))
65862 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
65863 +#endif /* FM_NO_WATCHDOG */
65864 +
65865 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
65866 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
65867 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
65868 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
65869 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
65870 +
65871 +#ifdef FM_NO_TNUM_AGING
65872 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
65873 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
65874 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
65875 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
65876 +#endif /* FM_NO_TNUM_AGING */
65877 +
65878 + /* check that user did not set revision-dependent exceptions */
65879 +#ifdef FM_NO_DISPATCH_RAM_ECC
65880 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
65881 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
65882 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
65883 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
65884 +#endif /* FM_NO_DISPATCH_RAM_ECC */
65885 +
65886 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
65887 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
65888 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
65889 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
65890 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
65891 +
65892 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
65893 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
65894 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
65895 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
65896 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
65897 +
65898 + return E_OK;
65899 +}
65900 +
65901 +
65902 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
65903 +{
65904 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
65905 +
65906 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
65907 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
65908 +
65909 + /* If the MAC is running on guest-partition and we have IPC session with it,
65910 + we inform him about the event through IPC; otherwise, we ignore the event. */
65911 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
65912 + {
65913 + t_Error err;
65914 + t_FmIpcIsr fmIpcIsr;
65915 + t_FmIpcMsg msg;
65916 +
65917 + memset(&msg, 0, sizeof(msg));
65918 + msg.msgId = FM_GUEST_ISR;
65919 + fmIpcIsr.pendingReg = pendingReg;
65920 + fmIpcIsr.boolErr = FALSE;
65921 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
65922 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
65923 + (uint8_t*)&msg,
65924 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
65925 + NULL,
65926 + NULL,
65927 + NULL,
65928 + NULL);
65929 + if (err != E_OK)
65930 + REPORT_ERROR(MINOR, err, NO_MSG);
65931 + }
65932 + else
65933 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
65934 +}
65935 +
65936 +static void BmiErrEvent(t_Fm *p_Fm)
65937 +{
65938 + uint32_t event;
65939 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
65940 +
65941 +
65942 + event = fman_get_bmi_err_event(bmi_rg);
65943 +
65944 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
65945 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
65946 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
65947 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
65948 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
65949 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
65950 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
65951 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
65952 +}
65953 +
65954 +static void QmiErrEvent(t_Fm *p_Fm)
65955 +{
65956 + uint32_t event;
65957 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
65958 +
65959 + event = fman_get_qmi_err_event(qmi_rg);
65960 +
65961 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
65962 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
65963 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
65964 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
65965 +}
65966 +
65967 +static void DmaErrEvent(t_Fm *p_Fm)
65968 +{
65969 + uint32_t status, com_id;
65970 + uint8_t tnum;
65971 + uint8_t hardwarePortId;
65972 + uint8_t relativePortId;
65973 + uint16_t liodn;
65974 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
65975 +
65976 + status = fman_get_dma_err_event(dma_rg);
65977 +
65978 + if (status & DMA_STATUS_BUS_ERR)
65979 + {
65980 + com_id = fman_get_dma_com_id(dma_rg);
65981 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
65982 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
65983 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
65984 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
65985 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
65986 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
65987 + p_Fm->f_BusError(p_Fm->h_App,
65988 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
65989 + relativePortId,
65990 + fman_get_dma_addr(dma_rg),
65991 + tnum,
65992 + liodn);
65993 + }
65994 + if (status & DMA_STATUS_FM_SPDAT_ECC)
65995 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
65996 + if (status & DMA_STATUS_READ_ECC)
65997 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
65998 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
65999 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
66000 + if (status & DMA_STATUS_FM_WRITE_ECC)
66001 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
66002 + }
66003 +
66004 +static void FpmErrEvent(t_Fm *p_Fm)
66005 +{
66006 + uint32_t event;
66007 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66008 +
66009 + event = fman_get_fpm_err_event(fpm_rg);
66010 +
66011 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
66012 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
66013 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
66014 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
66015 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
66016 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
66017 +}
66018 +
66019 +static void MuramErrIntr(t_Fm *p_Fm)
66020 +{
66021 + uint32_t event;
66022 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66023 +
66024 + event = fman_get_muram_err_event(fpm_rg);
66025 +
66026 + if (event & FPM_RAM_MURAM_ECC)
66027 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
66028 +}
66029 +
66030 +static void IramErrIntr(t_Fm *p_Fm)
66031 +{
66032 + uint32_t event;
66033 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66034 +
66035 + event = fman_get_iram_err_event(fpm_rg);
66036 +
66037 + if (event & FPM_RAM_IRAM_ECC)
66038 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
66039 +}
66040 +
66041 +static void QmiEvent(t_Fm *p_Fm)
66042 +{
66043 + uint32_t event;
66044 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66045 +
66046 + event = fman_get_qmi_event(qmi_rg);
66047 +
66048 + if (event & QMI_INTR_EN_SINGLE_ECC)
66049 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
66050 +}
66051 +
66052 +static void UnimplementedIsr(t_Handle h_Arg)
66053 +{
66054 + UNUSED(h_Arg);
66055 +
66056 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
66057 +}
66058 +
66059 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
66060 +{
66061 + UNUSED(h_Arg); UNUSED(event);
66062 +
66063 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
66064 +}
66065 +
66066 +static void EnableTimeStamp(t_Fm *p_Fm)
66067 +{
66068 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66069 +
66070 + ASSERT_COND(p_Fm->p_FmStateStruct);
66071 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
66072 +
66073 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
66074 +
66075 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
66076 +}
66077 +
66078 +static t_Error ClearIRam(t_Fm *p_Fm)
66079 +{
66080 + t_FMIramRegs *p_Iram;
66081 + int i;
66082 + int iram_size;
66083 +
66084 + ASSERT_COND(p_Fm);
66085 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66086 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
66087 +
66088 + /* Enable the auto-increment */
66089 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
66090 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
66091 +
66092 + for (i=0; i < (iram_size/4); i++)
66093 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
66094 +
66095 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
66096 + CORE_MemoryBarrier();
66097 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
66098 +
66099 + return E_OK;
66100 +}
66101 +
66102 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
66103 +{
66104 + t_FMIramRegs *p_Iram;
66105 + int i;
66106 + uint32_t tmp;
66107 + uint8_t compTo16;
66108 +
66109 + ASSERT_COND(p_Fm);
66110 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66111 +
66112 + /* Enable the auto-increment */
66113 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
66114 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
66115 +
66116 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
66117 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
66118 +
66119 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
66120 + if (compTo16)
66121 + for (i=0; i < ((16-compTo16) / 4); i++)
66122 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
66123 +
66124 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
66125 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
66126 +
66127 + /* verify that writing has completed */
66128 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
66129 +
66130 + if (p_Fm->fwVerify)
66131 + {
66132 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
66133 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
66134 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
66135 + {
66136 + tmp = GET_UINT32(p_Iram->idata);
66137 + if (tmp != p_Fm->firmware.p_Code[i])
66138 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
66139 + ("UCode write error : write 0x%x, read 0x%x",
66140 + p_Fm->firmware.p_Code[i],tmp));
66141 + }
66142 + WRITE_UINT32(p_Iram->iadd, 0x0);
66143 + }
66144 +
66145 + /* Enable patch from IRAM */
66146 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
66147 + XX_UDelay(1000);
66148 +
66149 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
66150 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
66151 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
66152 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
66153 +
66154 + return E_OK;
66155 +}
66156 +
66157 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
66158 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
66159 +{
66160 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66161 + uint32_t tmpReg;
66162 + uint32_t savedSpliodn[63];
66163 +
66164 + /* write to IRAM first location the debug instruction */
66165 + WRITE_UINT32(p_Iram->iadd, 0);
66166 + while (GET_UINT32(p_Iram->iadd) != 0) ;
66167 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
66168 +
66169 + WRITE_UINT32(p_Iram->iadd, 0);
66170 + while (GET_UINT32(p_Iram->iadd) != 0) ;
66171 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
66172 +
66173 + /* Enable patch from IRAM */
66174 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
66175 + CORE_MemoryBarrier();
66176 + XX_UDelay(100);
66177 + IO2MemCpy32((uint8_t *)savedSpliodn,
66178 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
66179 + 63*sizeof(uint32_t));
66180 +
66181 + /* reset FMAN */
66182 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66183 + CORE_MemoryBarrier();
66184 + XX_UDelay(100);
66185 +
66186 + /* verify breakpoint debug status register */
66187 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
66188 + if (!tmpReg)
66189 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
66190 +
66191 + /*************************************/
66192 + /* Load FMan-Controller code to IRAM */
66193 + /*************************************/
66194 + ClearIRam(p_Fm);
66195 + if (p_Fm->firmware.p_Code &&
66196 + (LoadFmanCtrlCode(p_Fm) != E_OK))
66197 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
66198 + XX_UDelay(100);
66199 +
66200 + /* reset FMAN again to start the microcode */
66201 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66202 + CORE_MemoryBarrier();
66203 + XX_UDelay(100);
66204 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
66205 + (uint8_t *)savedSpliodn,
66206 + 63*sizeof(uint32_t));
66207 +
66208 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
66209 + {
66210 + fman_resume(p_Fm->p_FmFpmRegs);
66211 + CORE_MemoryBarrier();
66212 + XX_UDelay(100);
66213 + }
66214 +
66215 + return E_OK;
66216 +}
66217 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
66218 +
66219 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
66220 +{
66221 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
66222 +do { \
66223 + 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);\
66224 +} while (0)
66225 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
66226 +do { \
66227 + 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);\
66228 +} while (0)
66229 +
66230 + /* error interrupts */
66231 + if (pending & ERR_INTR_EN_1G_MAC0)
66232 + FM_G_CALL_1G_MAC_ERR_ISR(0);
66233 + if (pending & ERR_INTR_EN_1G_MAC1)
66234 + FM_G_CALL_1G_MAC_ERR_ISR(1);
66235 + if (pending & ERR_INTR_EN_1G_MAC2)
66236 + FM_G_CALL_1G_MAC_ERR_ISR(2);
66237 + if (pending & ERR_INTR_EN_1G_MAC3)
66238 + FM_G_CALL_1G_MAC_ERR_ISR(3);
66239 + if (pending & ERR_INTR_EN_1G_MAC4)
66240 + FM_G_CALL_1G_MAC_ERR_ISR(4);
66241 + if (pending & ERR_INTR_EN_1G_MAC5)
66242 + FM_G_CALL_1G_MAC_ERR_ISR(5);
66243 + if (pending & ERR_INTR_EN_1G_MAC6)
66244 + FM_G_CALL_1G_MAC_ERR_ISR(6);
66245 + if (pending & ERR_INTR_EN_1G_MAC7)
66246 + FM_G_CALL_1G_MAC_ERR_ISR(7);
66247 + if (pending & ERR_INTR_EN_10G_MAC0)
66248 + FM_G_CALL_10G_MAC_ERR_ISR(0);
66249 + if (pending & ERR_INTR_EN_10G_MAC1)
66250 + FM_G_CALL_10G_MAC_ERR_ISR(1);
66251 +}
66252 +
66253 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
66254 +{
66255 +#define FM_G_CALL_1G_MAC_ISR(_id) \
66256 +do { \
66257 + 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);\
66258 +} while (0)
66259 +#define FM_G_CALL_10G_MAC_ISR(_id) \
66260 +do { \
66261 + 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);\
66262 +} while (0)
66263 +
66264 + if (pending & INTR_EN_1G_MAC0)
66265 + FM_G_CALL_1G_MAC_ISR(0);
66266 + if (pending & INTR_EN_1G_MAC1)
66267 + FM_G_CALL_1G_MAC_ISR(1);
66268 + if (pending & INTR_EN_1G_MAC2)
66269 + FM_G_CALL_1G_MAC_ISR(2);
66270 + if (pending & INTR_EN_1G_MAC3)
66271 + FM_G_CALL_1G_MAC_ISR(3);
66272 + if (pending & INTR_EN_1G_MAC4)
66273 + FM_G_CALL_1G_MAC_ISR(4);
66274 + if (pending & INTR_EN_1G_MAC5)
66275 + FM_G_CALL_1G_MAC_ISR(5);
66276 + if (pending & INTR_EN_1G_MAC6)
66277 + FM_G_CALL_1G_MAC_ISR(6);
66278 + if (pending & INTR_EN_1G_MAC7)
66279 + FM_G_CALL_1G_MAC_ISR(7);
66280 + if (pending & INTR_EN_10G_MAC0)
66281 + FM_G_CALL_10G_MAC_ISR(0);
66282 + if (pending & INTR_EN_10G_MAC1)
66283 + FM_G_CALL_10G_MAC_ISR(1);
66284 + if (pending & INTR_EN_TMR)
66285 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
66286 +}
66287 +
66288 +#if (DPAA_VERSION >= 11)
66289 +static t_Error SetVSPWindow(t_Handle h_Fm,
66290 + uint8_t hardwarePortId,
66291 + uint8_t baseStorageProfile,
66292 + uint8_t log2NumOfProfiles)
66293 +{
66294 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66295 +
66296 + ASSERT_COND(h_Fm);
66297 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66298 +
66299 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66300 + !p_Fm->p_FmBmiRegs &&
66301 + p_Fm->h_IpcSessions[0])
66302 + {
66303 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
66304 + t_FmIpcMsg msg;
66305 + t_Error err = E_OK;
66306 +
66307 + memset(&msg, 0, sizeof(msg));
66308 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
66309 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
66310 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
66311 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
66312 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
66313 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
66314 +
66315 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66316 + (uint8_t*)&msg,
66317 + sizeof(msg.msgId),
66318 + NULL,
66319 + NULL,
66320 + NULL,
66321 + NULL);
66322 + if (err != E_OK)
66323 + RETURN_ERROR(MINOR, err, NO_MSG);
66324 + return E_OK;
66325 + }
66326 + else if (!p_Fm->p_FmBmiRegs)
66327 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66328 + ("Either IPC or 'baseAddress' is required!"));
66329 +
66330 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
66331 + hardwarePortId,
66332 + baseStorageProfile,
66333 + log2NumOfProfiles);
66334 +
66335 + return E_OK;
66336 +}
66337 +
66338 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
66339 +{
66340 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66341 + uint8_t profilesFound = 0;
66342 + int i = 0;
66343 + uint32_t intFlags;
66344 +
66345 + if (!numOfProfiles)
66346 + return E_OK;
66347 +
66348 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
66349 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
66350 + return (uint8_t)ILLEGAL_BASE;
66351 +
66352 + if (p_Fm->h_IpcSessions[0])
66353 + {
66354 + t_FmIpcResourceAllocParams ipcAllocParams;
66355 + t_FmIpcMsg msg;
66356 + t_FmIpcReply reply;
66357 + t_Error err;
66358 + uint32_t replyLength;
66359 +
66360 + memset(&msg, 0, sizeof(msg));
66361 + memset(&reply, 0, sizeof(reply));
66362 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
66363 + ipcAllocParams.guestId = p_Fm->guestId;
66364 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
66365 + ipcAllocParams.base = p_Fm->partVSPBase;
66366 + msg.msgId = FM_VSP_ALLOC;
66367 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
66368 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66369 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66370 + (uint8_t*)&msg,
66371 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
66372 + (uint8_t*)&reply,
66373 + &replyLength,
66374 + NULL,
66375 + NULL);
66376 + if ((err != E_OK) ||
66377 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
66378 + RETURN_ERROR(MAJOR, err, NO_MSG);
66379 + else
66380 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
66381 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
66382 + RETURN_ERROR(MAJOR, err, NO_MSG);
66383 + }
66384 + if (p_Fm->guestId != NCSW_MASTER_ID)
66385 + {
66386 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
66387 + return (uint8_t)ILLEGAL_BASE;
66388 + }
66389 +
66390 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66391 + for (i = base; i < base + numOfProfiles; i++)
66392 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
66393 + profilesFound++;
66394 + else
66395 + break;
66396 +
66397 + if (profilesFound == numOfProfiles)
66398 + for (i = base; i<base + numOfProfiles; i++)
66399 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
66400 + else
66401 + {
66402 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66403 + return (uint8_t)ILLEGAL_BASE;
66404 + }
66405 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66406 +
66407 + return base;
66408 +}
66409 +
66410 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
66411 +{
66412 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66413 + int i = 0;
66414 +
66415 + ASSERT_COND(p_Fm);
66416 +
66417 + if (p_Fm->h_IpcSessions[0])
66418 + {
66419 + t_FmIpcResourceAllocParams ipcAllocParams;
66420 + t_FmIpcMsg msg;
66421 + t_FmIpcReply reply;
66422 + uint32_t replyLength;
66423 + t_Error err;
66424 +
66425 + memset(&msg, 0, sizeof(msg));
66426 + memset(&reply, 0, sizeof(reply));
66427 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
66428 + ipcAllocParams.guestId = p_Fm->guestId;
66429 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
66430 + ipcAllocParams.base = p_Fm->partVSPBase;
66431 + msg.msgId = FM_VSP_FREE;
66432 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
66433 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66434 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66435 + (uint8_t*)&msg,
66436 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
66437 + (uint8_t*)&reply,
66438 + &replyLength,
66439 + NULL,
66440 + NULL);
66441 + if (err != E_OK)
66442 + REPORT_ERROR(MAJOR, err, NO_MSG);
66443 + return;
66444 + }
66445 + if (p_Fm->guestId != NCSW_MASTER_ID)
66446 + {
66447 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
66448 + return;
66449 + }
66450 +
66451 + ASSERT_COND(p_Fm->p_FmSp);
66452 +
66453 + for (i=base; i<numOfProfiles; i++)
66454 + {
66455 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
66456 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
66457 + else
66458 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
66459 + }
66460 +}
66461 +#endif /* (DPAA_VERSION >= 11) */
66462 +
66463 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
66464 + uint8_t *p_Msg,
66465 + uint32_t msgLength,
66466 + uint8_t *p_Reply,
66467 + uint32_t *p_ReplyLength)
66468 +{
66469 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66470 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
66471 +
66472 + UNUSED(p_Reply);
66473 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66474 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
66475 +
66476 +#ifdef DISABLE_SANITY_CHECKS
66477 + UNUSED(msgLength);
66478 +#endif /* DISABLE_SANITY_CHECKS */
66479 +
66480 + ASSERT_COND(p_Msg);
66481 +
66482 + *p_ReplyLength = 0;
66483 +
66484 + switch (p_IpcMsg->msgId)
66485 + {
66486 + case (FM_GUEST_ISR):
66487 + {
66488 + t_FmIpcIsr ipcIsr;
66489 +
66490 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
66491 + if (ipcIsr.boolErr)
66492 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
66493 + else
66494 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
66495 + break;
66496 + }
66497 + default:
66498 + *p_ReplyLength = 0;
66499 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
66500 + }
66501 + return E_OK;
66502 +}
66503 +
66504 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
66505 + uint8_t *p_Msg,
66506 + uint32_t msgLength,
66507 + uint8_t *p_Reply,
66508 + uint32_t *p_ReplyLength)
66509 +{
66510 + t_Error err;
66511 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66512 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
66513 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
66514 +
66515 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66516 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
66517 +
66518 +#ifdef DISABLE_SANITY_CHECKS
66519 + UNUSED(msgLength);
66520 +#endif /* DISABLE_SANITY_CHECKS */
66521 +
66522 + ASSERT_COND(p_IpcMsg);
66523 +
66524 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
66525 + *p_ReplyLength = 0;
66526 +
66527 + switch (p_IpcMsg->msgId)
66528 + {
66529 + case (FM_GET_SET_PORT_PARAMS):
66530 + {
66531 + t_FmIpcPortInInitParams ipcInitParams;
66532 + t_FmInterModulePortInitParams initParams;
66533 + t_FmIpcPortOutInitParams ipcOutInitParams;
66534 +
66535 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
66536 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
66537 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
66538 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
66539 + initParams.liodnOffset = ipcInitParams.liodnOffset;
66540 + initParams.numOfTasks = ipcInitParams.numOfTasks;
66541 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
66542 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
66543 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
66544 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
66545 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
66546 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
66547 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
66548 + initParams.liodnBase = ipcInitParams.liodnBase;
66549 +
66550 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
66551 +
66552 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
66553 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
66554 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
66555 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
66556 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
66557 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
66558 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
66559 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
66560 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
66561 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
66562 + break;
66563 + }
66564 + case (FM_SET_SIZE_OF_FIFO):
66565 + {
66566 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
66567 +
66568 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
66569 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
66570 + ipcPortRsrcParams.hardwarePortId,
66571 + &ipcPortRsrcParams.val,
66572 + &ipcPortRsrcParams.extra,
66573 + (bool)ipcPortRsrcParams.boolInitialConfig);
66574 + *p_ReplyLength = sizeof(uint32_t);
66575 + break;
66576 + }
66577 + case (FM_SET_NUM_OF_TASKS):
66578 + {
66579 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
66580 +
66581 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
66582 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
66583 + (uint8_t*)&ipcPortRsrcParams.val,
66584 + (uint8_t*)&ipcPortRsrcParams.extra,
66585 + (bool)ipcPortRsrcParams.boolInitialConfig);
66586 + *p_ReplyLength = sizeof(uint32_t);
66587 + break;
66588 + }
66589 + case (FM_SET_NUM_OF_OPEN_DMAS):
66590 + {
66591 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
66592 +
66593 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
66594 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
66595 + (uint8_t*)&ipcPortRsrcParams.val,
66596 + (uint8_t*)&ipcPortRsrcParams.extra,
66597 + (bool)ipcPortRsrcParams.boolInitialConfig);
66598 + *p_ReplyLength = sizeof(uint32_t);
66599 + break;
66600 + }
66601 + case (FM_RESUME_STALLED_PORT):
66602 + *p_ReplyLength = sizeof(uint32_t);
66603 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
66604 + break;
66605 + case (FM_MASTER_IS_ALIVE):
66606 + {
66607 + uint8_t guestId = p_IpcMsg->msgBody[0];
66608 + /* build the FM master partition IPC address */
66609 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
66610 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
66611 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
66612 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
66613 + if (p_Fm->h_IpcSessions[guestId] == NULL)
66614 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
66615 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
66616 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
66617 + break;
66618 + }
66619 + case (FM_IS_PORT_STALLED):
66620 + {
66621 + bool tmp;
66622 +
66623 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
66624 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
66625 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
66626 + break;
66627 + }
66628 + case (FM_RESET_MAC):
66629 + {
66630 + t_FmIpcMacParams ipcMacParams;
66631 +
66632 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
66633 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
66634 + (e_FmMacType)(ipcMacParams.enumType),
66635 + ipcMacParams.id);
66636 + *p_ReplyLength = sizeof(uint32_t);
66637 + break;
66638 + }
66639 + case (FM_SET_MAC_MAX_FRAME):
66640 + {
66641 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
66642 +
66643 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
66644 + err = FmSetMacMaxFrame(p_Fm,
66645 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
66646 + ipcMacMaxFrameParams.macParams.id,
66647 + ipcMacMaxFrameParams.maxFrameLength);
66648 + if (err != E_OK)
66649 + REPORT_ERROR(MINOR, err, NO_MSG);
66650 + break;
66651 + }
66652 +#if (DPAA_VERSION >= 11)
66653 + case (FM_VSP_ALLOC) :
66654 + {
66655 + t_FmIpcResourceAllocParams ipcAllocParams;
66656 + uint8_t vspBase;
66657 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
66658 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
66659 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
66660 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
66661 + break;
66662 + }
66663 + case (FM_VSP_FREE) :
66664 + {
66665 + t_FmIpcResourceAllocParams ipcAllocParams;
66666 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
66667 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
66668 + break;
66669 + }
66670 + case (FM_VSP_SET_PORT_WINDOW) :
66671 + {
66672 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
66673 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
66674 + err = SetVSPWindow(h_Fm,
66675 + ipcVspSetPortWindow.hardwarePortId,
66676 + ipcVspSetPortWindow.baseStorageProfile,
66677 + ipcVspSetPortWindow.log2NumOfProfiles);
66678 + return err;
66679 + }
66680 + case (FM_SET_CONG_GRP_PFC_PRIO) :
66681 + {
66682 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
66683 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
66684 + err = FmSetCongestionGroupPFCpriority(h_Fm,
66685 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
66686 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
66687 + return err;
66688 + }
66689 +#endif /* (DPAA_VERSION >= 11) */
66690 +
66691 + case (FM_FREE_PORT):
66692 + {
66693 + t_FmInterModulePortFreeParams portParams;
66694 + t_FmIpcPortFreeParams ipcPortParams;
66695 +
66696 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
66697 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
66698 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
66699 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
66700 + FmFreePortParams(h_Fm, &portParams);
66701 + break;
66702 + }
66703 + case (FM_REGISTER_INTR):
66704 + {
66705 + t_FmIpcRegisterIntr ipcRegIntr;
66706 +
66707 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
66708 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
66709 + break;
66710 + }
66711 + case (FM_GET_PARAMS):
66712 + {
66713 + t_FmIpcParams ipcParams;
66714 +
66715 + /* Get clock frequency */
66716 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
66717 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
66718 +
66719 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
66720 +
66721 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
66722 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
66723 + break;
66724 + }
66725 + case (FM_GET_FMAN_CTRL_CODE_REV):
66726 + {
66727 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
66728 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
66729 +
66730 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
66731 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
66732 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
66733 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
66734 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
66735 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
66736 + break;
66737 + }
66738 +
66739 + case (FM_DMA_STAT):
66740 + {
66741 + t_FmDmaStatus dmaStatus;
66742 + t_FmIpcDmaStatus ipcDmaStatus;
66743 +
66744 + FM_GetDmaStatus(h_Fm, &dmaStatus);
66745 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
66746 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
66747 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
66748 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
66749 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
66750 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
66751 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
66752 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
66753 + break;
66754 + }
66755 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
66756 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
66757 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
66758 + break;
66759 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
66760 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
66761 + break;
66762 + case (FM_GET_TIMESTAMP_SCALE):
66763 + {
66764 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
66765 +
66766 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
66767 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
66768 + break;
66769 + }
66770 + case (FM_GET_COUNTER):
66771 + {
66772 + e_FmCounters inCounter;
66773 + uint32_t outCounter;
66774 +
66775 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
66776 + outCounter = FM_GetCounter(h_Fm, inCounter);
66777 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
66778 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
66779 + break;
66780 + }
66781 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
66782 + {
66783 + t_FmIpcFmanEvents ipcFmanEvents;
66784 +
66785 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
66786 + FmSetFmanCtrlIntr(h_Fm,
66787 + ipcFmanEvents.eventRegId,
66788 + ipcFmanEvents.enableEvents);
66789 + break;
66790 + }
66791 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
66792 + {
66793 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
66794 +
66795 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
66796 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
66797 + break;
66798 + }
66799 + case (FM_GET_PHYS_MURAM_BASE):
66800 + {
66801 + t_FmPhysAddr physAddr;
66802 + t_FmIpcPhysAddr ipcPhysAddr;
66803 +
66804 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
66805 + ipcPhysAddr.high = physAddr.high;
66806 + ipcPhysAddr.low = physAddr.low;
66807 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
66808 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
66809 + break;
66810 + }
66811 + case (FM_ENABLE_RAM_ECC):
66812 + {
66813 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
66814 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
66815 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
66816 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
66817 + UNUSED(err);
66818 +#else
66819 + REPORT_ERROR(MINOR, err, NO_MSG);
66820 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
66821 + break;
66822 + }
66823 + case (FM_DISABLE_RAM_ECC):
66824 + {
66825 +
66826 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
66827 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
66828 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
66829 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
66830 + UNUSED(err);
66831 +#else
66832 + REPORT_ERROR(MINOR, err, NO_MSG);
66833 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
66834 + break;
66835 + }
66836 + case (FM_SET_NUM_OF_FMAN_CTRL):
66837 + {
66838 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
66839 +
66840 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
66841 + err = FmSetNumOfRiscsPerPort(h_Fm,
66842 + ipcPortNumOfFmanCtrls.hardwarePortId,
66843 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
66844 + ipcPortNumOfFmanCtrls.orFmanCtrl);
66845 + if (err != E_OK)
66846 + REPORT_ERROR(MINOR, err, NO_MSG);
66847 + break;
66848 + }
66849 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
66850 + case (FM_10G_TX_ECC_WA):
66851 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
66852 + *p_ReplyLength = sizeof(uint32_t);
66853 + break;
66854 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
66855 + default:
66856 + *p_ReplyLength = 0;
66857 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
66858 + }
66859 + return E_OK;
66860 +}
66861 +
66862 +
66863 +/****************************************/
66864 +/* Inter-Module functions */
66865 +/****************************************/
66866 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
66867 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
66868 +{
66869 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66870 + t_Error err = E_OK;
66871 + t_FmIpcMsg msg;
66872 + t_FmIpcReply reply;
66873 + uint32_t replyLength;
66874 + uint8_t rxHardwarePortId, txHardwarePortId;
66875 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66876 +
66877 + if (p_Fm->guestId != NCSW_MASTER_ID)
66878 + {
66879 + memset(&msg, 0, sizeof(msg));
66880 + memset(&reply, 0, sizeof(reply));
66881 + msg.msgId = FM_10G_TX_ECC_WA;
66882 + msg.msgBody[0] = macId;
66883 + replyLength = sizeof(uint32_t);
66884 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66885 + (uint8_t*)&msg,
66886 + sizeof(msg.msgId)+sizeof(macId),
66887 + (uint8_t*)&reply,
66888 + &replyLength,
66889 + NULL,
66890 + NULL)) != E_OK)
66891 + RETURN_ERROR(MINOR, err, NO_MSG);
66892 + if (replyLength != sizeof(uint32_t))
66893 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66894 + return (t_Error)(reply.error);
66895 + }
66896 +
66897 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
66898 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
66899 +
66900 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
66901 + macId,
66902 + p_Fm->p_FmStateStruct->revInfo.majorRev,
66903 + p_Fm->p_FmStateStruct->revInfo.minorRev);
66904 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
66905 + macId,
66906 + p_Fm->p_FmStateStruct->revInfo.majorRev,
66907 + p_Fm->p_FmStateStruct->revInfo.minorRev);
66908 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
66909 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
66910 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
66911 + ("MAC should be initialized prior to Rx and Tx ports!"));
66912 +
66913 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
66914 +}
66915 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
66916 +
66917 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
66918 +{
66919 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66920 +
66921 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
66922 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
66923 +
66924 + return p_Fm->tnumAgingPeriod;
66925 +}
66926 +
66927 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
66928 + uint8_t portNum,
66929 + bool preFetchConfigured)
66930 +{
66931 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66932 +
66933 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66934 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
66935 +
66936 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
66937 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
66938 +
66939 + return E_OK;
66940 +}
66941 +
66942 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
66943 + uint8_t portNum,
66944 + bool *p_PortConfigured,
66945 + bool *p_PreFetchConfigured)
66946 +{
66947 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66948 +
66949 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66950 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
66951 +
66952 + /* If the prefetch wasn't configured yet (not enable or disabled)
66953 + we return the value TRUE as it was already configured */
66954 + if (!p_Fm->portsPreFetchConfigured[portNum])
66955 + {
66956 + *p_PortConfigured = FALSE;
66957 + *p_PreFetchConfigured = FALSE;
66958 + }
66959 + else
66960 + {
66961 + *p_PortConfigured = TRUE;
66962 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
66963 + }
66964 +
66965 + return E_OK;
66966 +}
66967 +
66968 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
66969 + uint32_t congestionGroupId,
66970 + uint8_t priorityBitMap)
66971 +{
66972 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66973 + uint32_t regNum;
66974 +
66975 + ASSERT_COND(h_Fm);
66976 +
66977 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
66978 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66979 + ("Congestion group ID bigger than %d",
66980 + FM_PORT_NUM_OF_CONGESTION_GRPS));
66981 +
66982 + if (p_Fm->guestId == NCSW_MASTER_ID)
66983 + {
66984 + ASSERT_COND(p_Fm->baseAddr);
66985 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
66986 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
66987 + congestionGroupId,
66988 + priorityBitMap,
66989 + regNum);
66990 + }
66991 + else if (p_Fm->h_IpcSessions[0])
66992 + {
66993 + t_Error err;
66994 + t_FmIpcMsg msg;
66995 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
66996 +
66997 + memset(&msg, 0, sizeof(msg));
66998 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
66999 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
67000 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
67001 +
67002 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
67003 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
67004 +
67005 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67006 + (uint8_t*)&msg,
67007 + sizeof(msg.msgId),
67008 + NULL,
67009 + NULL,
67010 + NULL,
67011 + NULL);
67012 + if (err != E_OK)
67013 + RETURN_ERROR(MINOR, err, NO_MSG);
67014 + }
67015 + else
67016 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
67017 +
67018 + return E_OK;
67019 +}
67020 +
67021 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
67022 +{
67023 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67024 +
67025 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67026 +
67027 + if (!p_Fm->baseAddr)
67028 + {
67029 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
67030 + ("No base-addr; probably Guest with IPC!"));
67031 + return 0;
67032 + }
67033 +
67034 + return (p_Fm->baseAddr + FM_MM_PRS);
67035 +}
67036 +
67037 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
67038 +{
67039 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67040 +
67041 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67042 +
67043 + if (!p_Fm->baseAddr)
67044 + {
67045 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
67046 + ("No base-addr; probably Guest with IPC!"));
67047 + return 0;
67048 + }
67049 +
67050 + return (p_Fm->baseAddr + FM_MM_KG);
67051 +}
67052 +
67053 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
67054 +{
67055 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67056 +
67057 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67058 +
67059 + if (!p_Fm->baseAddr)
67060 + {
67061 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
67062 + ("No base-addr; probably Guest with IPC!"));
67063 + return 0;
67064 + }
67065 +
67066 + return (p_Fm->baseAddr + FM_MM_PLCR);
67067 +}
67068 +
67069 +#if (DPAA_VERSION >= 11)
67070 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
67071 +{
67072 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67073 +
67074 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67075 +
67076 + return p_Fm->vspBaseAddr;
67077 +}
67078 +#endif /* (DPAA_VERSION >= 11) */
67079 +
67080 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
67081 +{
67082 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67083 +
67084 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
67085 +
67086 + return (p_Fm->h_FmMuram);
67087 +}
67088 +
67089 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
67090 +{
67091 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67092 +
67093 + if (p_Fm->fmMuramPhysBaseAddr)
67094 + {
67095 + /* General FM driver initialization */
67096 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
67097 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
67098 + return;
67099 + }
67100 +
67101 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67102 +
67103 + if (p_Fm->h_IpcSessions[0])
67104 + {
67105 + t_Error err;
67106 + t_FmIpcMsg msg;
67107 + t_FmIpcReply reply;
67108 + uint32_t replyLength;
67109 + t_FmIpcPhysAddr ipcPhysAddr;
67110 +
67111 + memset(&msg, 0, sizeof(msg));
67112 + memset(&reply, 0, sizeof(reply));
67113 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
67114 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
67115 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67116 + (uint8_t*)&msg,
67117 + sizeof(msg.msgId),
67118 + (uint8_t*)&reply,
67119 + &replyLength,
67120 + NULL,
67121 + NULL);
67122 + if (err != E_OK)
67123 + {
67124 + REPORT_ERROR(MINOR, err, NO_MSG);
67125 + return;
67126 + }
67127 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
67128 + {
67129 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
67130 + return;
67131 + }
67132 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
67133 + p_FmPhysAddr->high = ipcPhysAddr.high;
67134 + p_FmPhysAddr->low = ipcPhysAddr.low;
67135 + }
67136 + else
67137 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67138 + ("running in guest-mode without neither IPC nor mapped register!"));
67139 +}
67140 +
67141 +#if (DPAA_VERSION >= 11)
67142 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
67143 + e_FmPortType portType,
67144 + uint8_t portId,
67145 + uint8_t numOfVSPs)
67146 +{
67147 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67148 + t_Error err = E_OK;
67149 + uint32_t profilesFound, intFlags;
67150 + uint8_t first, i;
67151 + uint8_t log2Num;
67152 + uint8_t swPortIndex=0, hardwarePortId;
67153 +
67154 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67155 +
67156 + if (!numOfVSPs)
67157 + return E_OK;
67158 +
67159 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
67160 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
67161 +
67162 + if (!POWER_OF_2(numOfVSPs))
67163 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
67164 +
67165 + LOG2((uint64_t)numOfVSPs, log2Num);
67166 +
67167 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
67168 + first = 0;
67169 + else
67170 + first = 1<<log2Num;
67171 +
67172 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
67173 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
67174 +
67175 + if (first < p_Fm->partVSPBase)
67176 + while (first < p_Fm->partVSPBase)
67177 + first = first + numOfVSPs;
67178 +
67179 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
67180 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
67181 +
67182 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
67183 + profilesFound = 0;
67184 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
67185 + {
67186 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
67187 + {
67188 + profilesFound++;
67189 + i++;
67190 + if (profilesFound == numOfVSPs)
67191 + break;
67192 + }
67193 + else
67194 + {
67195 + profilesFound = 0;
67196 + /* advance i to the next aligned address */
67197 + first = i = (uint8_t)(first + numOfVSPs);
67198 + }
67199 + }
67200 + if (profilesFound == numOfVSPs)
67201 + for (i = first; i<first + numOfVSPs; i++)
67202 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
67203 + else
67204 + {
67205 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67206 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
67207 + }
67208 +
67209 + hardwarePortId = SwPortIdToHwPortId(portType,
67210 + portId,
67211 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67212 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67213 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67214 +
67215 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
67216 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
67217 +
67218 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
67219 + for (i = first; i < first + numOfVSPs; i++)
67220 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
67221 +
67222 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67223 +
67224 + return err;
67225 +}
67226 +
67227 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
67228 + e_FmPortType portType,
67229 + uint8_t portId)
67230 +{
67231 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67232 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
67233 + uint32_t intFlags;
67234 +
67235 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67236 +
67237 + hardwarePortId = SwPortIdToHwPortId(portType,
67238 + portId,
67239 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67240 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67241 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67242 +
67243 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
67244 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
67245 +
67246 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
67247 + for (i = first; i < first + numOfVSPs; i++)
67248 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
67249 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67250 +
67251 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
67252 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
67253 +
67254 + return E_OK;
67255 +}
67256 +#endif /* (DPAA_VERSION >= 11) */
67257 +
67258 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
67259 +{
67260 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67261 + uint8_t i;
67262 +
67263 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67264 +
67265 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67266 + p_Fm->h_IpcSessions[0])
67267 + {
67268 + t_Error err;
67269 + t_FmIpcMsg msg;
67270 + t_FmIpcReply reply;
67271 + uint32_t replyLength;
67272 +
67273 + memset(&msg, 0, sizeof(msg));
67274 + memset(&reply, 0, sizeof(reply));
67275 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
67276 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67277 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67278 + (uint8_t*)&msg,
67279 + sizeof(msg.msgId),
67280 + (uint8_t*)&reply,
67281 + &replyLength,
67282 + NULL,
67283 + NULL)) != E_OK)
67284 + RETURN_ERROR(MAJOR, err, NO_MSG);
67285 +
67286 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67287 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67288 +
67289 + *p_EventId = *(uint8_t*)(reply.replyBody);
67290 +
67291 + return (t_Error)(reply.error);
67292 + }
67293 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67294 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
67295 + ("running in guest-mode without IPC!"));
67296 +
67297 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67298 + if (!p_Fm->usedEventRegs[i])
67299 + {
67300 + p_Fm->usedEventRegs[i] = TRUE;
67301 + *p_EventId = i;
67302 + break;
67303 + }
67304 +
67305 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
67306 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
67307 +
67308 + return E_OK;
67309 +}
67310 +
67311 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
67312 +{
67313 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67314 +
67315 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
67316 +
67317 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67318 + p_Fm->h_IpcSessions[0])
67319 + {
67320 + t_Error err;
67321 + t_FmIpcMsg msg;
67322 +
67323 + memset(&msg, 0, sizeof(msg));
67324 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
67325 + msg.msgBody[0] = eventId;
67326 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67327 + (uint8_t*)&msg,
67328 + sizeof(msg.msgId)+sizeof(eventId),
67329 + NULL,
67330 + NULL,
67331 + NULL,
67332 + NULL);
67333 + if (err != E_OK)
67334 + REPORT_ERROR(MINOR, err, NO_MSG);
67335 + return;
67336 + }
67337 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67338 + {
67339 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67340 + ("running in guest-mode without IPC!"));
67341 + return;
67342 + }
67343 +
67344 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
67345 +}
67346 +
67347 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
67348 +{
67349 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67350 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67351 +
67352 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67353 + !p_Fm->p_FmFpmRegs &&
67354 + p_Fm->h_IpcSessions[0])
67355 + {
67356 + t_FmIpcFmanEvents fmanCtrl;
67357 + t_Error err;
67358 + t_FmIpcMsg msg;
67359 +
67360 + fmanCtrl.eventRegId = eventRegId;
67361 + fmanCtrl.enableEvents = enableEvents;
67362 + memset(&msg, 0, sizeof(msg));
67363 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
67364 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
67365 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67366 + (uint8_t*)&msg,
67367 + sizeof(msg.msgId)+sizeof(fmanCtrl),
67368 + NULL,
67369 + NULL,
67370 + NULL,
67371 + NULL);
67372 + if (err != E_OK)
67373 + REPORT_ERROR(MINOR, err, NO_MSG);
67374 + return;
67375 + }
67376 + else if (!p_Fm->p_FmFpmRegs)
67377 + {
67378 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67379 + ("Either IPC or 'baseAddress' is required!"));
67380 + return;
67381 + }
67382 +
67383 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
67384 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
67385 +}
67386 +
67387 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
67388 +{
67389 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67390 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67391 +
67392 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67393 + !p_Fm->p_FmFpmRegs &&
67394 + p_Fm->h_IpcSessions[0])
67395 + {
67396 + t_Error err;
67397 + t_FmIpcMsg msg;
67398 + t_FmIpcReply reply;
67399 + uint32_t replyLength, ctrlIntr;
67400 +
67401 + memset(&msg, 0, sizeof(msg));
67402 + memset(&reply, 0, sizeof(reply));
67403 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
67404 + msg.msgBody[0] = eventRegId;
67405 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
67406 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67407 + (uint8_t*)&msg,
67408 + sizeof(msg.msgId)+sizeof(eventRegId),
67409 + (uint8_t*)&reply,
67410 + &replyLength,
67411 + NULL,
67412 + NULL);
67413 + if (err != E_OK)
67414 + {
67415 + REPORT_ERROR(MINOR, err, NO_MSG);
67416 + return 0;
67417 + }
67418 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
67419 + {
67420 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67421 + return 0;
67422 + }
67423 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
67424 + return ctrlIntr;
67425 + }
67426 + else if (!p_Fm->p_FmFpmRegs)
67427 + {
67428 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67429 + ("Either IPC or 'baseAddress' is required!"));
67430 + return 0;
67431 + }
67432 +
67433 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
67434 +}
67435 +
67436 +void FmRegisterIntr(t_Handle h_Fm,
67437 + e_FmEventModules module,
67438 + uint8_t modId,
67439 + e_FmIntrType intrType,
67440 + void (*f_Isr) (t_Handle h_Arg),
67441 + t_Handle h_Arg)
67442 +{
67443 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67444 + int event = 0;
67445 +
67446 + ASSERT_COND(h_Fm);
67447 +
67448 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
67449 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
67450 +
67451 + /* register in local FM structure */
67452 + p_Fm->intrMng[event].f_Isr = f_Isr;
67453 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
67454 +
67455 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67456 + p_Fm->h_IpcSessions[0])
67457 + {
67458 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
67459 + t_Error err;
67460 + t_FmIpcMsg msg;
67461 +
67462 + /* register in Master FM structure */
67463 + fmIpcRegisterIntr.event = (uint32_t)event;
67464 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
67465 + memset(&msg, 0, sizeof(msg));
67466 + msg.msgId = FM_REGISTER_INTR;
67467 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
67468 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67469 + (uint8_t*)&msg,
67470 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
67471 + NULL,
67472 + NULL,
67473 + NULL,
67474 + NULL);
67475 + if (err != E_OK)
67476 + REPORT_ERROR(MINOR, err, NO_MSG);
67477 + }
67478 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67479 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67480 + ("running in guest-mode without IPC!"));
67481 +}
67482 +
67483 +void FmUnregisterIntr(t_Handle h_Fm,
67484 + e_FmEventModules module,
67485 + uint8_t modId,
67486 + e_FmIntrType intrType)
67487 +{
67488 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67489 + int event = 0;
67490 +
67491 + ASSERT_COND(h_Fm);
67492 +
67493 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
67494 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
67495 +
67496 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
67497 + p_Fm->intrMng[event].h_SrcHandle = NULL;
67498 +}
67499 +
67500 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
67501 +{
67502 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67503 +
67504 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
67505 +
67506 + if (p_Fm->guestId != NCSW_MASTER_ID)
67507 + {
67508 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
67509 + return;
67510 + }
67511 +
67512 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
67513 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
67514 +}
67515 +
67516 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
67517 +{
67518 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67519 +
67520 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
67521 +
67522 + if (p_Fm->guestId != NCSW_MASTER_ID)
67523 + {
67524 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
67525 + return;
67526 + }
67527 +
67528 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
67529 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
67530 +}
67531 +
67532 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
67533 +{
67534 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67535 +
67536 + if (p_Fm->h_Pcd)
67537 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
67538 +
67539 + p_Fm->h_Pcd = h_FmPcd;
67540 +}
67541 +
67542 +void FmUnregisterPcd(t_Handle h_Fm)
67543 +{
67544 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67545 +
67546 + if (!p_Fm->h_Pcd)
67547 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
67548 +
67549 + p_Fm->h_Pcd = NULL;
67550 +}
67551 +
67552 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
67553 +{
67554 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67555 +
67556 + return p_Fm->h_Pcd;
67557 +}
67558 +
67559 +uint8_t FmGetId(t_Handle h_Fm)
67560 +{
67561 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67562 +
67563 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
67564 +
67565 + return p_Fm->p_FmStateStruct->fmId;
67566 +}
67567 +
67568 +t_Error FmReset(t_Handle h_Fm)
67569 +{
67570 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67571 +
67572 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67573 +
67574 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
67575 + CORE_MemoryBarrier();
67576 + XX_UDelay(100);
67577 +
67578 + return E_OK;
67579 +}
67580 +
67581 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
67582 + uint8_t hardwarePortId,
67583 + uint8_t numOfFmanCtrls,
67584 + t_FmFmanCtrl orFmanCtrl)
67585 +{
67586 +
67587 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67588 + struct fman_fpm_regs *fpm_rg;
67589 +
67590 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67591 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
67592 +
67593 + fpm_rg = p_Fm->p_FmFpmRegs;
67594 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67595 + !p_Fm->p_FmFpmRegs &&
67596 + p_Fm->h_IpcSessions[0])
67597 + {
67598 + t_Error err;
67599 + t_FmIpcPortNumOfFmanCtrls params;
67600 + t_FmIpcMsg msg;
67601 +
67602 + memset(&msg, 0, sizeof(msg));
67603 + params.hardwarePortId = hardwarePortId;
67604 + params.numOfFmanCtrls = numOfFmanCtrls;
67605 + params.orFmanCtrl = orFmanCtrl;
67606 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
67607 + memcpy(msg.msgBody, &params, sizeof(params));
67608 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67609 + (uint8_t*)&msg,
67610 + sizeof(msg.msgId) +sizeof(params),
67611 + NULL,
67612 + NULL,
67613 + NULL,
67614 + NULL);
67615 + if (err != E_OK)
67616 + RETURN_ERROR(MINOR, err, NO_MSG);
67617 + return E_OK;
67618 + }
67619 + else if (!p_Fm->p_FmFpmRegs)
67620 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
67621 + ("Either IPC or 'baseAddress' is required!"));
67622 +
67623 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
67624 +
67625 + return E_OK;
67626 +}
67627 +
67628 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
67629 +{
67630 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67631 + t_Error err;
67632 + uint32_t intFlags;
67633 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
67634 + struct fman_rg fman_rg;
67635 +
67636 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67637 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67638 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67639 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67640 +
67641 + if (p_Fm->guestId != NCSW_MASTER_ID)
67642 + {
67643 + t_FmIpcPortInInitParams portInParams;
67644 + t_FmIpcPortOutInitParams portOutParams;
67645 + t_FmIpcMsg msg;
67646 + t_FmIpcReply reply;
67647 + uint32_t replyLength;
67648 +
67649 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
67650 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
67651 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
67652 + portInParams.liodnOffset = p_PortParams->liodnOffset;
67653 + portInParams.numOfTasks = p_PortParams->numOfTasks;
67654 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
67655 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
67656 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
67657 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
67658 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
67659 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
67660 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
67661 + portInParams.liodnBase = p_PortParams->liodnBase;
67662 +
67663 + memset(&msg, 0, sizeof(msg));
67664 + memset(&reply, 0, sizeof(reply));
67665 + msg.msgId = FM_GET_SET_PORT_PARAMS;
67666 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
67667 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
67668 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67669 + (uint8_t*)&msg,
67670 + sizeof(msg.msgId) +sizeof(portInParams),
67671 + (uint8_t*)&reply,
67672 + &replyLength,
67673 + NULL,
67674 + NULL)) != E_OK)
67675 + RETURN_ERROR(MINOR, err, NO_MSG);
67676 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
67677 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67678 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
67679 +
67680 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
67681 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
67682 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
67683 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
67684 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
67685 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
67686 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
67687 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
67688 +
67689 + return (t_Error)(reply.error);
67690 + }
67691 +
67692 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67693 +
67694 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
67695 + if (p_PortParams->independentMode)
67696 + {
67697 + /* set port parameters */
67698 + p_Fm->independentMode = p_PortParams->independentMode;
67699 + /* disable dispatch limit */
67700 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
67701 + }
67702 +
67703 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
67704 + {
67705 + if (p_Fm->hcPortInitialized)
67706 + {
67707 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67708 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
67709 + }
67710 + else
67711 + p_Fm->hcPortInitialized = TRUE;
67712 + }
67713 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
67714 +
67715 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
67716 + if (err)
67717 + {
67718 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67719 + RETURN_ERROR(MAJOR, err, NO_MSG);
67720 + }
67721 +
67722 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67723 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67724 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67725 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
67726 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
67727 + /* for transmit & O/H ports */
67728 + {
67729 + uint8_t enqTh;
67730 + uint8_t deqTh;
67731 +
67732 + /* update qmi ENQ/DEQ threshold */
67733 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
67734 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
67735 + /* if enqTh is too big, we reduce it to the max value that is still OK */
67736 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
67737 + {
67738 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
67739 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
67740 + }
67741 +
67742 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
67743 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
67744 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
67745 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
67746 + {
67747 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
67748 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
67749 + }
67750 + }
67751 +
67752 +#ifdef FM_LOW_END_RESTRICTION
67753 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
67754 + {
67755 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
67756 + {
67757 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67758 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
67759 + }
67760 + else
67761 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
67762 + }
67763 +#endif /* FM_LOW_END_RESTRICTION */
67764 +
67765 + err = FmSetSizeOfFifo(p_Fm,
67766 + hardwarePortId,
67767 + &p_PortParams->sizeOfFifo,
67768 + &p_PortParams->extraSizeOfFifo,
67769 + TRUE);
67770 + if (err)
67771 + {
67772 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67773 + RETURN_ERROR(MAJOR, err, NO_MSG);
67774 + }
67775 +
67776 + err = FmSetNumOfOpenDmas(p_Fm,
67777 + hardwarePortId,
67778 + &p_PortParams->numOfOpenDmas,
67779 + &p_PortParams->numOfExtraOpenDmas,
67780 + TRUE);
67781 + if (err)
67782 + {
67783 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67784 + RETURN_ERROR(MAJOR, err, NO_MSG);
67785 + }
67786 +
67787 + fman_set_liodn_per_port(&fman_rg,
67788 + hardwarePortId,
67789 + p_PortParams->liodnBase,
67790 + p_PortParams->liodnOffset);
67791 +
67792 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67793 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
67794 + hardwarePortId,
67795 + p_PortParams->independentMode,
67796 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
67797 +
67798 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
67799 +
67800 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
67801 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
67802 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
67803 + {
67804 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
67805 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
67806 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
67807 + else
67808 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
67809 + }
67810 + else
67811 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
67812 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
67813 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
67814 + {
67815 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
67816 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
67817 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
67818 + else
67819 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
67820 + }
67821 +
67822 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
67823 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67824 +
67825 + return E_OK;
67826 +}
67827 +
67828 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
67829 +{
67830 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67831 + uint32_t intFlags;
67832 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
67833 + uint8_t numOfTasks, numOfDmas, macId;
67834 + uint16_t sizeOfFifo;
67835 + t_Error err;
67836 + t_FmIpcPortFreeParams portParams;
67837 + t_FmIpcMsg msg;
67838 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
67839 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67840 +
67841 + if (p_Fm->guestId != NCSW_MASTER_ID)
67842 + {
67843 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
67844 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
67845 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
67846 + memset(&msg, 0, sizeof(msg));
67847 + msg.msgId = FM_FREE_PORT;
67848 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
67849 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67850 + (uint8_t*)&msg,
67851 + sizeof(msg.msgId)+sizeof(portParams),
67852 + NULL,
67853 + NULL,
67854 + NULL,
67855 + NULL);
67856 + if (err != E_OK)
67857 + REPORT_ERROR(MINOR, err, NO_MSG);
67858 + return;
67859 + }
67860 +
67861 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67862 +
67863 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
67864 +
67865 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
67866 + {
67867 + ASSERT_COND(p_Fm->hcPortInitialized);
67868 + p_Fm->hcPortInitialized = FALSE;
67869 + }
67870 +
67871 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
67872 +
67873 + /* free numOfTasks */
67874 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
67875 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
67876 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
67877 +
67878 + /* free numOfOpenDmas */
67879 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67880 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
67881 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
67882 +
67883 +#ifdef FM_HAS_TOTAL_DMAS
67884 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67885 + {
67886 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
67887 + fman_set_num_of_open_dmas(bmi_rg,
67888 + hardwarePortId,
67889 + 1,
67890 + 0,
67891 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
67892 + }
67893 +#endif /* FM_HAS_TOTAL_DMAS */
67894 +
67895 + /* free sizeOfFifo */
67896 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
67897 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
67898 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
67899 +
67900 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67901 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67902 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67903 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
67904 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
67905 + /* for transmit & O/H ports */
67906 + {
67907 + uint8_t enqTh;
67908 + uint8_t deqTh;
67909 +
67910 + /* update qmi ENQ/DEQ threshold */
67911 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
67912 +
67913 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
67914 + so we can enlarge enqTh */
67915 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
67916 +
67917 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
67918 + so we can reduce deqTh */
67919 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
67920 +
67921 + fman_set_qmi_enq_th(qmi_rg, enqTh);
67922 + fman_set_qmi_deq_th(qmi_rg, deqTh);
67923 + }
67924 +
67925 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
67926 +
67927 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
67928 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
67929 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
67930 + {
67931 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
67932 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
67933 + }
67934 + else
67935 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
67936 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
67937 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
67938 + {
67939 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
67940 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
67941 + }
67942 +
67943 +#ifdef FM_LOW_END_RESTRICTION
67944 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
67945 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
67946 +#endif /* FM_LOW_END_RESTRICTION */
67947 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67948 +}
67949 +
67950 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
67951 +{
67952 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67953 + t_Error err;
67954 + t_FmIpcMsg msg;
67955 + t_FmIpcReply reply;
67956 + uint32_t replyLength;
67957 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67958 +
67959 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67960 + !p_Fm->baseAddr &&
67961 + p_Fm->h_IpcSessions[0])
67962 + {
67963 + memset(&msg, 0, sizeof(msg));
67964 + memset(&reply, 0, sizeof(reply));
67965 + msg.msgId = FM_IS_PORT_STALLED;
67966 + msg.msgBody[0] = hardwarePortId;
67967 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67968 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67969 + (uint8_t*)&msg,
67970 + sizeof(msg.msgId)+sizeof(hardwarePortId),
67971 + (uint8_t*)&reply,
67972 + &replyLength,
67973 + NULL,
67974 + NULL);
67975 + if (err != E_OK)
67976 + RETURN_ERROR(MINOR, err, NO_MSG);
67977 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67978 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67979 +
67980 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
67981 +
67982 + return (t_Error)(reply.error);
67983 + }
67984 + else if (!p_Fm->baseAddr)
67985 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
67986 + ("Either IPC or 'baseAddress' is required!"));
67987 +
67988 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
67989 +
67990 + return E_OK;
67991 +}
67992 +
67993 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
67994 +{
67995 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67996 + t_Error err;
67997 + bool isStalled;
67998 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67999 +
68000 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68001 + !p_Fm->baseAddr &&
68002 + p_Fm->h_IpcSessions[0])
68003 + {
68004 + t_FmIpcMsg msg;
68005 + t_FmIpcReply reply;
68006 + uint32_t replyLength;
68007 +
68008 + memset(&msg, 0, sizeof(msg));
68009 + memset(&reply, 0, sizeof(reply));
68010 + msg.msgId = FM_RESUME_STALLED_PORT;
68011 + msg.msgBody[0] = hardwarePortId;
68012 + replyLength = sizeof(uint32_t);
68013 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68014 + (uint8_t*)&msg,
68015 + sizeof(msg.msgId) + sizeof(hardwarePortId),
68016 + (uint8_t*)&reply,
68017 + &replyLength,
68018 + NULL,
68019 + NULL);
68020 + if (err != E_OK)
68021 + RETURN_ERROR(MINOR, err, NO_MSG);
68022 + if (replyLength != sizeof(uint32_t))
68023 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68024 + return (t_Error)(reply.error);
68025 + }
68026 + else if (!p_Fm->baseAddr)
68027 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68028 + ("Either IPC or 'baseAddress' is required!"));
68029 +
68030 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68031 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
68032 +
68033 + /* Get port status */
68034 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
68035 + if (err)
68036 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
68037 + if (!isStalled)
68038 + return E_OK;
68039 +
68040 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
68041 +
68042 + return E_OK;
68043 +}
68044 +
68045 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
68046 +{
68047 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68048 + t_Error err;
68049 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
68050 +
68051 +#if (DPAA_VERSION >= 11)
68052 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68053 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68054 + ("FMan MAC reset!"));
68055 +#endif /*(DPAA_VERSION >= 11)*/
68056 +
68057 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68058 + !p_Fm->baseAddr &&
68059 + p_Fm->h_IpcSessions[0])
68060 + {
68061 + t_FmIpcMacParams macParams;
68062 + t_FmIpcMsg msg;
68063 + t_FmIpcReply reply;
68064 + uint32_t replyLength;
68065 +
68066 + memset(&msg, 0, sizeof(msg));
68067 + memset(&reply, 0, sizeof(reply));
68068 + macParams.id = macId;
68069 + macParams.enumType = (uint32_t)type;
68070 + msg.msgId = FM_RESET_MAC;
68071 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
68072 + replyLength = sizeof(uint32_t);
68073 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68074 + (uint8_t*)&msg,
68075 + sizeof(msg.msgId)+sizeof(macParams),
68076 + (uint8_t*)&reply,
68077 + &replyLength,
68078 + NULL,
68079 + NULL);
68080 + if (err != E_OK)
68081 + RETURN_ERROR(MINOR, err, NO_MSG);
68082 + if (replyLength != sizeof(uint32_t))
68083 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68084 + return (t_Error)(reply.error);
68085 + }
68086 + else if (!p_Fm->baseAddr)
68087 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68088 + ("Either IPC or 'baseAddress' is required!"));
68089 +
68090 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
68091 +
68092 + if (err == -EBUSY)
68093 + return ERROR_CODE(E_TIMEOUT);
68094 + else if (err)
68095 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
68096 +
68097 + return E_OK;
68098 +}
68099 +
68100 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
68101 +{
68102 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68103 +
68104 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68105 + p_Fm->h_IpcSessions[0])
68106 + {
68107 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
68108 + t_Error err;
68109 + t_FmIpcMsg msg;
68110 +
68111 + memset(&msg, 0, sizeof(msg));
68112 + macMaxFrameLengthParams.macParams.id = macId;
68113 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
68114 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
68115 + msg.msgId = FM_SET_MAC_MAX_FRAME;
68116 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
68117 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68118 + (uint8_t*)&msg,
68119 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
68120 + NULL,
68121 + NULL,
68122 + NULL,
68123 + NULL);
68124 + if (err != E_OK)
68125 + RETURN_ERROR(MINOR, err, NO_MSG);
68126 + return E_OK;
68127 + }
68128 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68129 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68130 + ("running in guest-mode without IPC!"));
68131 +
68132 + /* if port is already initialized, check that MaxFrameLength is smaller
68133 + * or equal to the port's max */
68134 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
68135 + if (type == e_FM_MAC_10G)
68136 + {
68137 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
68138 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
68139 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
68140 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
68141 + else
68142 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
68143 +
68144 + }
68145 + else
68146 +#else
68147 + UNUSED(type);
68148 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
68149 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
68150 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
68151 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
68152 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
68153 + else
68154 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
68155 +
68156 + return E_OK;
68157 +}
68158 +
68159 +uint16_t FmGetClockFreq(t_Handle h_Fm)
68160 +{
68161 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68162 +
68163 + /* for multicore environment: this depends on the
68164 + * fact that fmClkFreq was properly initialized at "init". */
68165 + return p_Fm->p_FmStateStruct->fmClkFreq;
68166 +}
68167 +
68168 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
68169 +{
68170 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68171 +
68172 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
68173 +}
68174 +
68175 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
68176 +{
68177 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68178 +
68179 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68180 + !p_Fm->baseAddr &&
68181 + p_Fm->h_IpcSessions[0])
68182 + {
68183 + t_Error err;
68184 + t_FmIpcMsg msg;
68185 + t_FmIpcReply reply;
68186 + uint32_t replyLength, timeStamp;
68187 +
68188 + memset(&msg, 0, sizeof(msg));
68189 + memset(&reply, 0, sizeof(reply));
68190 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
68191 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
68192 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68193 + (uint8_t*)&msg,
68194 + sizeof(msg.msgId),
68195 + (uint8_t*)&reply,
68196 + &replyLength,
68197 + NULL,
68198 + NULL)) != E_OK)
68199 + {
68200 + REPORT_ERROR(MAJOR, err, NO_MSG);
68201 + return 0;
68202 + }
68203 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
68204 + {
68205 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68206 + return 0;
68207 + }
68208 +
68209 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
68210 + return timeStamp;
68211 + }
68212 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68213 + p_Fm->baseAddr)
68214 + {
68215 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
68216 + {
68217 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
68218 + return 0;
68219 + }
68220 + }
68221 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68222 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
68223 +
68224 + return p_Fm->p_FmStateStruct->count1MicroBit;
68225 +}
68226 +
68227 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
68228 +{
68229 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68230 +
68231 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68232 +
68233 + p_Fm->p_FmStateStruct->ramsEccOwners++;
68234 + p_Fm->p_FmStateStruct->internalCall = TRUE;
68235 +
68236 + return FM_EnableRamsEcc(p_Fm);
68237 +}
68238 +
68239 +t_Error FmDisableRamsEcc(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 +
68245 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
68246 + p_Fm->p_FmStateStruct->ramsEccOwners--;
68247 +
68248 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
68249 + {
68250 + p_Fm->p_FmStateStruct->internalCall = TRUE;
68251 + return FM_DisableRamsEcc(p_Fm);
68252 + }
68253 +
68254 + return E_OK;
68255 +}
68256 +
68257 +uint8_t FmGetGuestId(t_Handle h_Fm)
68258 +{
68259 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68260 +
68261 + return p_Fm->guestId;
68262 +}
68263 +
68264 +bool FmIsMaster(t_Handle h_Fm)
68265 +{
68266 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68267 +
68268 + return (p_Fm->guestId == NCSW_MASTER_ID);
68269 +}
68270 +
68271 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
68272 + uint8_t hardwarePortId,
68273 + uint32_t *p_SizeOfFifo,
68274 + uint32_t *p_ExtraSizeOfFifo,
68275 + bool initialConfig)
68276 +{
68277 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68278 + t_FmIpcPortRsrcParams rsrcParams;
68279 + t_Error err;
68280 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68281 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
68282 + uint16_t currentVal = 0, currentExtraVal = 0;
68283 +
68284 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68285 + !p_Fm->baseAddr &&
68286 + p_Fm->h_IpcSessions[0])
68287 + {
68288 + t_FmIpcMsg msg;
68289 + t_FmIpcReply reply;
68290 + uint32_t replyLength;
68291 +
68292 + rsrcParams.hardwarePortId = hardwarePortId;
68293 + rsrcParams.val = sizeOfFifo;
68294 + rsrcParams.extra = extraSizeOfFifo;
68295 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
68296 +
68297 + memset(&msg, 0, sizeof(msg));
68298 + memset(&reply, 0, sizeof(reply));
68299 + msg.msgId = FM_SET_SIZE_OF_FIFO;
68300 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
68301 + replyLength = sizeof(uint32_t);
68302 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68303 + (uint8_t*)&msg,
68304 + sizeof(msg.msgId) + sizeof(rsrcParams),
68305 + (uint8_t*)&reply,
68306 + &replyLength,
68307 + NULL,
68308 + NULL)) != E_OK)
68309 + RETURN_ERROR(MINOR, err, NO_MSG);
68310 + if (replyLength != sizeof(uint32_t))
68311 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68312 + return (t_Error)(reply.error);
68313 + }
68314 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68315 + p_Fm->baseAddr)
68316 + {
68317 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
68318 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
68319 + }
68320 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68321 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
68322 + ("running in guest-mode without neither IPC nor mapped register!"));
68323 +
68324 + if (!initialConfig)
68325 + {
68326 + /* !initialConfig - runtime change of existing value.
68327 + * - read the current FIFO and extra FIFO size */
68328 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
68329 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
68330 + }
68331 +
68332 + if (extraSizeOfFifo > currentExtraVal)
68333 + {
68334 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
68335 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
68336 + * must be initialized to 1 buffer per port
68337 + */
68338 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
68339 +
68340 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
68341 + }
68342 +
68343 + /* check that there are enough uncommitted fifo size */
68344 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
68345 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
68346 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
68347 + ("Port request fifo size + accumulated size > total FIFO size:"));
68348 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
68349 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
68350 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
68351 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
68352 + p_Fm->p_FmStateStruct->totalFifoSize));
68353 + }
68354 + else
68355 + {
68356 + /* update accumulated */
68357 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
68358 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
68359 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
68360 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
68361 + }
68362 +
68363 + return E_OK;
68364 +}
68365 +
68366 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
68367 + uint8_t hardwarePortId,
68368 + uint8_t *p_NumOfTasks,
68369 + uint8_t *p_NumOfExtraTasks,
68370 + bool initialConfig)
68371 +{
68372 + t_Fm *p_Fm = (t_Fm *)h_Fm;
68373 + t_Error err;
68374 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68375 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
68376 +
68377 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68378 +
68379 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68380 + !p_Fm->baseAddr &&
68381 + p_Fm->h_IpcSessions[0])
68382 + {
68383 + t_FmIpcPortRsrcParams rsrcParams;
68384 + t_FmIpcMsg msg;
68385 + t_FmIpcReply reply;
68386 + uint32_t replyLength;
68387 +
68388 + rsrcParams.hardwarePortId = hardwarePortId;
68389 + rsrcParams.val = numOfTasks;
68390 + rsrcParams.extra = numOfExtraTasks;
68391 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
68392 +
68393 + memset(&msg, 0, sizeof(msg));
68394 + memset(&reply, 0, sizeof(reply));
68395 + msg.msgId = FM_SET_NUM_OF_TASKS;
68396 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
68397 + replyLength = sizeof(uint32_t);
68398 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68399 + (uint8_t*)&msg,
68400 + sizeof(msg.msgId) + sizeof(rsrcParams),
68401 + (uint8_t*)&reply,
68402 + &replyLength,
68403 + NULL,
68404 + NULL)) != E_OK)
68405 + RETURN_ERROR(MINOR, err, NO_MSG);
68406 + if (replyLength != sizeof(uint32_t))
68407 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68408 + return (t_Error)(reply.error);
68409 + }
68410 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68411 + p_Fm->baseAddr)
68412 + {
68413 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
68414 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
68415 + }
68416 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68417 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
68418 + ("running in guest-mode without neither IPC nor mapped register!"));
68419 +
68420 + if (!initialConfig)
68421 + {
68422 + /* !initialConfig - runtime change of existing value.
68423 + * - read the current number of tasks */
68424 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
68425 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
68426 + }
68427 +
68428 + if (numOfExtraTasks > currentExtraVal)
68429 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
68430 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
68431 +
68432 + /* check that there are enough uncommitted tasks */
68433 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
68434 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
68435 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
68436 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
68437 + p_Fm->p_FmStateStruct->fmId));
68438 + else
68439 + {
68440 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
68441 + /* update accumulated */
68442 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
68443 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
68444 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
68445 + }
68446 +
68447 + return E_OK;
68448 +}
68449 +
68450 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
68451 + uint8_t hardwarePortId,
68452 + uint8_t *p_NumOfOpenDmas,
68453 + uint8_t *p_NumOfExtraOpenDmas,
68454 + bool initialConfig)
68455 +
68456 +{
68457 + t_Fm *p_Fm = (t_Fm *)h_Fm;
68458 + t_Error err;
68459 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68460 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
68461 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
68462 +
68463 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68464 +
68465 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68466 + !p_Fm->baseAddr &&
68467 + p_Fm->h_IpcSessions[0])
68468 + {
68469 + t_FmIpcPortRsrcParams rsrcParams;
68470 + t_FmIpcMsg msg;
68471 + t_FmIpcReply reply;
68472 + uint32_t replyLength;
68473 +
68474 + rsrcParams.hardwarePortId = hardwarePortId;
68475 + rsrcParams.val = numOfOpenDmas;
68476 + rsrcParams.extra = numOfExtraOpenDmas;
68477 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
68478 +
68479 + memset(&msg, 0, sizeof(msg));
68480 + memset(&reply, 0, sizeof(reply));
68481 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
68482 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
68483 + replyLength = sizeof(uint32_t);
68484 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68485 + (uint8_t*)&msg,
68486 + sizeof(msg.msgId) + sizeof(rsrcParams),
68487 + (uint8_t*)&reply,
68488 + &replyLength,
68489 + NULL,
68490 + NULL)) != E_OK)
68491 + RETURN_ERROR(MINOR, err, NO_MSG);
68492 + if (replyLength != sizeof(uint32_t))
68493 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68494 + return (t_Error)(reply.error);
68495 + }
68496 +#ifdef FM_HAS_TOTAL_DMAS
68497 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68498 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
68499 +#else
68500 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68501 + p_Fm->baseAddr &&
68502 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
68503 + {
68504 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
68505 +
68506 + if (!numOfOpenDmas)
68507 + {
68508 + /* first config without explic it value: Do Nothing - reset value shouldn't be
68509 + changed, read register for port save */
68510 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68511 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
68512 + }
68513 + else
68514 + /* whether it is the first time with explicit value, or runtime "set" - write register */
68515 + fman_set_num_of_open_dmas(bmi_rg,
68516 + hardwarePortId,
68517 + numOfOpenDmas,
68518 + numOfExtraOpenDmas,
68519 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
68520 + }
68521 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68522 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
68523 + ("running in guest-mode without neither IPC nor mapped register!"));
68524 +#endif /* FM_HAS_TOTAL_DMAS */
68525 +
68526 + if (!initialConfig)
68527 + {
68528 + /* !initialConfig - runtime change of existing value.
68529 + * - read the current number of open Dma's */
68530 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
68531 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68532 + }
68533 +
68534 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
68535 + /* it's illegal to be in a state where this is not the first set and no value is specified */
68536 + ASSERT_COND(initialConfig || numOfOpenDmas);
68537 + if (!numOfOpenDmas)
68538 + {
68539 + /* !numOfOpenDmas - first configuration according to values in regs.
68540 + * - read the current number of open Dma's */
68541 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
68542 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68543 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
68544 + * reset values will be used and we just save these values for resource management */
68545 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
68546 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
68547 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
68548 + *p_NumOfOpenDmas = currentVal;
68549 + *p_NumOfExtraOpenDmas = currentExtraVal;
68550 + return E_OK;
68551 + }
68552 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
68553 +
68554 + if (numOfExtraOpenDmas > currentExtraVal)
68555 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
68556 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
68557 +
68558 +#ifdef FM_HAS_TOTAL_DMAS
68559 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
68560 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
68561 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
68562 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
68563 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
68564 + p_Fm->p_FmStateStruct->fmId));
68565 +#else
68566 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
68567 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
68568 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
68569 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
68570 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
68571 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
68572 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
68573 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
68574 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
68575 +#endif /* FM_HAS_TOTAL_DMAS */
68576 + else
68577 + {
68578 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
68579 + /* update acummulated */
68580 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
68581 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
68582 +
68583 +#ifdef FM_HAS_TOTAL_DMAS
68584 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
68585 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
68586 +#endif /* FM_HAS_TOTAL_DMAS */
68587 + fman_set_num_of_open_dmas(bmi_rg,
68588 + hardwarePortId,
68589 + numOfOpenDmas,
68590 + numOfExtraOpenDmas,
68591 + totalNumDmas);
68592 + }
68593 +
68594 + return E_OK;
68595 +}
68596 +
68597 +#if (DPAA_VERSION >= 11)
68598 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
68599 + e_FmPortType portType,
68600 + uint8_t portId,
68601 + uint16_t relativeProfile)
68602 +{
68603 + t_Fm *p_Fm;
68604 + t_FmSp *p_FmPcdSp;
68605 + uint8_t swPortIndex=0, hardwarePortId;
68606 +
68607 + ASSERT_COND(h_Fm);
68608 + p_Fm = (t_Fm*)h_Fm;
68609 +
68610 + hardwarePortId = SwPortIdToHwPortId(portType,
68611 + portId,
68612 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68613 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68614 + ASSERT_COND(hardwarePortId);
68615 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
68616 +
68617 + p_FmPcdSp = p_Fm->p_FmSp;
68618 + ASSERT_COND(p_FmPcdSp);
68619 +
68620 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
68621 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
68622 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
68623 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
68624 +
68625 + return E_OK;
68626 +}
68627 +
68628 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
68629 + e_FmPortType portType,
68630 + uint8_t portId,
68631 + uint16_t relativeProfile,
68632 + uint16_t *p_AbsoluteId)
68633 +{
68634 + t_Fm *p_Fm;
68635 + t_FmSp *p_FmPcdSp;
68636 + uint8_t swPortIndex=0, hardwarePortId;
68637 + t_Error err;
68638 +
68639 + ASSERT_COND(h_Fm);
68640 + p_Fm = (t_Fm*)h_Fm;
68641 +
68642 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
68643 + if (err != E_OK)
68644 + return err;
68645 +
68646 + hardwarePortId = SwPortIdToHwPortId(portType,
68647 + portId,
68648 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68649 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68650 + ASSERT_COND(hardwarePortId);
68651 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
68652 +
68653 + p_FmPcdSp = p_Fm->p_FmSp;
68654 + ASSERT_COND(p_FmPcdSp);
68655 +
68656 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
68657 +
68658 + return E_OK;
68659 +}
68660 +#endif /* (DPAA_VERSION >= 11) */
68661 +
68662 +static t_Error InitFmDma(t_Fm *p_Fm)
68663 +{
68664 + t_Error err;
68665 +
68666 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
68667 + if (err != E_OK)
68668 + return err;
68669 +
68670 + /* Allocate MURAM for CAM */
68671 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
68672 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
68673 + DMA_CAM_ALIGN));
68674 + if (!p_Fm->camBaseAddr)
68675 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
68676 +
68677 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
68678 + 0,
68679 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
68680 +
68681 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
68682 + {
68683 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
68684 +
68685 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
68686 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
68687 + 64));
68688 + if (!p_Fm->camBaseAddr)
68689 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
68690 +
68691 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
68692 + 0,
68693 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
68694 +
68695 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
68696 + {
68697 + case (8):
68698 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
68699 + break;
68700 + case (16):
68701 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
68702 + break;
68703 + case (24):
68704 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
68705 + break;
68706 + case (32):
68707 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
68708 + break;
68709 + default:
68710 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
68711 + }
68712 + }
68713 +
68714 + p_Fm->p_FmDriverParam->cam_base_addr =
68715 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
68716 +
68717 + return E_OK;
68718 +}
68719 +
68720 +static t_Error InitFmFpm(t_Fm *p_Fm)
68721 +{
68722 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
68723 +}
68724 +
68725 +static t_Error InitFmBmi(t_Fm *p_Fm)
68726 +{
68727 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
68728 +}
68729 +
68730 +static t_Error InitFmQmi(t_Fm *p_Fm)
68731 +{
68732 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
68733 +}
68734 +
68735 +static t_Error InitGuestMode(t_Fm *p_Fm)
68736 +{
68737 + t_Error err = E_OK;
68738 + int i;
68739 + t_FmIpcMsg msg;
68740 + t_FmIpcReply reply;
68741 + uint32_t replyLength;
68742 +
68743 + ASSERT_COND(p_Fm);
68744 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
68745 +
68746 + /* build the FM guest partition IPC address */
68747 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
68748 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
68749 +
68750 + /* build the FM master partition IPC address */
68751 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
68752 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
68753 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
68754 +
68755 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
68756 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
68757 +
68758 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
68759 + if (p_Fm->h_IpcSessions[0])
68760 + {
68761 + uint8_t isMasterAlive;
68762 + t_FmIpcParams ipcParams;
68763 +
68764 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
68765 + if (err)
68766 + RETURN_ERROR(MAJOR, err, NO_MSG);
68767 +
68768 + memset(&msg, 0, sizeof(msg));
68769 + memset(&reply, 0, sizeof(reply));
68770 + msg.msgId = FM_MASTER_IS_ALIVE;
68771 + msg.msgBody[0] = p_Fm->guestId;
68772 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
68773 + do
68774 + {
68775 + blockingFlag = TRUE;
68776 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68777 + (uint8_t*)&msg,
68778 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
68779 + (uint8_t*)&reply,
68780 + &replyLength,
68781 + IpcMsgCompletionCB,
68782 + p_Fm)) != E_OK)
68783 + REPORT_ERROR(MINOR, err, NO_MSG);
68784 + while (blockingFlag) ;
68785 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
68786 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68787 + isMasterAlive = *(uint8_t*)(reply.replyBody);
68788 + } while (!isMasterAlive);
68789 +
68790 + /* read FM parameters and save */
68791 + memset(&msg, 0, sizeof(msg));
68792 + memset(&reply, 0, sizeof(reply));
68793 + msg.msgId = FM_GET_PARAMS;
68794 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
68795 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68796 + (uint8_t*)&msg,
68797 + sizeof(msg.msgId),
68798 + (uint8_t*)&reply,
68799 + &replyLength,
68800 + NULL,
68801 + NULL)) != E_OK)
68802 + RETURN_ERROR(MAJOR, err, NO_MSG);
68803 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
68804 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68805 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
68806 +
68807 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
68808 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
68809 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
68810 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
68811 + }
68812 + else
68813 + {
68814 + DBG(WARNING, ("FM Guest mode - without IPC"));
68815 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
68816 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
68817 + if (p_Fm->baseAddr)
68818 + {
68819 + fman_get_revision(p_Fm->p_FmFpmRegs,
68820 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
68821 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
68822 +
68823 + }
68824 + }
68825 +
68826 +#if (DPAA_VERSION >= 11)
68827 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68828 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
68829 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
68830 +#endif /* (DPAA_VERSION >= 11) */
68831 +
68832 + /* General FM driver initialization */
68833 + if (p_Fm->baseAddr)
68834 + p_Fm->fmMuramPhysBaseAddr =
68835 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
68836 +
68837 + XX_Free(p_Fm->p_FmDriverParam);
68838 + p_Fm->p_FmDriverParam = NULL;
68839 +
68840 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
68841 + (p_Fm->h_IpcSessions[0]))
68842 + {
68843 + FM_DisableRamsEcc(p_Fm);
68844 + FmMuramClear(p_Fm->h_FmMuram);
68845 + FM_EnableRamsEcc(p_Fm);
68846 + }
68847 +
68848 + return E_OK;
68849 +}
68850 +
68851 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
68852 +{
68853 + switch (exception) {
68854 + case e_FM_EX_DMA_BUS_ERROR:
68855 + return E_FMAN_EX_DMA_BUS_ERROR;
68856 + case e_FM_EX_DMA_READ_ECC:
68857 + return E_FMAN_EX_DMA_READ_ECC;
68858 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
68859 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
68860 + case e_FM_EX_DMA_FM_WRITE_ECC:
68861 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
68862 + case e_FM_EX_FPM_STALL_ON_TASKS:
68863 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
68864 + case e_FM_EX_FPM_SINGLE_ECC:
68865 + return E_FMAN_EX_FPM_SINGLE_ECC;
68866 + case e_FM_EX_FPM_DOUBLE_ECC:
68867 + return E_FMAN_EX_FPM_DOUBLE_ECC;
68868 + case e_FM_EX_QMI_SINGLE_ECC:
68869 + return E_FMAN_EX_QMI_SINGLE_ECC;
68870 + case e_FM_EX_QMI_DOUBLE_ECC:
68871 + return E_FMAN_EX_QMI_DOUBLE_ECC;
68872 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
68873 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
68874 + case e_FM_EX_BMI_LIST_RAM_ECC:
68875 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
68876 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
68877 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
68878 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
68879 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
68880 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
68881 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
68882 + case e_FM_EX_IRAM_ECC:
68883 + return E_FMAN_EX_IRAM_ECC;
68884 + case e_FM_EX_MURAM_ECC:
68885 + return E_FMAN_EX_MURAM_ECC;
68886 + default:
68887 + return E_FMAN_EX_DMA_BUS_ERROR;
68888 + }
68889 +}
68890 +
68891 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
68892 +{
68893 + switch (type)
68894 + {
68895 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
68896 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
68897 + CHECK_PORT_ID_OH_PORTS(relativePortId);
68898 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
68899 + case (e_FM_PORT_TYPE_RX):
68900 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
68901 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
68902 + case (e_FM_PORT_TYPE_RX_10G):
68903 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
68904 + * This is the reason why the 1G port offset is used.
68905 + */
68906 + if (majorRev == 6 && minorRev == 4)
68907 + {
68908 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
68909 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
68910 + }
68911 + else
68912 + {
68913 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
68914 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
68915 + }
68916 + case (e_FM_PORT_TYPE_TX):
68917 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
68918 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
68919 + case (e_FM_PORT_TYPE_TX_10G):
68920 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
68921 + * This is the reason why the 1G port offset is used.
68922 + */
68923 + if (majorRev == 6 && minorRev == 4)
68924 + {
68925 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
68926 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
68927 + }
68928 + else
68929 + {
68930 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
68931 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
68932 + }
68933 + default:
68934 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
68935 + return 0;
68936 + }
68937 +}
68938 +
68939 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
68940 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
68941 +{
68942 + t_Fm *p_Fm = (t_Fm *)h_Fm;
68943 +
68944 + DECLARE_DUMP;
68945 +
68946 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68947 +
68948 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68949 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
68950 + p_Fm->baseAddr), E_INVALID_OPERATION);
68951 +
68952 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
68953 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
68954 +
68955 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
68956 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
68957 +
68958 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
68959 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
68960 +
68961 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
68962 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
68963 +
68964 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
68965 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
68966 +
68967 + return E_OK;
68968 +}
68969 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
68970 +
68971 +
68972 +/*****************************************************************************/
68973 +/* API Init unit functions */
68974 +/*****************************************************************************/
68975 +t_Handle FM_Config(t_FmParams *p_FmParam)
68976 +{
68977 + t_Fm *p_Fm;
68978 + uint8_t i;
68979 + uintptr_t baseAddr;
68980 +
68981 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
68982 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
68983 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
68984 + E_INVALID_VALUE, NULL);
68985 +
68986 + baseAddr = p_FmParam->baseAddr;
68987 +
68988 + /* Allocate FM structure */
68989 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
68990 + if (!p_Fm)
68991 + {
68992 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
68993 + return NULL;
68994 + }
68995 + memset(p_Fm, 0, sizeof(t_Fm));
68996 +
68997 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
68998 + if (!p_Fm->p_FmStateStruct)
68999 + {
69000 + XX_Free(p_Fm);
69001 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
69002 + return NULL;
69003 + }
69004 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
69005 +
69006 + /* Initialize FM parameters which will be kept by the driver */
69007 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
69008 + p_Fm->guestId = p_FmParam->guestId;
69009 +
69010 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
69011 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
69012 +
69013 + /* Allocate the FM driver's parameters structure */
69014 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
69015 + if (!p_Fm->p_FmDriverParam)
69016 + {
69017 + XX_Free(p_Fm->p_FmStateStruct);
69018 + XX_Free(p_Fm);
69019 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
69020 + return NULL;
69021 + }
69022 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
69023 +
69024 +#if (DPAA_VERSION >= 11)
69025 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
69026 + if (!p_Fm->p_FmSp)
69027 + {
69028 + XX_Free(p_Fm->p_FmDriverParam);
69029 + XX_Free(p_Fm->p_FmStateStruct);
69030 + XX_Free(p_Fm);
69031 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
69032 + return NULL;
69033 + }
69034 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
69035 +
69036 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
69037 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
69038 +#endif /* (DPAA_VERSION >= 11) */
69039 +
69040 + /* Initialize FM parameters which will be kept by the driver */
69041 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
69042 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
69043 + p_Fm->h_App = p_FmParam->h_App;
69044 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
69045 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
69046 + p_Fm->f_Exception = p_FmParam->f_Exception;
69047 + p_Fm->f_BusError = p_FmParam->f_BusError;
69048 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
69049 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
69050 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
69051 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
69052 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
69053 + p_Fm->baseAddr = baseAddr;
69054 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
69055 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
69056 + p_Fm->hcPortInitialized = FALSE;
69057 + p_Fm->independentMode = FALSE;
69058 +
69059 + p_Fm->h_Spinlock = XX_InitSpinlock();
69060 + if (!p_Fm->h_Spinlock)
69061 + {
69062 + XX_Free(p_Fm->p_FmDriverParam);
69063 + XX_Free(p_Fm->p_FmStateStruct);
69064 + XX_Free(p_Fm);
69065 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
69066 + return NULL;
69067 + }
69068 +
69069 +#if (DPAA_VERSION >= 11)
69070 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
69071 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
69072 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
69073 +#endif /* (DPAA_VERSION >= 11) */
69074 +
69075 + fman_defconfig(p_Fm->p_FmDriverParam,
69076 + !!(p_Fm->guestId == NCSW_MASTER_ID));
69077 +/* overide macros dependent parameters */
69078 +#ifdef FM_PEDANTIC_DMA
69079 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
69080 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
69081 +#endif /* FM_PEDANTIC_DMA */
69082 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
69083 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
69084 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
69085 +
69086 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
69087 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
69088 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
69089 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
69090 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
69091 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
69092 + p_Fm->firmware.size = p_FmParam->firmware.size;
69093 + if (p_Fm->firmware.size)
69094 + {
69095 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
69096 + if (!p_Fm->firmware.p_Code)
69097 + {
69098 + XX_FreeSpinlock(p_Fm->h_Spinlock);
69099 + XX_Free(p_Fm->p_FmStateStruct);
69100 + XX_Free(p_Fm->p_FmDriverParam);
69101 + XX_Free(p_Fm);
69102 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
69103 + return NULL;
69104 + }
69105 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
69106 + }
69107 +
69108 + if (p_Fm->guestId != NCSW_MASTER_ID)
69109 + return p_Fm;
69110 +
69111 + /* read revision */
69112 + /* Chip dependent, will be configured in Init */
69113 + fman_get_revision(p_Fm->p_FmFpmRegs,
69114 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
69115 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
69116 +
69117 +#ifdef FM_AID_MODE_NO_TNUM_SW005
69118 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69119 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
69120 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
69121 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
69122 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
69123 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
69124 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
69125 +
69126 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
69127 + p_Fm->p_FmStateStruct->totalNumOfTasks =
69128 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
69129 + p_Fm->p_FmStateStruct->revInfo.minorRev);
69130 +
69131 +#ifdef FM_HAS_TOTAL_DMAS
69132 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
69133 +#endif /* FM_HAS_TOTAL_DMAS */
69134 +#if (DPAA_VERSION < 11)
69135 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
69136 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
69137 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
69138 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
69139 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
69140 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
69141 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
69142 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
69143 +#endif /* (DPAA_VERSION < 11) */
69144 +#ifdef FM_NO_TNUM_AGING
69145 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
69146 +#endif
69147 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
69148 +
69149 + return p_Fm;
69150 +}
69151 +
69152 +/**************************************************************************//**
69153 + @Function FM_Init
69154 +
69155 + @Description Initializes the FM module
69156 +
69157 + @Param[in] h_Fm - FM module descriptor
69158 +
69159 + @Return E_OK on success; Error code otherwise.
69160 +*//***************************************************************************/
69161 +t_Error FM_Init(t_Handle h_Fm)
69162 +{
69163 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69164 + struct fman_cfg *p_FmDriverParam = NULL;
69165 + t_Error err = E_OK;
69166 + int i;
69167 + t_FmRevisionInfo revInfo;
69168 + struct fman_rg fman_rg;
69169 +
69170 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69171 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69172 +
69173 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69174 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69175 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69176 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69177 +
69178 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
69179 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
69180 +
69181 + if (p_Fm->guestId != NCSW_MASTER_ID)
69182 + return InitGuestMode(p_Fm);
69183 +
69184 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
69185 + * according to chip. otherwise, we use user's configuration.
69186 + */
69187 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
69188 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
69189 + p_Fm->p_FmStateStruct->revInfo.minorRev);
69190 +
69191 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
69192 +
69193 + p_FmDriverParam = p_Fm->p_FmDriverParam;
69194 +
69195 + FM_GetRevision(p_Fm, &revInfo);
69196 +
69197 + /* clear revision-dependent non existing exception */
69198 +#ifdef FM_NO_DISPATCH_RAM_ECC
69199 + if ((revInfo.majorRev != 4) &&
69200 + (revInfo.majorRev < 6))
69201 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
69202 +#endif /* FM_NO_DISPATCH_RAM_ECC */
69203 +
69204 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
69205 + if (revInfo.majorRev == 4)
69206 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
69207 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
69208 +
69209 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
69210 + if (revInfo.majorRev >= 6)
69211 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
69212 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
69213 +
69214 + FmMuramClear(p_Fm->h_FmMuram);
69215 +
69216 + /* clear CPG */
69217 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
69218 +
69219 + /* add to the default exceptions the user's definitions */
69220 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
69221 +
69222 + /* Reset the FM if required */
69223 + if (p_Fm->resetOnInit)
69224 + {
69225 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
69226 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
69227 + RETURN_ERROR(MAJOR, err, NO_MSG);
69228 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69229 +
69230 + if (p_Fm->f_ResetOnInitOverride)
69231 + {
69232 + /* Perform user specific FMan reset */
69233 + p_Fm->f_ResetOnInitOverride(h_Fm);
69234 + }
69235 + else
69236 + {
69237 + /* Perform FMan reset */
69238 + FmReset(h_Fm);
69239 + }
69240 +
69241 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
69242 + {
69243 + fman_resume(p_Fm->p_FmFpmRegs);
69244 + XX_UDelay(100);
69245 + }
69246 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69247 + }
69248 +
69249 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
69250 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
69251 + {
69252 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69253 + /* Load FMan-Controller code to IRAM */
69254 +
69255 + ClearIRam(p_Fm);
69256 +
69257 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
69258 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
69259 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
69260 + }
69261 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69262 +
69263 +#ifdef FM_CAPWAP_SUPPORT
69264 + /* save first 256 byte in MURAM */
69265 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
69266 + if (!p_Fm->resAddr)
69267 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
69268 +
69269 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
69270 +#endif /* FM_CAPWAP_SUPPORT */
69271 +
69272 +#if (DPAA_VERSION >= 11)
69273 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69274 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
69275 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
69276 +#endif /* (DPAA_VERSION >= 11) */
69277 +
69278 + /* General FM driver initialization */
69279 + p_Fm->fmMuramPhysBaseAddr =
69280 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
69281 +
69282 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
69283 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
69284 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
69285 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
69286 +
69287 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
69288 +
69289 + /**********************/
69290 + /* Init DMA Registers */
69291 + /**********************/
69292 + err = InitFmDma(p_Fm);
69293 + if (err != E_OK)
69294 + {
69295 + FreeInitResources(p_Fm);
69296 + RETURN_ERROR(MAJOR, err, NO_MSG);
69297 + }
69298 +
69299 + /**********************/
69300 + /* Init FPM Registers */
69301 + /**********************/
69302 + err = InitFmFpm(p_Fm);
69303 + if (err != E_OK)
69304 + {
69305 + FreeInitResources(p_Fm);
69306 + RETURN_ERROR(MAJOR, err, NO_MSG);
69307 + }
69308 +
69309 + /* define common resources */
69310 + /* allocate MURAM for FIFO according to total size */
69311 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
69312 + p_Fm->p_FmStateStruct->totalFifoSize,
69313 + BMI_FIFO_ALIGN));
69314 + if (!p_Fm->fifoBaseAddr)
69315 + {
69316 + FreeInitResources(p_Fm);
69317 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
69318 + }
69319 +
69320 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
69321 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
69322 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
69323 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
69324 +
69325 + /**********************/
69326 + /* Init BMI Registers */
69327 + /**********************/
69328 + err = InitFmBmi(p_Fm);
69329 + if (err != E_OK)
69330 + {
69331 + FreeInitResources(p_Fm);
69332 + RETURN_ERROR(MAJOR, err, NO_MSG);
69333 + }
69334 +
69335 + /**********************/
69336 + /* Init QMI Registers */
69337 + /**********************/
69338 + err = InitFmQmi(p_Fm);
69339 + if (err != E_OK)
69340 + {
69341 + FreeInitResources(p_Fm);
69342 + RETURN_ERROR(MAJOR, err, NO_MSG);
69343 + }
69344 +
69345 + /* build the FM master partition IPC address */
69346 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
69347 + {
69348 + FreeInitResources(p_Fm);
69349 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
69350 + }
69351 +
69352 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
69353 + if (err)
69354 + {
69355 + FreeInitResources(p_Fm);
69356 + RETURN_ERROR(MAJOR, err, NO_MSG);
69357 + }
69358 +
69359 + /* Register the FM interrupts handlers */
69360 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
69361 + {
69362 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
69363 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
69364 + }
69365 +
69366 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
69367 + {
69368 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
69369 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
69370 + }
69371 +
69372 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
69373 + if (err != E_OK)
69374 + return err; /* FIXME */
69375 +
69376 + EnableTimeStamp(p_Fm);
69377 +
69378 + if (p_Fm->firmware.p_Code)
69379 + {
69380 + XX_Free(p_Fm->firmware.p_Code);
69381 + p_Fm->firmware.p_Code = NULL;
69382 + }
69383 +
69384 + XX_Free(p_Fm->p_FmDriverParam);
69385 + p_Fm->p_FmDriverParam = NULL;
69386 +
69387 + return E_OK;
69388 +}
69389 +
69390 +/**************************************************************************//**
69391 + @Function FM_Free
69392 +
69393 + @Description Frees all resources that were assigned to FM module.
69394 +
69395 + Calling this routine invalidates the descriptor.
69396 +
69397 + @Param[in] h_Fm - FM module descriptor
69398 +
69399 + @Return E_OK on success; Error code otherwise.
69400 +*//***************************************************************************/
69401 +t_Error FM_Free(t_Handle h_Fm)
69402 +{
69403 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69404 + struct fman_rg fman_rg;
69405 +
69406 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69407 +
69408 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69409 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69410 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69411 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69412 +
69413 + if (p_Fm->guestId != NCSW_MASTER_ID)
69414 + {
69415 +#if (DPAA_VERSION >= 11)
69416 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69417 +
69418 + if (p_Fm->p_FmSp)
69419 + {
69420 + XX_Free(p_Fm->p_FmSp);
69421 + p_Fm->p_FmSp = NULL;
69422 + }
69423 +#endif /* (DPAA_VERSION >= 11) */
69424 +
69425 + if (p_Fm->fmModuleName[0] != 0)
69426 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
69427 +
69428 + if (!p_Fm->recoveryMode)
69429 + XX_Free(p_Fm->p_FmStateStruct);
69430 +
69431 + XX_Free(p_Fm);
69432 +
69433 + return E_OK;
69434 + }
69435 +
69436 + fman_free_resources(&fman_rg);
69437 +
69438 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
69439 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
69440 +
69441 + if (p_Fm->p_FmStateStruct)
69442 + {
69443 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
69444 + {
69445 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
69446 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
69447 + }
69448 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
69449 + {
69450 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
69451 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
69452 + }
69453 + }
69454 +
69455 +#if (DPAA_VERSION >= 11)
69456 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69457 +
69458 + if (p_Fm->p_FmSp)
69459 + {
69460 + XX_Free(p_Fm->p_FmSp);
69461 + p_Fm->p_FmSp = NULL;
69462 + }
69463 +#endif /* (DPAA_VERSION >= 11) */
69464 +
69465 + if (p_Fm->h_Spinlock)
69466 + XX_FreeSpinlock(p_Fm->h_Spinlock);
69467 +
69468 + if (p_Fm->p_FmDriverParam)
69469 + {
69470 + if (p_Fm->firmware.p_Code)
69471 + XX_Free(p_Fm->firmware.p_Code);
69472 + XX_Free(p_Fm->p_FmDriverParam);
69473 + p_Fm->p_FmDriverParam = NULL;
69474 + }
69475 +
69476 + FreeInitResources(p_Fm);
69477 +
69478 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
69479 + XX_Free(p_Fm->p_FmStateStruct);
69480 +
69481 + XX_Free(p_Fm);
69482 +
69483 + return E_OK;
69484 +}
69485 +
69486 +/*************************************************/
69487 +/* API Advanced Init unit functions */
69488 +/*************************************************/
69489 +
69490 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
69491 +{
69492 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69493 +
69494 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69495 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69496 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69497 +
69498 + p_Fm->resetOnInit = enable;
69499 +
69500 + return E_OK;
69501 +}
69502 +
69503 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
69504 +{
69505 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69506 +
69507 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69508 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69509 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69510 +
69511 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
69512 +
69513 + return E_OK;
69514 +}
69515 +
69516 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
69517 +{
69518 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69519 +
69520 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69521 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69522 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69523 +
69524 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
69525 +
69526 + return E_OK;
69527 +}
69528 +
69529 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
69530 +{
69531 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69532 + enum fman_dma_cache_override fsl_cache_override;
69533 +
69534 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69535 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69536 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69537 +
69538 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
69539 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
69540 +
69541 + return E_OK;
69542 +}
69543 +
69544 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
69545 +{
69546 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69547 +
69548 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69549 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69550 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69551 +
69552 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
69553 +
69554 + return E_OK;
69555 +}
69556 +
69557 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
69558 +{
69559 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69560 + enum fman_dma_aid_mode fsl_aid_mode;
69561 +
69562 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69563 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69564 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69565 +
69566 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
69567 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
69568 +
69569 + return E_OK;
69570 +}
69571 +
69572 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
69573 +{
69574 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69575 +
69576 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69577 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69578 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69579 +
69580 +#if (DPAA_VERSION >= 11)
69581 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69582 +#else
69583 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
69584 +
69585 + return E_OK;
69586 +#endif /* (DPAA_VERSION >= 11) */
69587 +}
69588 +
69589 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
69590 +{
69591 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69592 +
69593 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69594 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69595 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69596 +
69597 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
69598 +
69599 + return E_OK;
69600 +}
69601 +
69602 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
69603 +{
69604 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69605 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
69606 +
69607 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69608 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69609 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69610 +
69611 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
69612 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
69613 +
69614 + return E_OK;
69615 +}
69616 +
69617 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
69618 +{
69619 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69620 +
69621 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69622 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69623 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69624 +
69625 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
69626 +
69627 + return E_OK;
69628 +}
69629 +
69630 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
69631 +{
69632 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69633 + enum fman_dma_emergency_level fsl_dma_emer;
69634 +
69635 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69636 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69637 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69638 +
69639 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
69640 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
69641 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
69642 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
69643 +
69644 + return E_OK;
69645 +}
69646 +
69647 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
69648 +{
69649 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69650 +
69651 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69652 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69653 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69654 +
69655 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
69656 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
69657 +
69658 + return E_OK;
69659 +}
69660 +
69661 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
69662 +{
69663 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69664 + enum fman_dma_err fsl_dma_err;
69665 +
69666 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69667 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69668 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69669 +
69670 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
69671 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
69672 +
69673 + return E_OK;
69674 +}
69675 +
69676 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
69677 +{
69678 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69679 + enum fman_catastrophic_err fsl_catastrophic_err;
69680 +
69681 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69682 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69683 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69684 +
69685 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
69686 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
69687 +
69688 + return E_OK;
69689 +}
69690 +
69691 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
69692 +{
69693 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69694 +
69695 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69696 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69697 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69698 +
69699 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69700 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69701 +
69702 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
69703 +
69704 + return E_OK;
69705 +}
69706 +
69707 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
69708 +{
69709 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69710 +
69711 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
69712 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69713 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69714 +
69715 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69716 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69717 +
69718 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
69719 +
69720 + return E_OK;
69721 +}
69722 +
69723 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
69724 +{
69725 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69726 +
69727 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69728 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69729 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69730 +
69731 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
69732 +
69733 + return E_OK;
69734 +}
69735 +
69736 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
69737 +{
69738 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69739 +
69740 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69741 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69742 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69743 +
69744 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69745 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69746 +
69747 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
69748 +
69749 + return E_OK;
69750 +}
69751 +
69752 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
69753 +{
69754 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69755 + uint32_t bitMask = 0;
69756 +
69757 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69758 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69759 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69760 +
69761 + GET_EXCEPTION_FLAG(bitMask, exception);
69762 + if (bitMask)
69763 + {
69764 + if (enable)
69765 + p_Fm->userSetExceptions |= bitMask;
69766 + else
69767 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
69768 + }
69769 + else
69770 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
69771 +
69772 + return E_OK;
69773 +}
69774 +
69775 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
69776 +{
69777 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69778 +
69779 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69780 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69781 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69782 +
69783 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
69784 +
69785 + return E_OK;
69786 +}
69787 +
69788 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
69789 +{
69790 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69791 +
69792 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69793 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69794 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69795 +
69796 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
69797 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
69798 +
69799 + return E_OK;
69800 +}
69801 +
69802 +/****************************************************/
69803 +/* Hidden-DEBUG Only API */
69804 +/****************************************************/
69805 +
69806 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
69807 +{
69808 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69809 +
69810 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69811 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69812 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69813 +
69814 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
69815 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
69816 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
69817 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
69818 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
69819 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
69820 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
69821 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
69822 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
69823 +
69824 + return E_OK;
69825 +}
69826 +
69827 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
69828 +{
69829 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69830 +
69831 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69832 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69833 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69834 +
69835 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
69836 +
69837 + return E_OK;
69838 +}
69839 +
69840 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
69841 +
69842 +{
69843 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69844 +
69845 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69846 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69847 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69848 +
69849 +#if (DPAA_VERSION >= 11)
69850 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69851 +#else
69852 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
69853 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
69854 +
69855 + return E_OK;
69856 +#endif
69857 +}
69858 +
69859 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
69860 +{
69861 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69862 +
69863 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69864 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69865 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69866 +
69867 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
69868 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
69869 +
69870 + return E_OK;
69871 +}
69872 +
69873 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
69874 +{
69875 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69876 +
69877 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69878 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69879 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69880 +
69881 +#if (DPAA_VERSION >= 11)
69882 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69883 +#else
69884 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
69885 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
69886 +
69887 + return E_OK;
69888 +#endif
69889 +}
69890 +
69891 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
69892 +{
69893 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69894 +
69895 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69896 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69897 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69898 +
69899 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
69900 +
69901 + return E_OK;
69902 +}
69903 +
69904 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
69905 +{
69906 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69907 +
69908 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69909 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69910 +UNUSED(p_Fm);
69911 +
69912 + return E_OK;
69913 +}
69914 +
69915 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
69916 +{
69917 + t_Fm* p_Fm = (t_Fm*)h_Fm;
69918 + if (p_Params->setParams.type & UPDATE_FM_CLD)
69919 + {
69920 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
69921 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
69922 + }
69923 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
69924 + {
69925 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
69926 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
69927 + }
69928 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
69929 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
69930 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
69931 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
69932 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
69933 + {
69934 + if (p_Params->setParams.sleep)
69935 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
69936 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
69937 + else
69938 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
69939 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
69940 + }
69941 + if (p_Params->getParams.type & GET_FM_CLD)
69942 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
69943 + if (p_Params->getParams.type & GET_FMQM_GS)
69944 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
69945 + if (p_Params->getParams.type & GET_FM_NPI)
69946 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
69947 + if (p_Params->getParams.type & GET_FMFP_EXTC)
69948 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
69949 + return E_OK;
69950 +}
69951 +
69952 +
69953 +/****************************************************/
69954 +/* API Run-time Control uint functions */
69955 +/****************************************************/
69956 +void FM_EventIsr(t_Handle h_Fm)
69957 +{
69958 +#define FM_M_CALL_1G_MAC_ISR(_id) \
69959 + { \
69960 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
69961 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
69962 + else \
69963 + 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);\
69964 + }
69965 +#define FM_M_CALL_10G_MAC_ISR(_id) \
69966 + { \
69967 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
69968 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
69969 + else \
69970 + 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);\
69971 + }
69972 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69973 + uint32_t pending, event;
69974 + struct fman_fpm_regs *fpm_rg;
69975 +
69976 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69977 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69978 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69979 +
69980 + fpm_rg = p_Fm->p_FmFpmRegs;
69981 +
69982 + /* normal interrupts */
69983 + pending = fman_get_normal_pending(fpm_rg);
69984 + if (!pending)
69985 + return;
69986 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
69987 + {
69988 + t_FmGetSetParams fmGetSetParams;
69989 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
69990 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
69991 + fmGetSetParams.setParams.sleep = 0;
69992 + FmGetSetParams(h_Fm, &fmGetSetParams);
69993 + }
69994 + if (pending & INTR_EN_QMI)
69995 + QmiEvent(p_Fm);
69996 + if (pending & INTR_EN_PRS)
69997 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
69998 + if (pending & INTR_EN_PLCR)
69999 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
70000 + if (pending & INTR_EN_TMR)
70001 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
70002 +
70003 + /* MAC events may belong to different partitions */
70004 + if (pending & INTR_EN_1G_MAC0)
70005 + FM_M_CALL_1G_MAC_ISR(0);
70006 + if (pending & INTR_EN_1G_MAC1)
70007 + FM_M_CALL_1G_MAC_ISR(1);
70008 + if (pending & INTR_EN_1G_MAC2)
70009 + FM_M_CALL_1G_MAC_ISR(2);
70010 + if (pending & INTR_EN_1G_MAC3)
70011 + FM_M_CALL_1G_MAC_ISR(3);
70012 + if (pending & INTR_EN_1G_MAC4)
70013 + FM_M_CALL_1G_MAC_ISR(4);
70014 + if (pending & INTR_EN_1G_MAC5)
70015 + FM_M_CALL_1G_MAC_ISR(5);
70016 + if (pending & INTR_EN_1G_MAC6)
70017 + FM_M_CALL_1G_MAC_ISR(6);
70018 + if (pending & INTR_EN_1G_MAC7)
70019 + FM_M_CALL_1G_MAC_ISR(7);
70020 + if (pending & INTR_EN_10G_MAC0)
70021 + FM_M_CALL_10G_MAC_ISR(0);
70022 + if (pending & INTR_EN_10G_MAC1)
70023 + FM_M_CALL_10G_MAC_ISR(1);
70024 +
70025 + /* IM port events may belong to different partitions */
70026 + if (pending & INTR_EN_REV0)
70027 + {
70028 + event = fman_get_controller_event(fpm_rg, 0);
70029 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
70030 + /*TODO IPC ISR For Fman Ctrl */
70031 + ASSERT_COND(0);
70032 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
70033 + else
70034 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
70035 +
70036 + }
70037 + if (pending & INTR_EN_REV1)
70038 + {
70039 + event = fman_get_controller_event(fpm_rg, 1);
70040 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
70041 + /*TODO IPC ISR For Fman Ctrl */
70042 + ASSERT_COND(0);
70043 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
70044 + else
70045 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
70046 + }
70047 + if (pending & INTR_EN_REV2)
70048 + {
70049 + event = fman_get_controller_event(fpm_rg, 2);
70050 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
70051 + /*TODO IPC ISR For Fman Ctrl */
70052 + ASSERT_COND(0);
70053 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
70054 + else
70055 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
70056 + }
70057 + if (pending & INTR_EN_REV3)
70058 + {
70059 + event = fman_get_controller_event(fpm_rg, 3);
70060 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
70061 + /*TODO IPC ISR For Fman Ctrl */
70062 + ASSERT_COND(0);
70063 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
70064 + else
70065 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
70066 + }
70067 +#ifdef FM_MACSEC_SUPPORT
70068 + if (pending & INTR_EN_MACSEC_MAC0)
70069 + {
70070 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
70071 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
70072 + else
70073 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
70074 + }
70075 +#endif /* FM_MACSEC_SUPPORT */
70076 +}
70077 +
70078 +t_Error FM_ErrorIsr(t_Handle h_Fm)
70079 +{
70080 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
70081 + { \
70082 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
70083 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
70084 + else \
70085 + 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);\
70086 + }
70087 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
70088 + { \
70089 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
70090 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
70091 + else \
70092 + 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);\
70093 + }
70094 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70095 + uint32_t pending;
70096 + struct fman_fpm_regs *fpm_rg;
70097 +
70098 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
70099 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70100 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70101 +
70102 + fpm_rg = p_Fm->p_FmFpmRegs;
70103 +
70104 + /* error interrupts */
70105 + pending = fman_get_fpm_error_interrupts(fpm_rg);
70106 + if (!pending)
70107 + return ERROR_CODE(E_EMPTY);
70108 +
70109 + if (pending & ERR_INTR_EN_BMI)
70110 + BmiErrEvent(p_Fm);
70111 + if (pending & ERR_INTR_EN_QMI)
70112 + QmiErrEvent(p_Fm);
70113 + if (pending & ERR_INTR_EN_FPM)
70114 + FpmErrEvent(p_Fm);
70115 + if (pending & ERR_INTR_EN_DMA)
70116 + DmaErrEvent(p_Fm);
70117 + if (pending & ERR_INTR_EN_IRAM)
70118 + IramErrIntr(p_Fm);
70119 + if (pending & ERR_INTR_EN_MURAM)
70120 + MuramErrIntr(p_Fm);
70121 + if (pending & ERR_INTR_EN_PRS)
70122 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
70123 + if (pending & ERR_INTR_EN_PLCR)
70124 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
70125 + if (pending & ERR_INTR_EN_KG)
70126 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
70127 +
70128 + /* MAC events may belong to different partitions */
70129 + if (pending & ERR_INTR_EN_1G_MAC0)
70130 + FM_M_CALL_1G_MAC_ERR_ISR(0);
70131 + if (pending & ERR_INTR_EN_1G_MAC1)
70132 + FM_M_CALL_1G_MAC_ERR_ISR(1);
70133 + if (pending & ERR_INTR_EN_1G_MAC2)
70134 + FM_M_CALL_1G_MAC_ERR_ISR(2);
70135 + if (pending & ERR_INTR_EN_1G_MAC3)
70136 + FM_M_CALL_1G_MAC_ERR_ISR(3);
70137 + if (pending & ERR_INTR_EN_1G_MAC4)
70138 + FM_M_CALL_1G_MAC_ERR_ISR(4);
70139 + if (pending & ERR_INTR_EN_1G_MAC5)
70140 + FM_M_CALL_1G_MAC_ERR_ISR(5);
70141 + if (pending & ERR_INTR_EN_1G_MAC6)
70142 + FM_M_CALL_1G_MAC_ERR_ISR(6);
70143 + if (pending & ERR_INTR_EN_1G_MAC7)
70144 + FM_M_CALL_1G_MAC_ERR_ISR(7);
70145 + if (pending & ERR_INTR_EN_10G_MAC0)
70146 + FM_M_CALL_10G_MAC_ERR_ISR(0);
70147 + if (pending & ERR_INTR_EN_10G_MAC1)
70148 + FM_M_CALL_10G_MAC_ERR_ISR(1);
70149 +
70150 +#ifdef FM_MACSEC_SUPPORT
70151 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
70152 + {
70153 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
70154 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
70155 + else
70156 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
70157 + }
70158 +#endif /* FM_MACSEC_SUPPORT */
70159 +
70160 + return E_OK;
70161 +}
70162 +
70163 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
70164 +{
70165 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70166 + int i;
70167 + uint8_t sum;
70168 + uint8_t hardwarePortId;
70169 + uint8_t weights[64];
70170 + uint8_t weight, maxPercent = 0;
70171 + struct fman_bmi_regs *bmi_rg;
70172 +
70173 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70174 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70175 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70176 +
70177 + bmi_rg = p_Fm->p_FmBmiRegs;
70178 +
70179 + memset(weights, 0, (sizeof(uint8_t) * 64));
70180 +
70181 + /* check that all ports add up to 100% */
70182 + sum = 0;
70183 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
70184 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
70185 + if (sum != 100)
70186 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
70187 +
70188 + /* find highest percent */
70189 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
70190 + {
70191 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
70192 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
70193 + }
70194 +
70195 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
70196 +
70197 + /* calculate weight for each port */
70198 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
70199 + {
70200 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
70201 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
70202 + is not reached, we round up so that:
70203 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
70204 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
70205 + ...
70206 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
70207 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
70208 + weight++;
70209 +
70210 + /* find the location of this port within the register */
70211 + hardwarePortId =
70212 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
70213 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
70214 + p_Fm->p_FmStateStruct->revInfo.majorRev,
70215 + p_Fm->p_FmStateStruct->revInfo.minorRev);
70216 +
70217 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
70218 + weights[hardwarePortId] = weight;
70219 + }
70220 +
70221 + fman_set_ports_bandwidth(bmi_rg, weights);
70222 +
70223 + return E_OK;
70224 +}
70225 +
70226 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
70227 +{
70228 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70229 + struct fman_fpm_regs *fpm_rg;
70230 +
70231 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70232 +
70233 + fpm_rg = p_Fm->p_FmFpmRegs;
70234 +
70235 + if (p_Fm->guestId != NCSW_MASTER_ID)
70236 + {
70237 + t_FmIpcMsg msg;
70238 + t_Error err;
70239 +
70240 + memset(&msg, 0, sizeof(msg));
70241 + msg.msgId = FM_ENABLE_RAM_ECC;
70242 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70243 + (uint8_t*)&msg,
70244 + sizeof(msg.msgId),
70245 + NULL,
70246 + NULL,
70247 + NULL,
70248 + NULL);
70249 + if (err != E_OK)
70250 + RETURN_ERROR(MINOR, err, NO_MSG);
70251 + return E_OK;
70252 + }
70253 +
70254 + if (!p_Fm->p_FmStateStruct->internalCall)
70255 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
70256 + p_Fm->p_FmStateStruct->internalCall = FALSE;
70257 +
70258 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
70259 + return E_OK;
70260 + else
70261 + {
70262 + fman_enable_rams_ecc(fpm_rg);
70263 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
70264 + }
70265 +
70266 + return E_OK;
70267 +}
70268 +
70269 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
70270 +{
70271 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70272 + bool explicitDisable = FALSE;
70273 + struct fman_fpm_regs *fpm_rg;
70274 +
70275 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70276 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70277 +
70278 + fpm_rg = p_Fm->p_FmFpmRegs;
70279 +
70280 + if (p_Fm->guestId != NCSW_MASTER_ID)
70281 + {
70282 + t_Error err;
70283 + t_FmIpcMsg msg;
70284 +
70285 + memset(&msg, 0, sizeof(msg));
70286 + msg.msgId = FM_DISABLE_RAM_ECC;
70287 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70288 + (uint8_t*)&msg,
70289 + sizeof(msg.msgId),
70290 + NULL,
70291 + NULL,
70292 + NULL,
70293 + NULL)) != E_OK)
70294 + RETURN_ERROR(MINOR, err, NO_MSG);
70295 + return E_OK;
70296 + }
70297 +
70298 + if (!p_Fm->p_FmStateStruct->internalCall)
70299 + explicitDisable = TRUE;
70300 + p_Fm->p_FmStateStruct->internalCall = FALSE;
70301 +
70302 + /* if rams are already disabled, or if rams were explicitly enabled and are
70303 + currently called indirectly (not explicitly), ignore this call. */
70304 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
70305 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
70306 + return E_OK;
70307 + else
70308 + {
70309 + if (p_Fm->p_FmStateStruct->explicitEnable)
70310 + /* This is the case were both explicit are TRUE.
70311 + Turn off this flag for cases were following ramsEnable
70312 + routines are called */
70313 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
70314 +
70315 + fman_enable_rams_ecc(fpm_rg);
70316 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
70317 + }
70318 +
70319 + return E_OK;
70320 +}
70321 +
70322 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
70323 +{
70324 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70325 + uint32_t bitMask = 0;
70326 + enum fman_exceptions fslException;
70327 + struct fman_rg fman_rg;
70328 +
70329 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70330 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70331 +
70332 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70333 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70334 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70335 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70336 +
70337 + GET_EXCEPTION_FLAG(bitMask, exception);
70338 + if (bitMask)
70339 + {
70340 + if (enable)
70341 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
70342 + else
70343 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
70344 +
70345 + fslException = FmanExceptionTrans(exception);
70346 +
70347 + return (t_Error)fman_set_exception(&fman_rg,
70348 + fslException,
70349 + enable);
70350 + }
70351 + else
70352 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
70353 +
70354 + return E_OK;
70355 +}
70356 +
70357 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
70358 +{
70359 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70360 +
70361 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
70362 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
70363 +
70364 + return E_OK;
70365 +}
70366 +
70367 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
70368 +{
70369 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70370 + t_FMIramRegs *p_Iram;
70371 + uint32_t revInfo;
70372 +
70373 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70374 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
70375 +
70376 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
70377 + p_Fm->h_IpcSessions[0])
70378 + {
70379 + t_Error err;
70380 + t_FmIpcMsg msg;
70381 + t_FmIpcReply reply;
70382 + uint32_t replyLength;
70383 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
70384 +
70385 + memset(&msg, 0, sizeof(msg));
70386 + memset(&reply, 0, sizeof(reply));
70387 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
70388 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
70389 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70390 + (uint8_t*)&msg,
70391 + sizeof(msg.msgId),
70392 + (uint8_t*)&reply,
70393 + &replyLength,
70394 + NULL,
70395 + NULL)) != E_OK)
70396 + RETURN_ERROR(MINOR, err, NO_MSG);
70397 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
70398 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
70399 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
70400 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
70401 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
70402 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
70403 + return (t_Error)(reply.error);
70404 + }
70405 + else if (p_Fm->guestId != NCSW_MASTER_ID)
70406 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
70407 + ("running in guest-mode without IPC!"));
70408 +
70409 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
70410 + WRITE_UINT32(p_Iram->iadd, 0x4);
70411 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
70412 + revInfo = GET_UINT32(p_Iram->idata);
70413 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
70414 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
70415 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
70416 +
70417 + return E_OK;
70418 +}
70419 +
70420 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
70421 +{
70422 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70423 + t_Error err;
70424 + uint32_t counterValue;
70425 + struct fman_rg fman_rg;
70426 + enum fman_counters fsl_counter;
70427 +
70428 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
70429 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
70430 +
70431 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70432 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70433 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70434 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70435 +
70436 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
70437 + !p_Fm->baseAddr &&
70438 + p_Fm->h_IpcSessions[0])
70439 + {
70440 + t_FmIpcMsg msg;
70441 + t_FmIpcReply reply;
70442 + uint32_t replyLength, outCounter;
70443 +
70444 + memset(&msg, 0, sizeof(msg));
70445 + memset(&reply, 0, sizeof(reply));
70446 + msg.msgId = FM_GET_COUNTER;
70447 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
70448 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
70449 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70450 + (uint8_t*)&msg,
70451 + sizeof(msg.msgId) +sizeof(counterValue),
70452 + (uint8_t*)&reply,
70453 + &replyLength,
70454 + NULL,
70455 + NULL);
70456 + if (err != E_OK)
70457 + {
70458 + REPORT_ERROR(MAJOR, err, NO_MSG);
70459 + return 0;
70460 + }
70461 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
70462 + {
70463 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
70464 + return 0;
70465 + }
70466 +
70467 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
70468 + return outCounter;
70469 + }
70470 + else if (!p_Fm->baseAddr)
70471 + {
70472 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
70473 + return 0;
70474 + }
70475 +
70476 + /* When applicable (when there is an 'enable counters' bit,
70477 + check that counters are enabled */
70478 + switch (counter)
70479 + {
70480 + case (e_FM_COUNTERS_DEQ_1):
70481 + case (e_FM_COUNTERS_DEQ_2):
70482 + case (e_FM_COUNTERS_DEQ_3):
70483 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
70484 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
70485 + {
70486 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
70487 + return 0;
70488 + }
70489 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
70490 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
70491 + case (e_FM_COUNTERS_DEQ_0):
70492 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
70493 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
70494 + case (e_FM_COUNTERS_DEQ_FROM_FD):
70495 + case (e_FM_COUNTERS_DEQ_CONFIRM):
70496 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
70497 + {
70498 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
70499 + return 0;
70500 + }
70501 + break;
70502 + default:
70503 + break;
70504 + }
70505 +
70506 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
70507 + return fman_get_counter(&fman_rg, fsl_counter);
70508 +}
70509 +
70510 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
70511 +{
70512 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70513 + struct fman_rg fman_rg;
70514 + enum fman_counters fsl_counter;
70515 +
70516 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70517 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70518 +
70519 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70520 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70521 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70522 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70523 +
70524 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
70525 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
70526 +}
70527 +
70528 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
70529 +{
70530 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70531 + struct fman_dma_regs *dma_rg;
70532 +
70533 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70534 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70535 +
70536 + dma_rg = p_Fm->p_FmDmaRegs;
70537 +
70538 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
70539 +}
70540 +
70541 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
70542 +{
70543 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70544 + struct fman_dma_regs *dma_rg;
70545 +
70546 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70547 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70548 +
70549 + dma_rg = p_Fm->p_FmDmaRegs;
70550 +
70551 + fman_set_dma_ext_bus_pri(dma_rg, pri);
70552 +}
70553 +
70554 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
70555 +{
70556 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70557 + uint32_t dmaStatus;
70558 + struct fman_dma_regs *dma_rg;
70559 +
70560 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70561 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70562 +
70563 + dma_rg = p_Fm->p_FmDmaRegs;
70564 +
70565 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
70566 + !p_Fm->baseAddr &&
70567 + p_Fm->h_IpcSessions[0])
70568 + {
70569 + t_FmIpcDmaStatus ipcDmaStatus;
70570 + t_FmIpcMsg msg;
70571 + t_FmIpcReply reply;
70572 + t_Error err;
70573 + uint32_t replyLength;
70574 +
70575 + memset(&msg, 0, sizeof(msg));
70576 + memset(&reply, 0, sizeof(reply));
70577 + msg.msgId = FM_DMA_STAT;
70578 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
70579 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70580 + (uint8_t*)&msg,
70581 + sizeof(msg.msgId),
70582 + (uint8_t*)&reply,
70583 + &replyLength,
70584 + NULL,
70585 + NULL);
70586 + if (err != E_OK)
70587 + {
70588 + REPORT_ERROR(MINOR, err, NO_MSG);
70589 + return;
70590 + }
70591 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
70592 + {
70593 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
70594 + return;
70595 + }
70596 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
70597 +
70598 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
70599 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
70600 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
70601 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70602 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70603 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
70604 + return;
70605 + }
70606 + else if (!p_Fm->baseAddr)
70607 + {
70608 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
70609 + ("Either IPC or 'baseAddress' is required!"));
70610 + return;
70611 + }
70612 +
70613 + dmaStatus = fman_get_dma_status(dma_rg);
70614 +
70615 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
70616 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
70617 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
70618 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
70619 + else
70620 + {
70621 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
70622 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
70623 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
70624 + }
70625 +}
70626 +
70627 +void FM_Resume(t_Handle h_Fm)
70628 +{
70629 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70630 + struct fman_fpm_regs *fpm_rg;
70631 +
70632 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70633 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70634 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70635 +
70636 + fpm_rg = p_Fm->p_FmFpmRegs;
70637 +
70638 + fman_resume(fpm_rg);
70639 +}
70640 +
70641 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
70642 + fmSpecialOperations_t spOper,
70643 + uint8_t *p_SpOperCoding)
70644 +{
70645 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70646 + t_FmCtrlCodeRevisionInfo revInfo;
70647 + t_Error err;
70648 +
70649 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70650 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70651 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
70652 +
70653 + if (!spOper)
70654 + {
70655 + *p_SpOperCoding = 0;
70656 + return E_OK;
70657 + }
70658 +
70659 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
70660 + {
70661 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
70662 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
70663 + }
70664 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
70665 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
70666 +
70667 + switch (spOper)
70668 + {
70669 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
70670 + *p_SpOperCoding = 9;
70671 + break;
70672 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
70673 + *p_SpOperCoding = 10;
70674 + break;
70675 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
70676 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
70677 + *p_SpOperCoding = 5;
70678 + break;
70679 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
70680 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
70681 + *p_SpOperCoding = 6;
70682 + break;
70683 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
70684 + *p_SpOperCoding = 3;
70685 + break;
70686 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
70687 + *p_SpOperCoding = 1;
70688 + break;
70689 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
70690 + *p_SpOperCoding = 12;
70691 + break;
70692 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
70693 + *p_SpOperCoding = 4;
70694 + break;
70695 + case (FM_SP_OP_IPSEC):
70696 + *p_SpOperCoding = 2;
70697 + break;
70698 + case (FM_SP_OP_DCL4C):
70699 + *p_SpOperCoding = 7;
70700 + break;
70701 + case (FM_SP_OP_CLEAR_RPD):
70702 + *p_SpOperCoding = 8;
70703 + break;
70704 + default:
70705 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
70706 + }
70707 +
70708 + return E_OK;
70709 +}
70710 +
70711 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
70712 +{
70713 + t_Fm *p_Fm = (t_Fm *)h_Fm;
70714 + t_FmTrbRegs *p_MonRegs;
70715 + uint8_t i;
70716 +
70717 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70718 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70719 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70720 +
70721 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
70722 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
70723 +
70724 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
70725 + {
70726 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
70727 +
70728 + /* Reset control registers */
70729 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
70730 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
70731 +
70732 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
70733 + counter #2 counts all stalls in risc - other stall*/
70734 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
70735 +
70736 + /* Enable monitoring */
70737 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
70738 + }
70739 +
70740 + return E_OK;
70741 +}
70742 +
70743 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
70744 +{
70745 + t_Fm *p_Fm = (t_Fm *)h_Fm;
70746 + t_FmTrbRegs *p_MonRegs;
70747 + uint8_t i;
70748 +
70749 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70750 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70751 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70752 +
70753 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
70754 + {
70755 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
70756 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
70757 + }
70758 +
70759 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
70760 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
70761 +
70762 + return E_OK;
70763 +}
70764 +
70765 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
70766 +{
70767 + t_Fm *p_Fm = (t_Fm *)h_Fm;
70768 + t_FmTrbRegs *p_MonRegs;
70769 + uint64_t clkCnt, utilValue, effValue;
70770 +
70771 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70772 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70773 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70774 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
70775 +
70776 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
70777 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
70778 +
70779 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
70780 +
70781 + clkCnt = (uint64_t)
70782 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
70783 +
70784 + utilValue = (uint64_t)
70785 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
70786 +
70787 + effValue = (uint64_t)
70788 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
70789 +
70790 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
70791 + if (clkCnt != utilValue)
70792 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
70793 + else
70794 + p_Mon->percentCnt[1] = 0;
70795 +
70796 + return E_OK;
70797 +}
70798 +
70799 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
70800 +{
70801 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70802 +
70803 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
70804 +
70805 + return (p_Fm->h_FmMuram);
70806 +}
70807 +
70808 +/****************************************************/
70809 +/* Hidden-DEBUG Only API */
70810 +/****************************************************/
70811 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
70812 +{
70813 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70814 + enum fman_exceptions fslException;
70815 + struct fman_rg fman_rg;
70816 +
70817 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70818 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70819 +
70820 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70821 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70822 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70823 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70824 +
70825 + switch (exception)
70826 + {
70827 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
70828 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
70829 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70830 + break;
70831 + case e_FM_EX_QMI_SINGLE_ECC:
70832 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
70833 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
70834 +
70835 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
70836 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70837 + break;
70838 + case e_FM_EX_QMI_DOUBLE_ECC:
70839 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
70840 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70841 + break;
70842 + case e_FM_EX_BMI_LIST_RAM_ECC:
70843 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
70844 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70845 + break;
70846 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
70847 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
70848 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70849 + break;
70850 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
70851 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
70852 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70853 + break;
70854 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
70855 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
70856 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
70857 + break;
70858 + default:
70859 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
70860 + }
70861 +
70862 + fslException = FmanExceptionTrans(exception);
70863 + fman_force_intr (&fman_rg, fslException);
70864 +
70865 + return E_OK;
70866 +}
70867 +
70868 +t_Handle FmGetPcd(t_Handle h_Fm)
70869 +{
70870 + return ((t_Fm*)h_Fm)->h_Pcd;
70871 +}
70872 +#if (DPAA_VERSION >= 11)
70873 +extern void *g_MemacRegs;
70874 +void fm_clk_down(void);
70875 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
70876 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
70877 +{
70878 + int macId;
70879 + uint32_t event, rcr;
70880 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70881 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
70882 + rcr |= 0x04000000;
70883 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
70884 +
70885 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
70886 + do
70887 + {
70888 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
70889 + } while ((event & 0x00000020) == 0);
70890 + fm_clk_down();
70891 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
70892 + rcr &= ~0x04000000;
70893 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
70894 +}
70895 +#endif
70896 --- /dev/null
70897 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
70898 @@ -0,0 +1,648 @@
70899 +/*
70900 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70901 + *
70902 + * Redistribution and use in source and binary forms, with or without
70903 + * modification, are permitted provided that the following conditions are met:
70904 + * * Redistributions of source code must retain the above copyright
70905 + * notice, this list of conditions and the following disclaimer.
70906 + * * Redistributions in binary form must reproduce the above copyright
70907 + * notice, this list of conditions and the following disclaimer in the
70908 + * documentation and/or other materials provided with the distribution.
70909 + * * Neither the name of Freescale Semiconductor nor the
70910 + * names of its contributors may be used to endorse or promote products
70911 + * derived from this software without specific prior written permission.
70912 + *
70913 + *
70914 + * ALTERNATIVELY, this software may be distributed under the terms of the
70915 + * GNU General Public License ("GPL") as published by the Free Software
70916 + * Foundation, either version 2 of that License or (at your option) any
70917 + * later version.
70918 + *
70919 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70920 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70921 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70922 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70923 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70924 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70925 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70926 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70927 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70928 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70929 + */
70930 +
70931 +
70932 +/******************************************************************************
70933 + @File fm.h
70934 +
70935 + @Description FM internal structures and definitions.
70936 +*//***************************************************************************/
70937 +#ifndef __FM_H
70938 +#define __FM_H
70939 +
70940 +#include "error_ext.h"
70941 +#include "std_ext.h"
70942 +#include "fm_ext.h"
70943 +#include "fm_ipc.h"
70944 +
70945 +#include "fsl_fman.h"
70946 +
70947 +#define __ERR_MODULE__ MODULE_FM
70948 +
70949 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
70950 +#define FM_MAX_NUM_OF_GUESTS 100
70951 +
70952 +/**************************************************************************//**
70953 + @Description Exceptions
70954 +*//***************************************************************************/
70955 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
70956 +#define FM_EX_DMA_READ_ECC 0x40000000
70957 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
70958 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
70959 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
70960 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
70961 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
70962 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
70963 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
70964 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
70965 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
70966 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
70967 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
70968 +#define FM_EX_IRAM_ECC 0x00040000
70969 +#define FM_EX_MURAM_ECC 0x00020000
70970 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
70971 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
70972 +
70973 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
70974 +
70975 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
70976 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
70977 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
70978 +
70979 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
70980 +switch (exception){ \
70981 + case e_FM_EX_DMA_BUS_ERROR: \
70982 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
70983 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
70984 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
70985 + case e_FM_EX_DMA_READ_ECC: \
70986 + bitMask = FM_EX_DMA_READ_ECC; break; \
70987 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
70988 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
70989 + case e_FM_EX_DMA_FM_WRITE_ECC: \
70990 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
70991 + case e_FM_EX_FPM_STALL_ON_TASKS: \
70992 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
70993 + case e_FM_EX_FPM_SINGLE_ECC: \
70994 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
70995 + case e_FM_EX_FPM_DOUBLE_ECC: \
70996 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
70997 + case e_FM_EX_QMI_SINGLE_ECC: \
70998 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
70999 + case e_FM_EX_QMI_DOUBLE_ECC: \
71000 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
71001 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
71002 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
71003 + case e_FM_EX_BMI_LIST_RAM_ECC: \
71004 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
71005 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
71006 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
71007 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
71008 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
71009 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
71010 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
71011 + case e_FM_EX_IRAM_ECC: \
71012 + bitMask = FM_EX_IRAM_ECC; break; \
71013 + case e_FM_EX_MURAM_ECC: \
71014 + bitMask = FM_EX_MURAM_ECC; break; \
71015 + default: bitMask = 0;break; \
71016 +}
71017 +
71018 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
71019 + switch (_mod) { \
71020 + case e_FM_MOD_PRS: \
71021 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71022 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
71023 + break; \
71024 + case e_FM_MOD_KG: \
71025 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71026 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
71027 + break; \
71028 + case e_FM_MOD_PLCR: \
71029 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71030 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
71031 + break; \
71032 + case e_FM_MOD_TMR: \
71033 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71034 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
71035 + break; \
71036 + case e_FM_MOD_10G_MAC: \
71037 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
71038 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
71039 + break; \
71040 + case e_FM_MOD_1G_MAC: \
71041 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
71042 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
71043 + break; \
71044 + case e_FM_MOD_MACSEC: \
71045 + switch (_id){ \
71046 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
71047 + break; \
71048 + } \
71049 + break; \
71050 + case e_FM_MOD_FMAN_CTRL: \
71051 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
71052 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
71053 + break; \
71054 + default: _event = e_FM_EV_DUMMY_LAST; \
71055 + break; \
71056 + }
71057 +
71058 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
71059 + switch (_cache_override){ \
71060 + case e_FM_DMA_NO_CACHE_OR: \
71061 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
71062 + case e_FM_DMA_NO_STASH_DATA: \
71063 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
71064 + case e_FM_DMA_MAY_STASH_DATA: \
71065 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
71066 + case e_FM_DMA_STASH_DATA: \
71067 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
71068 + default: \
71069 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
71070 + }
71071 +
71072 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
71073 + switch (_aid_mode){ \
71074 + case e_FM_DMA_AID_OUT_PORT_ID: \
71075 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
71076 + case e_FM_DMA_AID_OUT_TNUM: \
71077 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
71078 + default: \
71079 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
71080 + }
71081 +
71082 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
71083 + switch (_dma_dbg_cnt){ \
71084 + case e_FM_DMA_DBG_NO_CNT: \
71085 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
71086 + case e_FM_DMA_DBG_CNT_DONE: \
71087 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
71088 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
71089 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
71090 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
71091 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
71092 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
71093 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
71094 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
71095 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
71096 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
71097 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
71098 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
71099 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
71100 + default: \
71101 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
71102 + }
71103 +
71104 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
71105 + switch (_dma_emer){ \
71106 + case e_FM_DMA_EM_EBS: \
71107 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
71108 + case e_FM_DMA_EM_SOS: \
71109 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
71110 + default: \
71111 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
71112 + }
71113 +
71114 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
71115 + switch (_dma_err){ \
71116 + case e_FM_DMA_ERR_CATASTROPHIC: \
71117 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
71118 + case e_FM_DMA_ERR_REPORT: \
71119 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
71120 + default: \
71121 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
71122 + }
71123 +
71124 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
71125 + switch (_catastrophic_err){ \
71126 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
71127 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
71128 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
71129 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
71130 + default: \
71131 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
71132 + }
71133 +
71134 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
71135 + switch (_counters){ \
71136 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
71137 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
71138 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
71139 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
71140 + case e_FM_COUNTERS_DEQ_0: \
71141 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
71142 + case e_FM_COUNTERS_DEQ_1: \
71143 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
71144 + case e_FM_COUNTERS_DEQ_2: \
71145 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
71146 + case e_FM_COUNTERS_DEQ_3: \
71147 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
71148 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
71149 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
71150 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
71151 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
71152 + case e_FM_COUNTERS_DEQ_FROM_FD: \
71153 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
71154 + case e_FM_COUNTERS_DEQ_CONFIRM: \
71155 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
71156 + default: \
71157 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
71158 + }
71159 +
71160 +/**************************************************************************//**
71161 + @Description defaults
71162 +*//***************************************************************************/
71163 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
71164 + FM_EX_DMA_READ_ECC |\
71165 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
71166 + FM_EX_DMA_FM_WRITE_ECC |\
71167 + FM_EX_FPM_STALL_ON_TASKS |\
71168 + FM_EX_FPM_SINGLE_ECC |\
71169 + FM_EX_FPM_DOUBLE_ECC |\
71170 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
71171 + FM_EX_BMI_LIST_RAM_ECC |\
71172 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
71173 + FM_EX_BMI_STATISTICS_RAM_ECC |\
71174 + FM_EX_IRAM_ECC |\
71175 + FM_EX_MURAM_ECC |\
71176 + FM_EX_BMI_DISPATCH_RAM_ECC |\
71177 + FM_EX_QMI_DOUBLE_ECC |\
71178 + FM_EX_QMI_SINGLE_ECC)
71179 +
71180 +#define DEFAULT_eccEnable FALSE
71181 +#ifdef FM_PEDANTIC_DMA
71182 +#define DEFAULT_aidOverride TRUE
71183 +#else
71184 +#define DEFAULT_aidOverride FALSE
71185 +#endif /* FM_PEDANTIC_DMA */
71186 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
71187 +#define DEFAULT_dmaStopOnBusError FALSE
71188 +#define DEFAULT_stopAtBusError FALSE
71189 +#define DEFAULT_axiDbgNumOfBeats 1
71190 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
71191 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
71192 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
71193 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
71194 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
71195 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
71196 +#define DEFAULT_resetOnInit FALSE
71197 +#define DEFAULT_resetOnInitOverrideCallback NULL
71198 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
71199 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
71200 +#define DEFAULT_externalEccRamsEnable FALSE
71201 +#define DEFAULT_VerifyUcode FALSE
71202 +
71203 +#if (DPAA_VERSION < 11)
71204 +#define DEFAULT_totalFifoSize(major, minor) \
71205 + (((major == 2) || (major == 5)) ? \
71206 + (100*KILOBYTE) : ((major == 4) ? \
71207 + (49*KILOBYTE) : (122*KILOBYTE)))
71208 +#define DEFAULT_totalNumOfTasks(major, minor) \
71209 + BMI_MAX_NUM_OF_TASKS
71210 +
71211 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
71212 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
71213 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
71214 +#define DEFAULT_dmaCamNumOfEntries 32
71215 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
71216 +#define DEFAULT_dmaEnEmergency FALSE
71217 +#define DEFAULT_dmaSosEmergency 0
71218 +#define DEFAULT_dmaWatchdog 0 /* disabled */
71219 +#define DEFAULT_dmaEnEmergencySmoother FALSE
71220 +#define DEFAULT_dmaEmergencySwitchCounter 0
71221 +
71222 +#define DEFAULT_dispLimit 0
71223 +#define DEFAULT_prsDispTh 16
71224 +#define DEFAULT_plcrDispTh 16
71225 +#define DEFAULT_kgDispTh 16
71226 +#define DEFAULT_bmiDispTh 16
71227 +#define DEFAULT_qmiEnqDispTh 16
71228 +#define DEFAULT_qmiDeqDispTh 16
71229 +#define DEFAULT_fmCtl1DispTh 16
71230 +#define DEFAULT_fmCtl2DispTh 16
71231 +
71232 +#else /* (DPAA_VERSION < 11) */
71233 +/* Defaults are registers' reset values */
71234 +#define DEFAULT_totalFifoSize(major, minor) \
71235 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
71236 + (156*KILOBYTE) : (295*KILOBYTE))
71237 +
71238 +/* According to the default value of FMBM_CFG2[TNTSKS] */
71239 +#define DEFAULT_totalNumOfTasks(major, minor) \
71240 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
71241 +
71242 +#define DEFAULT_dmaCommQLow 0x2A
71243 +#define DEFAULT_dmaCommQHigh 0x3F
71244 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
71245 +#define DEFAULT_dmaCamNumOfEntries 64
71246 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
71247 +#define DEFAULT_dmaEnEmergency FALSE
71248 +#define DEFAULT_dmaSosEmergency 0
71249 +#define DEFAULT_dmaWatchdog 0 /* disabled */
71250 +#define DEFAULT_dmaEnEmergencySmoother FALSE
71251 +#define DEFAULT_dmaEmergencySwitchCounter 0
71252 +
71253 +#define DEFAULT_dispLimit 0
71254 +#define DEFAULT_prsDispTh 16
71255 +#define DEFAULT_plcrDispTh 16
71256 +#define DEFAULT_kgDispTh 16
71257 +#define DEFAULT_bmiDispTh 16
71258 +#define DEFAULT_qmiEnqDispTh 16
71259 +#define DEFAULT_qmiDeqDispTh 16
71260 +#define DEFAULT_fmCtl1DispTh 16
71261 +#define DEFAULT_fmCtl2DispTh 16
71262 +#endif /* (DPAA_VERSION < 11) */
71263 +
71264 +#define FM_TIMESTAMP_1_USEC_BIT 8
71265 +
71266 +/**************************************************************************//**
71267 + @Collection Defines used for enabling/disabling FM interrupts
71268 + @{
71269 +*//***************************************************************************/
71270 +#define ERR_INTR_EN_DMA 0x00010000
71271 +#define ERR_INTR_EN_FPM 0x80000000
71272 +#define ERR_INTR_EN_BMI 0x00800000
71273 +#define ERR_INTR_EN_QMI 0x00400000
71274 +#define ERR_INTR_EN_PRS 0x00200000
71275 +#define ERR_INTR_EN_KG 0x00100000
71276 +#define ERR_INTR_EN_PLCR 0x00080000
71277 +#define ERR_INTR_EN_MURAM 0x00040000
71278 +#define ERR_INTR_EN_IRAM 0x00020000
71279 +#define ERR_INTR_EN_10G_MAC0 0x00008000
71280 +#define ERR_INTR_EN_10G_MAC1 0x00000040
71281 +#define ERR_INTR_EN_1G_MAC0 0x00004000
71282 +#define ERR_INTR_EN_1G_MAC1 0x00002000
71283 +#define ERR_INTR_EN_1G_MAC2 0x00001000
71284 +#define ERR_INTR_EN_1G_MAC3 0x00000800
71285 +#define ERR_INTR_EN_1G_MAC4 0x00000400
71286 +#define ERR_INTR_EN_1G_MAC5 0x00000200
71287 +#define ERR_INTR_EN_1G_MAC6 0x00000100
71288 +#define ERR_INTR_EN_1G_MAC7 0x00000080
71289 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
71290 +
71291 +#define INTR_EN_QMI 0x40000000
71292 +#define INTR_EN_PRS 0x20000000
71293 +#define INTR_EN_WAKEUP 0x10000000
71294 +#define INTR_EN_PLCR 0x08000000
71295 +#define INTR_EN_1G_MAC0 0x00080000
71296 +#define INTR_EN_1G_MAC1 0x00040000
71297 +#define INTR_EN_1G_MAC2 0x00020000
71298 +#define INTR_EN_1G_MAC3 0x00010000
71299 +#define INTR_EN_1G_MAC4 0x00000040
71300 +#define INTR_EN_1G_MAC5 0x00000020
71301 +#define INTR_EN_1G_MAC6 0x00000008
71302 +#define INTR_EN_1G_MAC7 0x00000002
71303 +#define INTR_EN_10G_MAC0 0x00200000
71304 +#define INTR_EN_10G_MAC1 0x00100000
71305 +#define INTR_EN_REV0 0x00008000
71306 +#define INTR_EN_REV1 0x00004000
71307 +#define INTR_EN_REV2 0x00002000
71308 +#define INTR_EN_REV3 0x00001000
71309 +#define INTR_EN_BRK 0x00000080
71310 +#define INTR_EN_TMR 0x01000000
71311 +#define INTR_EN_MACSEC_MAC0 0x00000001
71312 +/* @} */
71313 +
71314 +/**************************************************************************//**
71315 + @Description Memory Mapped Registers
71316 +*//***************************************************************************/
71317 +
71318 +#if defined(__MWERKS__) && !defined(__GNUC__)
71319 +#pragma pack(push,1)
71320 +#endif /* defined(__MWERKS__) && ... */
71321 +
71322 +typedef struct
71323 +{
71324 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
71325 + volatile uint32_t idata; /**< FM IRAM instruction data register */
71326 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
71327 + volatile uint32_t iready; /**< FM IRAM ready register */
71328 + volatile uint32_t res[0x1FFFC];
71329 +} t_FMIramRegs;
71330 +
71331 +/* Trace buffer registers -
71332 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
71333 +typedef struct t_FmTrbRegs
71334 +{
71335 + volatile uint32_t tcrh;
71336 + volatile uint32_t tcrl;
71337 + volatile uint32_t tesr;
71338 + volatile uint32_t tecr0h;
71339 + volatile uint32_t tecr0l;
71340 + volatile uint32_t terf0h;
71341 + volatile uint32_t terf0l;
71342 + volatile uint32_t tecr1h;
71343 + volatile uint32_t tecr1l;
71344 + volatile uint32_t terf1h;
71345 + volatile uint32_t terf1l;
71346 + volatile uint32_t tpcch;
71347 + volatile uint32_t tpccl;
71348 + volatile uint32_t tpc1h;
71349 + volatile uint32_t tpc1l;
71350 + volatile uint32_t tpc2h;
71351 + volatile uint32_t tpc2l;
71352 + volatile uint32_t twdimr;
71353 + volatile uint32_t twicvr;
71354 + volatile uint32_t tar;
71355 + volatile uint32_t tdr;
71356 + volatile uint32_t tsnum1;
71357 + volatile uint32_t tsnum2;
71358 + volatile uint32_t tsnum3;
71359 + volatile uint32_t tsnum4;
71360 +} t_FmTrbRegs;
71361 +
71362 +#if defined(__MWERKS__) && !defined(__GNUC__)
71363 +#pragma pack(pop)
71364 +#endif /* defined(__MWERKS__) && ... */
71365 +
71366 +/**************************************************************************//**
71367 + @Description General defines
71368 +*//***************************************************************************/
71369 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
71370 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
71371 +
71372 +/**************************************************************************//**
71373 + @Description FPM defines
71374 +*//***************************************************************************/
71375 +/* masks */
71376 +#define FPM_BRKC_RDBG 0x00000200
71377 +#define FPM_BRKC_SLP 0x00000800
71378 +/**************************************************************************//**
71379 + @Description BMI defines
71380 +*//***************************************************************************/
71381 +/* masks */
71382 +#define BMI_INIT_START 0x80000000
71383 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
71384 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
71385 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
71386 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
71387 +/**************************************************************************//**
71388 + @Description QMI defines
71389 +*//***************************************************************************/
71390 +/* masks */
71391 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
71392 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
71393 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
71394 +
71395 +/**************************************************************************//**
71396 + @Description IRAM defines
71397 +*//***************************************************************************/
71398 +/* masks */
71399 +#define IRAM_IADD_AIE 0x80000000
71400 +#define IRAM_READY 0x80000000
71401 +
71402 +/**************************************************************************//**
71403 + @Description TRB defines
71404 +*//***************************************************************************/
71405 +/* masks */
71406 +#define TRB_TCRH_RESET 0x04000000
71407 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
71408 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
71409 +#define TRB_TCRL_RESET 0x20000000
71410 +#define TRB_TCRL_UTIL 0x00000460
71411 +typedef struct {
71412 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
71413 + t_Handle h_SrcHandle;
71414 +} t_FmanCtrlIntrSrc;
71415 +
71416 +
71417 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
71418 +
71419 +typedef struct
71420 +{
71421 +/***************************/
71422 +/* Master/Guest parameters */
71423 +/***************************/
71424 + uint8_t fmId;
71425 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
71426 + uint16_t fmClkFreq;
71427 + uint16_t fmMacClkFreq;
71428 + t_FmRevisionInfo revInfo;
71429 +/**************************/
71430 +/* Master Only parameters */
71431 +/**************************/
71432 + bool enabledTimeStamp;
71433 + uint8_t count1MicroBit;
71434 + uint8_t totalNumOfTasks;
71435 + uint32_t totalFifoSize;
71436 + uint8_t maxNumOfOpenDmas;
71437 + uint8_t accumulatedNumOfTasks;
71438 + uint32_t accumulatedFifoSize;
71439 + uint8_t accumulatedNumOfOpenDmas;
71440 + uint8_t accumulatedNumOfDeqTnums;
71441 +#ifdef FM_LOW_END_RESTRICTION
71442 + bool lowEndRestriction;
71443 +#endif /* FM_LOW_END_RESTRICTION */
71444 + uint32_t exceptions;
71445 + int irq;
71446 + int errIrq;
71447 + bool ramsEccEnable;
71448 + bool explicitEnable;
71449 + bool internalCall;
71450 + uint8_t ramsEccOwners;
71451 + uint32_t extraFifoPoolSize;
71452 + uint8_t extraTasksPoolSize;
71453 + uint8_t extraOpenDmasPoolSize;
71454 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
71455 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
71456 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
71457 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
71458 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
71459 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
71460 +} t_FmStateStruct;
71461 +
71462 +#if (DPAA_VERSION >= 11)
71463 +typedef struct t_FmMapParam {
71464 + uint16_t profilesBase;
71465 + uint16_t numOfProfiles;
71466 + t_Handle h_FmPort;
71467 +} t_FmMapParam;
71468 +
71469 +typedef struct t_FmAllocMng {
71470 + bool allocated;
71471 + uint8_t ownerId; /* guestId for KG in multi-partition only,
71472 + portId for PLCR in any environment */
71473 +} t_FmAllocMng;
71474 +
71475 +typedef struct t_FmPcdSpEntry {
71476 + bool valid;
71477 + t_FmAllocMng profilesMng;
71478 +} t_FmPcdSpEntry;
71479 +
71480 +typedef struct t_FmSp {
71481 + void *p_FmPcdStoragePrflRegs;
71482 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
71483 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
71484 +} t_FmSp;
71485 +#endif /* (DPAA_VERSION >= 11) */
71486 +
71487 +typedef struct t_Fm
71488 +{
71489 +/***************************/
71490 +/* Master/Guest parameters */
71491 +/***************************/
71492 +/* locals for recovery */
71493 + uintptr_t baseAddr;
71494 +
71495 +/* un-needed for recovery */
71496 + t_Handle h_Pcd;
71497 + char fmModuleName[MODULE_NAME_SIZE];
71498 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
71499 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
71500 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
71501 + uint8_t guestId;
71502 +/**************************/
71503 +/* Master Only parameters */
71504 +/**************************/
71505 +/* locals for recovery */
71506 + struct fman_fpm_regs *p_FmFpmRegs;
71507 + struct fman_bmi_regs *p_FmBmiRegs;
71508 + struct fman_qmi_regs *p_FmQmiRegs;
71509 + struct fman_dma_regs *p_FmDmaRegs;
71510 + struct fman_regs *p_FmRegs;
71511 + t_FmExceptionsCallback *f_Exception;
71512 + t_FmBusErrorCallback *f_BusError;
71513 + t_Handle h_App; /* Application handle */
71514 + t_Handle h_Spinlock;
71515 + bool recoveryMode;
71516 + t_FmStateStruct *p_FmStateStruct;
71517 + uint16_t tnumAgingPeriod;
71518 +#if (DPAA_VERSION >= 11)
71519 + t_FmSp *p_FmSp;
71520 + uint8_t partNumOfVSPs;
71521 + uint8_t partVSPBase;
71522 + uintptr_t vspBaseAddr;
71523 +#endif /* (DPAA_VERSION >= 11) */
71524 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
71525 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
71526 +
71527 +/* un-needed for recovery */
71528 + struct fman_cfg *p_FmDriverParam;
71529 + t_Handle h_FmMuram;
71530 + uint64_t fmMuramPhysBaseAddr;
71531 + bool independentMode;
71532 + bool hcPortInitialized;
71533 + uintptr_t camBaseAddr; /* save for freeing */
71534 + uintptr_t resAddr;
71535 + uintptr_t fifoBaseAddr; /* save for freeing */
71536 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
71537 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
71538 + t_FmFirmwareParams firmware;
71539 + bool fwVerify;
71540 + bool resetOnInit;
71541 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
71542 + uint32_t userSetExceptions;
71543 +} t_Fm;
71544 +
71545 +
71546 +#endif /* __FM_H */
71547 --- /dev/null
71548 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
71549 @@ -0,0 +1,465 @@
71550 +/*
71551 + * Copyright 2008-2012 Freescale Semiconductor Inc.
71552 + *
71553 + * Redistribution and use in source and binary forms, with or without
71554 + * modification, are permitted provided that the following conditions are met:
71555 + * * Redistributions of source code must retain the above copyright
71556 + * notice, this list of conditions and the following disclaimer.
71557 + * * Redistributions in binary form must reproduce the above copyright
71558 + * notice, this list of conditions and the following disclaimer in the
71559 + * documentation and/or other materials provided with the distribution.
71560 + * * Neither the name of Freescale Semiconductor nor the
71561 + * names of its contributors may be used to endorse or promote products
71562 + * derived from this software without specific prior written permission.
71563 + *
71564 + *
71565 + * ALTERNATIVELY, this software may be distributed under the terms of the
71566 + * GNU General Public License ("GPL") as published by the Free Software
71567 + * Foundation, either version 2 of that License or (at your option) any
71568 + * later version.
71569 + *
71570 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
71571 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
71572 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71573 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
71574 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
71575 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
71576 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
71577 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71578 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
71579 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71580 + */
71581 +
71582 +
71583 +/**************************************************************************//**
71584 + @File fm_ipc.h
71585 +
71586 + @Description FM Inter-Partition prototypes, structures and definitions.
71587 +*//***************************************************************************/
71588 +#ifndef __FM_IPC_H
71589 +#define __FM_IPC_H
71590 +
71591 +#include "error_ext.h"
71592 +#include "std_ext.h"
71593 +
71594 +
71595 +/**************************************************************************//**
71596 + @Group FM_grp Frame Manager API
71597 +
71598 + @Description FM API functions, definitions and enums
71599 +
71600 + @{
71601 +*//***************************************************************************/
71602 +
71603 +/**************************************************************************//**
71604 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
71605 +
71606 + @Description FM Inter-Partition messaging unit API definitions and enums.
71607 +
71608 + @{
71609 +*//***************************************************************************/
71610 +
71611 +#if defined(__MWERKS__) && !defined(__GNUC__)
71612 +#pragma pack(push,1)
71613 +#endif /* defined(__MWERKS__) && ... */
71614 +
71615 +/**************************************************************************//**
71616 + @Description enum for defining MAC types
71617 +*//***************************************************************************/
71618 +
71619 +/**************************************************************************//**
71620 + @Description A structure of parameters for specifying a MAC.
71621 +*//***************************************************************************/
71622 +typedef _Packed struct
71623 +{
71624 + uint8_t id;
71625 + uint32_t enumType;
71626 +} _PackedType t_FmIpcMacParams;
71627 +
71628 +/**************************************************************************//**
71629 + @Description A structure of parameters for specifying a MAC.
71630 +*//***************************************************************************/
71631 +typedef _Packed struct
71632 +{
71633 + t_FmIpcMacParams macParams;
71634 + uint16_t maxFrameLength;
71635 +} _PackedType t_FmIpcMacMaxFrameParams;
71636 +
71637 +/**************************************************************************//**
71638 + @Description FM physical Address
71639 +*//***************************************************************************/
71640 +typedef _Packed struct t_FmIpcPhysAddr
71641 +{
71642 + volatile uint8_t high;
71643 + volatile uint32_t low;
71644 +} _PackedType t_FmIpcPhysAddr;
71645 +
71646 +
71647 +typedef _Packed struct t_FmIpcPortOutInitParams {
71648 + uint8_t numOfTasks; /**< OUT */
71649 + uint8_t numOfExtraTasks; /**< OUT */
71650 + uint8_t numOfOpenDmas; /**< OUT */
71651 + uint8_t numOfExtraOpenDmas; /**< OUT */
71652 + uint32_t sizeOfFifo; /**< OUT */
71653 + uint32_t extraSizeOfFifo; /**< OUT */
71654 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
71655 +} _PackedType t_FmIpcPortOutInitParams;
71656 +
71657 +/**************************************************************************//**
71658 + @Description Structure for IPC communication during FM_PORT_Init.
71659 +*//***************************************************************************/
71660 +typedef _Packed struct t_FmIpcPortInInitParams {
71661 + uint8_t hardwarePortId; /**< IN. port Id */
71662 + uint32_t enumPortType; /**< IN. Port type */
71663 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
71664 + uint16_t liodnOffset; /**< IN. Port's requested resource */
71665 + uint8_t numOfTasks; /**< IN. Port's requested resource */
71666 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
71667 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
71668 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
71669 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
71670 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
71671 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
71672 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
71673 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
71674 + LIODN base for this port, to be
71675 + used together with LIODN offset. */
71676 +} _PackedType t_FmIpcPortInInitParams;
71677 +
71678 +
71679 +/**************************************************************************//**
71680 + @Description Structure for IPC communication between port and FM
71681 + regarding tasks and open DMA resources management.
71682 +*//***************************************************************************/
71683 +typedef _Packed struct t_FmIpcPortRsrcParams {
71684 + uint8_t hardwarePortId; /**< IN. port Id */
71685 + uint32_t val; /**< IN. Port's requested resource */
71686 + uint32_t extra; /**< IN. Port's requested resource */
71687 + uint8_t boolInitialConfig;
71688 +} _PackedType t_FmIpcPortRsrcParams;
71689 +
71690 +
71691 +/**************************************************************************//**
71692 + @Description Structure for IPC communication between port and FM
71693 + regarding tasks and open DMA resources management.
71694 +*//***************************************************************************/
71695 +typedef _Packed struct t_FmIpcPortFifoParams {
71696 + t_FmIpcPortRsrcParams rsrcParams;
71697 + uint32_t enumPortType;
71698 + uint8_t boolIndependentMode;
71699 + uint8_t deqPipelineDepth;
71700 + uint8_t numOfPools;
71701 + uint16_t secondLargestBufSize;
71702 + uint16_t largestBufSize;
71703 + uint8_t boolInitialConfig;
71704 +} _PackedType t_FmIpcPortFifoParams;
71705 +
71706 +/**************************************************************************//**
71707 + @Description Structure for port-FM communication during FM_PORT_Free.
71708 +*//***************************************************************************/
71709 +typedef _Packed struct t_FmIpcPortFreeParams {
71710 + uint8_t hardwarePortId; /**< IN. port Id */
71711 + uint32_t enumPortType; /**< IN. Port type */
71712 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
71713 +} _PackedType t_FmIpcPortFreeParams;
71714 +
71715 +/**************************************************************************//**
71716 + @Description Structure for defining DMA status
71717 +*//***************************************************************************/
71718 +typedef _Packed struct t_FmIpcDmaStatus {
71719 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
71720 + uint8_t boolBusError; /**< Bus error occurred */
71721 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
71722 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
71723 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
71724 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
71725 +} _PackedType t_FmIpcDmaStatus;
71726 +
71727 +typedef _Packed struct t_FmIpcRegisterIntr
71728 +{
71729 + uint8_t guestId; /* IN */
71730 + uint32_t event; /* IN */
71731 +} _PackedType t_FmIpcRegisterIntr;
71732 +
71733 +typedef _Packed struct t_FmIpcIsr
71734 +{
71735 + uint8_t boolErr; /* IN */
71736 + uint32_t pendingReg; /* IN */
71737 +} _PackedType t_FmIpcIsr;
71738 +
71739 +/**************************************************************************//**
71740 + @Description structure for returning FM parameters
71741 +*//***************************************************************************/
71742 +typedef _Packed struct t_FmIpcParams {
71743 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
71744 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
71745 + uint8_t majorRev; /**< OUT: FM Major revision */
71746 + uint8_t minorRev; /**< OUT: FM Minor revision */
71747 +} _PackedType t_FmIpcParams;
71748 +
71749 +
71750 +/**************************************************************************//**
71751 + @Description structure for returning Fman Ctrl Code revision information
71752 +*//***************************************************************************/
71753 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
71754 + uint16_t packageRev; /**< OUT: Package revision */
71755 + uint8_t majorRev; /**< OUT: Major revision */
71756 + uint8_t minorRev; /**< OUT: Minor revision */
71757 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
71758 +
71759 +/**************************************************************************//**
71760 + @Description Structure for defining Fm number of Fman controlers
71761 +*//***************************************************************************/
71762 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
71763 + uint8_t hardwarePortId; /**< IN. port Id */
71764 + uint8_t numOfFmanCtrls; /**< IN. Port type */
71765 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
71766 +} t_FmIpcPortNumOfFmanCtrls;
71767 +
71768 +/**************************************************************************//**
71769 + @Description structure for setting Fman contriller events
71770 +*//***************************************************************************/
71771 +typedef _Packed struct t_FmIpcFmanEvents {
71772 + uint8_t eventRegId; /**< IN: Fman controller event register id */
71773 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
71774 +} _PackedType t_FmIpcFmanEvents;
71775 +
71776 +typedef _Packed struct t_FmIpcResourceAllocParams {
71777 + uint8_t guestId;
71778 + uint16_t base;
71779 + uint16_t num;
71780 +}_PackedType t_FmIpcResourceAllocParams;
71781 +
71782 +typedef _Packed struct t_FmIpcVspSetPortWindow {
71783 + uint8_t hardwarePortId;
71784 + uint8_t baseStorageProfile;
71785 + uint8_t log2NumOfProfiles;
71786 +}_PackedType t_FmIpcVspSetPortWindow;
71787 +
71788 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
71789 + uint32_t congestionGroupId;
71790 + uint8_t priorityBitMap;
71791 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
71792 +
71793 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
71794 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
71795 +#define FM_IPC_MAX_MSG_SIZE 30
71796 +
71797 +typedef _Packed struct t_FmIpcMsg
71798 +{
71799 + uint32_t msgId;
71800 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
71801 +} _PackedType t_FmIpcMsg;
71802 +
71803 +typedef _Packed struct t_FmIpcReply
71804 +{
71805 + uint32_t error;
71806 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
71807 +} _PackedType t_FmIpcReply;
71808 +
71809 +#if defined(__MWERKS__) && !defined(__GNUC__)
71810 +#pragma pack(pop)
71811 +#endif /* defined(__MWERKS__) && ... */
71812 +
71813 +
71814 +/***************************************************************************/
71815 +/************************ FRONT-END-TO-BACK-END*****************************/
71816 +/***************************************************************************/
71817 +
71818 +/**************************************************************************//**
71819 + @Function FM_GET_TIMESTAMP_SCALE
71820 +
71821 + @Description Used by FM front-end.
71822 +
71823 + @Param[out] uint32_t Pointer
71824 +*//***************************************************************************/
71825 +#define FM_GET_TIMESTAMP_SCALE 1
71826 +
71827 +/**************************************************************************//**
71828 + @Function FM_GET_COUNTER
71829 +
71830 + @Description Used by FM front-end.
71831 +
71832 + @Param[in/out] t_FmIpcGetCounter Pointer
71833 +*//***************************************************************************/
71834 +#define FM_GET_COUNTER 2
71835 +
71836 +/**************************************************************************//**
71837 + @Function FM_GET_SET_PORT_PARAMS
71838 +
71839 + @Description Used by FM front-end for the PORT module in order to set and get
71840 + parameters in/from master FM module on FM PORT initialization time.
71841 +
71842 + @Param[in/out] t_FmIcPortInitParams Pointer
71843 +*//***************************************************************************/
71844 +#define FM_GET_SET_PORT_PARAMS 4
71845 +
71846 +/**************************************************************************//**
71847 + @Function FM_FREE_PORT
71848 +
71849 + @Description Used by FM front-end for the PORT module when a port is freed
71850 + to free all FM PORT resources.
71851 +
71852 + @Param[in] uint8_t Pointer
71853 +*//***************************************************************************/
71854 +#define FM_FREE_PORT 5
71855 +
71856 +/**************************************************************************//**
71857 + @Function FM_RESET_MAC
71858 +
71859 + @Description Used by front-end for the MAC module to reset the MAC registers
71860 +
71861 + @Param[in] t_FmIpcMacParams Pointer .
71862 +*//***************************************************************************/
71863 +#define FM_RESET_MAC 6
71864 +
71865 +/**************************************************************************//**
71866 + @Function FM_RESUME_STALLED_PORT
71867 +
71868 + @Description Used by FM front-end for the PORT module in order to
71869 + release a stalled FM Port.
71870 +
71871 + @Param[in] uint8_t Pointer
71872 +*//***************************************************************************/
71873 +#define FM_RESUME_STALLED_PORT 7
71874 +
71875 +/**************************************************************************//**
71876 + @Function FM_IS_PORT_STALLED
71877 +
71878 + @Description Used by FM front-end for the PORT module in order to check whether
71879 + an FM port is stalled.
71880 +
71881 + @Param[in/out] t_FmIcPortIsStalled Pointer
71882 +*//***************************************************************************/
71883 +#define FM_IS_PORT_STALLED 8
71884 +
71885 +/**************************************************************************//**
71886 + @Function FM_GET_PARAMS
71887 +
71888 + @Description Used by FM front-end for the PORT module in order to dump
71889 + return FM parameters.
71890 +
71891 + @Param[in] uint8_t Pointer
71892 +*//***************************************************************************/
71893 +#define FM_GET_PARAMS 10
71894 +
71895 +/**************************************************************************//**
71896 + @Function FM_REGISTER_INTR
71897 +
71898 + @Description Used by FM front-end to register an interrupt handler to
71899 + be called upon interrupt for guest.
71900 +
71901 + @Param[out] t_FmIpcRegisterIntr Pointer
71902 +*//***************************************************************************/
71903 +#define FM_REGISTER_INTR 11
71904 +
71905 +/**************************************************************************//**
71906 + @Function FM_DMA_STAT
71907 +
71908 + @Description Used by FM front-end to read the FM DMA status.
71909 +
71910 + @Param[out] t_FmIpcDmaStatus Pointer
71911 +*//***************************************************************************/
71912 +#define FM_DMA_STAT 13
71913 +
71914 +/**************************************************************************//**
71915 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
71916 +
71917 + @Description Used by FM front-end to allocate event register.
71918 +
71919 + @Param[out] Event register id Pointer
71920 +*//***************************************************************************/
71921 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
71922 +
71923 +/**************************************************************************//**
71924 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
71925 +
71926 + @Description Used by FM front-end to free locate event register.
71927 +
71928 + @Param[in] uint8_t Pointer - Event register id
71929 +*//***************************************************************************/
71930 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
71931 +
71932 +/**************************************************************************//**
71933 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
71934 +
71935 + @Description Used by FM front-end to enable events in the FPM
71936 + Fman controller event register.
71937 +
71938 + @Param[in] t_FmIpcFmanEvents Pointer
71939 +*//***************************************************************************/
71940 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
71941 +
71942 +/**************************************************************************//**
71943 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
71944 +
71945 + @Description Used by FM front-end to enable events in the FPM
71946 + Fman controller event register.
71947 +
71948 + @Param[in/out] t_FmIpcFmanEvents Pointer
71949 +*//***************************************************************************/
71950 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
71951 +
71952 +/**************************************************************************//**
71953 + @Function FM_SET_MAC_MAX_FRAME
71954 +
71955 + @Description Used by FM front-end to set MAC's MTU/RTU's in
71956 + back-end.
71957 +
71958 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
71959 +*//***************************************************************************/
71960 +#define FM_SET_MAC_MAX_FRAME 18
71961 +
71962 +/**************************************************************************//**
71963 + @Function FM_GET_PHYS_MURAM_BASE
71964 +
71965 + @Description Used by FM front-end in order to get MURAM base address
71966 +
71967 + @Param[in/out] t_FmIpcPhysAddr Pointer
71968 +*//***************************************************************************/
71969 +#define FM_GET_PHYS_MURAM_BASE 19
71970 +
71971 +/**************************************************************************//**
71972 + @Function FM_MASTER_IS_ALIVE
71973 +
71974 + @Description Used by FM front-end in order to verify Master is up
71975 +
71976 + @Param[in/out] bool
71977 +*//***************************************************************************/
71978 +#define FM_MASTER_IS_ALIVE 20
71979 +
71980 +#define FM_ENABLE_RAM_ECC 21
71981 +#define FM_DISABLE_RAM_ECC 22
71982 +#define FM_SET_NUM_OF_FMAN_CTRL 23
71983 +#define FM_SET_SIZE_OF_FIFO 24
71984 +#define FM_SET_NUM_OF_TASKS 25
71985 +#define FM_SET_NUM_OF_OPEN_DMAS 26
71986 +#define FM_VSP_ALLOC 27
71987 +#define FM_VSP_FREE 28
71988 +#define FM_VSP_SET_PORT_WINDOW 29
71989 +#define FM_GET_FMAN_CTRL_CODE_REV 30
71990 +#define FM_SET_CONG_GRP_PFC_PRIO 31
71991 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
71992 +#define FM_10G_TX_ECC_WA 100
71993 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
71994 +
71995 +/***************************************************************************/
71996 +/************************ BACK-END-TO-FRONT-END*****************************/
71997 +/***************************************************************************/
71998 +
71999 +/**************************************************************************//**
72000 + @Function FM_GUEST_ISR
72001 +
72002 + @Description Used by FM back-end to report an interrupt to the front-end.
72003 +
72004 + @Param[out] t_FmIpcIsr Pointer
72005 +*//***************************************************************************/
72006 +#define FM_GUEST_ISR 1
72007 +
72008 +
72009 +
72010 +/** @} */ /* end of FM_IPC_grp group */
72011 +/** @} */ /* end of FM_grp group */
72012 +
72013 +
72014 +#endif /* __FM_IPC_H */
72015 --- /dev/null
72016 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
72017 @@ -0,0 +1,174 @@
72018 +/*
72019 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72020 + *
72021 + * Redistribution and use in source and binary forms, with or without
72022 + * modification, are permitted provided that the following conditions are met:
72023 + * * Redistributions of source code must retain the above copyright
72024 + * notice, this list of conditions and the following disclaimer.
72025 + * * Redistributions in binary form must reproduce the above copyright
72026 + * notice, this list of conditions and the following disclaimer in the
72027 + * documentation and/or other materials provided with the distribution.
72028 + * * Neither the name of Freescale Semiconductor nor the
72029 + * names of its contributors may be used to endorse or promote products
72030 + * derived from this software without specific prior written permission.
72031 + *
72032 + *
72033 + * ALTERNATIVELY, this software may be distributed under the terms of the
72034 + * GNU General Public License ("GPL") as published by the Free Software
72035 + * Foundation, either version 2 of that License or (at your option) any
72036 + * later version.
72037 + *
72038 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72039 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72040 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72041 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72042 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72043 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72044 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72045 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72046 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72047 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72048 + */
72049 +
72050 +
72051 +/******************************************************************************
72052 + @File FM_muram.c
72053 +
72054 + @Description FM MURAM ...
72055 +*//***************************************************************************/
72056 +#include "error_ext.h"
72057 +#include "std_ext.h"
72058 +#include "mm_ext.h"
72059 +#include "string_ext.h"
72060 +#include "sprint_ext.h"
72061 +#include "fm_muram_ext.h"
72062 +#include "fm_common.h"
72063 +
72064 +#define __ERR_MODULE__ MODULE_FM_MURAM
72065 +
72066 +
72067 +typedef struct
72068 +{
72069 + t_Handle h_Mem;
72070 + uintptr_t baseAddr;
72071 + uint32_t size;
72072 +} t_FmMuram;
72073 +
72074 +
72075 +void FmMuramClear(t_Handle h_FmMuram)
72076 +{
72077 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72078 +
72079 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
72080 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
72081 +}
72082 +
72083 +
72084 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
72085 +{
72086 + t_Handle h_Mem;
72087 + t_FmMuram *p_FmMuram;
72088 +
72089 + if (!baseAddress)
72090 + {
72091 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
72092 + return NULL;
72093 + }
72094 +
72095 + if (baseAddress%4)
72096 + {
72097 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
72098 + return NULL;
72099 + }
72100 +
72101 + /* Allocate FM MURAM structure */
72102 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
72103 + if (!p_FmMuram)
72104 + {
72105 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
72106 + return NULL;
72107 + }
72108 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
72109 +
72110 +
72111 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
72112 + {
72113 + XX_Free(p_FmMuram);
72114 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
72115 + return NULL;
72116 + }
72117 +
72118 + /* Initialize FM MURAM parameters which will be kept by the driver */
72119 + p_FmMuram->baseAddr = baseAddress;
72120 + p_FmMuram->size = size;
72121 + p_FmMuram->h_Mem = h_Mem;
72122 +
72123 + return p_FmMuram;
72124 +}
72125 +
72126 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
72127 +{
72128 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72129 +
72130 + if (p_FmMuram->h_Mem)
72131 + MM_Free(p_FmMuram->h_Mem);
72132 +
72133 + XX_Free(h_FmMuram);
72134 +
72135 + return E_OK;
72136 +}
72137 +
72138 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
72139 +{
72140 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72141 + uintptr_t addr;
72142 +
72143 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
72144 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
72145 +
72146 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
72147 +
72148 + if (addr == ILLEGAL_BASE)
72149 + return NULL;
72150 +
72151 + return UINT_TO_PTR(addr);
72152 +}
72153 +
72154 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
72155 +{
72156 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72157 + uintptr_t addr;
72158 +
72159 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
72160 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
72161 +
72162 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
72163 +
72164 + if (addr == ILLEGAL_BASE)
72165 + return NULL;
72166 +
72167 + return UINT_TO_PTR(addr);
72168 +}
72169 +
72170 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
72171 +{
72172 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72173 +
72174 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
72175 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
72176 +
72177 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
72178 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
72179 +
72180 + return E_OK;
72181 +}
72182 +
72183 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
72184 +{
72185 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72186 +
72187 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
72188 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
72189 +
72190 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
72191 +}
72192 --- /dev/null
72193 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
72194 @@ -0,0 +1,1400 @@
72195 +/*
72196 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72197 + *
72198 + * Redistribution and use in source and binary forms, with or without
72199 + * modification, are permitted provided that the following conditions are met:
72200 + * * Redistributions of source code must retain the above copyright
72201 + * notice, this list of conditions and the following disclaimer.
72202 + * * Redistributions in binary form must reproduce the above copyright
72203 + * notice, this list of conditions and the following disclaimer in the
72204 + * documentation and/or other materials provided with the distribution.
72205 + * * Neither the name of Freescale Semiconductor nor the
72206 + * names of its contributors may be used to endorse or promote products
72207 + * derived from this software without specific prior written permission.
72208 + *
72209 + *
72210 + * ALTERNATIVELY, this software may be distributed under the terms of the
72211 + * GNU General Public License ("GPL") as published by the Free Software
72212 + * Foundation, either version 2 of that License or (at your option) any
72213 + * later version.
72214 + *
72215 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72216 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72217 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72218 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72219 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72220 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72221 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72222 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72223 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72224 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72225 + */
72226 +
72227 +
72228 +#include "std_ext.h"
72229 +#include "error_ext.h"
72230 +#include <linux/math64.h>
72231 +#include "fsl_fman.h"
72232 +#include "dpaa_integration_ext.h"
72233 +
72234 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
72235 +{
72236 + uint32_t event, mask, force;
72237 +
72238 + event = ioread32be(&bmi_rg->fmbm_ievr);
72239 + mask = ioread32be(&bmi_rg->fmbm_ier);
72240 + event &= mask;
72241 + /* clear the forced events */
72242 + force = ioread32be(&bmi_rg->fmbm_ifr);
72243 + if (force & event)
72244 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
72245 + /* clear the acknowledged events */
72246 + iowrite32be(event, &bmi_rg->fmbm_ievr);
72247 + return event;
72248 +}
72249 +
72250 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
72251 +{
72252 + uint32_t event, mask, force;
72253 +
72254 + event = ioread32be(&qmi_rg->fmqm_eie);
72255 + mask = ioread32be(&qmi_rg->fmqm_eien);
72256 + event &= mask;
72257 +
72258 + /* clear the forced events */
72259 + force = ioread32be(&qmi_rg->fmqm_eif);
72260 + if (force & event)
72261 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
72262 + /* clear the acknowledged events */
72263 + iowrite32be(event, &qmi_rg->fmqm_eie);
72264 + return event;
72265 +}
72266 +
72267 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
72268 +{
72269 + return ioread32be(&dma_rg->fmdmtcid);
72270 +}
72271 +
72272 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
72273 +{
72274 + uint64_t addr;
72275 +
72276 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
72277 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
72278 +
72279 + return addr;
72280 +}
72281 +
72282 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
72283 +{
72284 + uint32_t status, mask;
72285 +
72286 + status = ioread32be(&dma_rg->fmdmsr);
72287 + mask = ioread32be(&dma_rg->fmdmmr);
72288 +
72289 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
72290 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
72291 + status &= ~DMA_STATUS_BUS_ERR;
72292 +
72293 + /* clear relevant bits if mask has no DMA_MODE_ECC */
72294 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
72295 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
72296 + DMA_STATUS_READ_ECC |
72297 + DMA_STATUS_SYSTEM_WRITE_ECC |
72298 + DMA_STATUS_FM_WRITE_ECC);
72299 +
72300 + /* clear set events */
72301 + iowrite32be(status, &dma_rg->fmdmsr);
72302 +
72303 + return status;
72304 +}
72305 +
72306 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
72307 +{
72308 + uint32_t event;
72309 +
72310 + event = ioread32be(&fpm_rg->fmfp_ee);
72311 + /* clear the all occurred events */
72312 + iowrite32be(event, &fpm_rg->fmfp_ee);
72313 + return event;
72314 +}
72315 +
72316 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
72317 +{
72318 + uint32_t event, mask;
72319 +
72320 + event = ioread32be(&fpm_rg->fm_rcr);
72321 + mask = ioread32be(&fpm_rg->fm_rie);
72322 +
72323 + /* clear MURAM event bit (do not clear IRAM event) */
72324 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
72325 +
72326 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
72327 + return event;
72328 + else
72329 + return 0;
72330 +}
72331 +
72332 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
72333 +{
72334 + uint32_t event, mask;
72335 +
72336 + event = ioread32be(&fpm_rg->fm_rcr) ;
72337 + mask = ioread32be(&fpm_rg->fm_rie);
72338 + /* clear IRAM event bit (do not clear MURAM event) */
72339 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
72340 + &fpm_rg->fm_rcr);
72341 +
72342 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
72343 + return event;
72344 + else
72345 + return 0;
72346 +}
72347 +
72348 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
72349 +{
72350 + uint32_t event, mask, force;
72351 +
72352 + event = ioread32be(&qmi_rg->fmqm_ie);
72353 + mask = ioread32be(&qmi_rg->fmqm_ien);
72354 + event &= mask;
72355 + /* clear the forced events */
72356 + force = ioread32be(&qmi_rg->fmqm_if);
72357 + if (force & event)
72358 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
72359 + /* clear the acknowledged events */
72360 + iowrite32be(event, &qmi_rg->fmqm_ie);
72361 + return event;
72362 +}
72363 +
72364 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
72365 + uint8_t count1ubit,
72366 + uint16_t fm_clk_freq)
72367 +{
72368 + uint32_t tmp;
72369 + uint64_t frac;
72370 + uint32_t intgr;
72371 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
72372 +
72373 + /* configure timestamp so that bit 8 will count 1 microsecond
72374 + * Find effective count rate at TIMESTAMP least significant bits:
72375 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
72376 + * Find frequency ratio between effective count rate and the clock:
72377 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
72378 + * 256/600 = 0.4266666... */
72379 +
72380 + intgr = ts_freq / fm_clk_freq;
72381 + /* we multiply by 2^16 to keep the fraction of the division
72382 + * we do not div back, since we write this value as a fraction
72383 + * see spec */
72384 +
72385 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
72386 + /* we check remainder of the division in order to round up if not int */
72387 + if (do_div(frac, fm_clk_freq))
72388 + frac++;
72389 +
72390 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
72391 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
72392 +
72393 + /* enable timestamp with original clock */
72394 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
72395 +}
72396 +
72397 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
72398 +{
72399 + return ioread32be(&fpm_rg->fm_epi);
72400 +}
72401 +
72402 +
72403 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
72404 +{
72405 + int timeout = 100;
72406 +
72407 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
72408 +
72409 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
72410 + udelay(10);
72411 +
72412 + if (!timeout)
72413 + return -EBUSY;
72414 + return 0;
72415 +}
72416 +
72417 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
72418 + uint8_t event_reg_id,
72419 + uint32_t enable_events)
72420 +{
72421 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
72422 +}
72423 +
72424 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
72425 +{
72426 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
72427 +}
72428 +
72429 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
72430 + uint8_t port_id,
72431 + uint8_t num_fman_ctrls,
72432 + uint32_t or_fman_ctrl)
72433 +{
72434 + uint32_t tmp = 0;
72435 +
72436 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
72437 + /*TODO - maybe to put CTL# according to another criteria*/
72438 + if (num_fman_ctrls == 2)
72439 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
72440 + /* order restoration */
72441 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
72442 +
72443 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
72444 +}
72445 +
72446 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
72447 + uint8_t port_id,
72448 + bool independent_mode,
72449 + bool is_rx_port)
72450 +{
72451 + uint32_t tmp = 0;
72452 +
72453 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
72454 + if (independent_mode) {
72455 + if (is_rx_port)
72456 + tmp |= (FPM_PRT_FM_CTL1 <<
72457 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
72458 + else
72459 + tmp |= (FPM_PRT_FM_CTL2 <<
72460 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
72461 + } else {
72462 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
72463 +
72464 + /* order restoration */
72465 + if (port_id % 2)
72466 + tmp |= (FPM_PRT_FM_CTL1 <<
72467 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
72468 + else
72469 + tmp |= (FPM_PRT_FM_CTL2 <<
72470 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
72471 + }
72472 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
72473 +}
72474 +
72475 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
72476 +{
72477 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
72478 +}
72479 +
72480 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
72481 +{
72482 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
72483 +}
72484 +
72485 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
72486 +{
72487 + uint32_t tmp_reg;
72488 +
72489 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
72490 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
72491 + tmp_reg |= ((uint32_t)val << 8);
72492 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
72493 +}
72494 +
72495 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
72496 +{
72497 + uint32_t tmp_reg;
72498 +
72499 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
72500 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
72501 + tmp_reg |= (uint32_t)val;
72502 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
72503 +}
72504 +
72505 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
72506 +{
72507 + iowrite32be(0, &fpm_rg->fmfp_mxd);
72508 +}
72509 +
72510 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
72511 + uint16_t liodn_base,
72512 + uint16_t liodn_ofst)
72513 +{
72514 + uint32_t tmp;
72515 +
72516 + if ((port_id > 63) || (port_id < 1))
72517 + return;
72518 +
72519 + /* set LIODN base for this port */
72520 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
72521 + if (port_id % 2) {
72522 + tmp &= ~FM_LIODN_BASE_MASK;
72523 + tmp |= (uint32_t)liodn_base;
72524 + } else {
72525 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
72526 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
72527 + }
72528 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
72529 + iowrite32be((uint32_t)liodn_ofst,
72530 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
72531 +}
72532 +
72533 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
72534 +{
72535 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
72536 +}
72537 +
72538 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
72539 +{
72540 + uint32_t tmp;
72541 +
72542 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
72543 + FPM_PRC_REALSE_STALLED);
72544 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
72545 +}
72546 +
72547 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
72548 +{
72549 + uint32_t msk, timeout = 100;
72550 +
72551 + /* Get the relevant bit mask */
72552 + if (is_10g) {
72553 + switch (mac_id) {
72554 + case(0):
72555 + msk = FPM_RSTC_10G0_RESET;
72556 + break;
72557 + case(1):
72558 + msk = FPM_RSTC_10G1_RESET;
72559 + break;
72560 + default:
72561 + return -EINVAL;
72562 + }
72563 + } else {
72564 + switch (mac_id) {
72565 + case(0):
72566 + msk = FPM_RSTC_1G0_RESET;
72567 + break;
72568 + case(1):
72569 + msk = FPM_RSTC_1G1_RESET;
72570 + break;
72571 + case(2):
72572 + msk = FPM_RSTC_1G2_RESET;
72573 + break;
72574 + case(3):
72575 + msk = FPM_RSTC_1G3_RESET;
72576 + break;
72577 + case(4):
72578 + msk = FPM_RSTC_1G4_RESET;
72579 + break;
72580 + case (5):
72581 + msk = FPM_RSTC_1G5_RESET;
72582 + break;
72583 + case (6):
72584 + msk = FPM_RSTC_1G6_RESET;
72585 + break;
72586 + case (7):
72587 + msk = FPM_RSTC_1G7_RESET;
72588 + break;
72589 + default:
72590 + return -EINVAL;
72591 + }
72592 + }
72593 + /* reset */
72594 + iowrite32be(msk, &fpm_rg->fm_rstc);
72595 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
72596 + udelay(10);
72597 +
72598 + if (!timeout)
72599 + return -EBUSY;
72600 + return 0;
72601 +}
72602 +
72603 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
72604 +{
72605 + uint32_t tmp_reg;
72606 +
72607 + if ((port_id > 63) || (port_id < 1))
72608 + return 0;
72609 +
72610 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
72611 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
72612 +}
72613 +
72614 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
72615 +{
72616 + uint32_t reg, res;
72617 +
72618 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
72619 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
72620 + return res * FMAN_BMI_FIFO_UNITS;
72621 +}
72622 +
72623 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
72624 + uint8_t port_id)
72625 +{
72626 + uint32_t tmp_reg;
72627 +
72628 + if ((port_id > 63) || (port_id < 1))
72629 + return 0;
72630 +
72631 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
72632 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
72633 + BMI_EXTRA_FIFO_SIZE_SHIFT);
72634 +}
72635 +
72636 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
72637 + uint8_t port_id,
72638 + uint32_t sz_fifo,
72639 + uint32_t extra_sz_fifo)
72640 +{
72641 + uint32_t tmp;
72642 +
72643 + if ((port_id > 63) || (port_id < 1))
72644 + return;
72645 +
72646 + /* calculate reg */
72647 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
72648 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
72649 + BMI_EXTRA_FIFO_SIZE_SHIFT));
72650 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
72651 +}
72652 +
72653 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
72654 +{
72655 + uint32_t tmp;
72656 +
72657 + if ((port_id > 63) || (port_id < 1))
72658 + return 0;
72659 +
72660 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
72661 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
72662 + BMI_NUM_OF_TASKS_SHIFT) + 1);
72663 +}
72664 +
72665 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
72666 +{
72667 + uint32_t tmp;
72668 +
72669 + if ((port_id > 63) || (port_id < 1))
72670 + return 0;
72671 +
72672 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
72673 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
72674 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
72675 +}
72676 +
72677 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
72678 + uint8_t port_id,
72679 + uint8_t num_tasks,
72680 + uint8_t num_extra_tasks)
72681 +{
72682 + uint32_t tmp;
72683 +
72684 + if ((port_id > 63) || (port_id < 1))
72685 + return;
72686 +
72687 + /* calculate reg */
72688 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
72689 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
72690 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
72691 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
72692 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
72693 +}
72694 +
72695 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
72696 +{
72697 + uint32_t tmp;
72698 +
72699 + if ((port_id > 63) || (port_id < 1))
72700 + return 0;
72701 +
72702 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
72703 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
72704 + BMI_NUM_OF_DMAS_SHIFT) + 1);
72705 +}
72706 +
72707 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
72708 +{
72709 + uint32_t tmp;
72710 +
72711 + if ((port_id > 63) || (port_id < 1))
72712 + return 0;
72713 +
72714 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
72715 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
72716 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
72717 +}
72718 +
72719 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
72720 + uint8_t port_id,
72721 + uint8_t num_open_dmas,
72722 + uint8_t num_extra_open_dmas,
72723 + uint8_t total_num_dmas)
72724 +{
72725 + uint32_t tmp = 0;
72726 +
72727 + if ((port_id > 63) || (port_id < 1))
72728 + return;
72729 +
72730 + /* calculate reg */
72731 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
72732 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
72733 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
72734 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
72735 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
72736 +
72737 + /* update total num of DMA's with committed number of open DMAS,
72738 + * and max uncommitted pool. */
72739 + if (total_num_dmas)
72740 + {
72741 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
72742 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
72743 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
72744 + }
72745 +}
72746 +
72747 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
72748 + uint8_t port_id,
72749 + uint8_t base_storage_profile,
72750 + uint8_t log2_num_of_profiles)
72751 +{
72752 + uint32_t tmp = 0;
72753 + if ((port_id > 63) || (port_id < 1))
72754 + return;
72755 +
72756 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
72757 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
72758 + tmp |= (uint32_t)log2_num_of_profiles << 28;
72759 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
72760 +}
72761 +
72762 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
72763 + uint32_t congestion_group_id,
72764 + uint8_t priority_bit_map,
72765 + uint32_t reg_num)
72766 +{
72767 + uint32_t offset, tmp = 0;
72768 +
72769 + offset = (congestion_group_id%4)*8;
72770 +
72771 + tmp = ioread32be(&cpg_rg[reg_num]);
72772 + tmp &= ~(0xFF<<offset);
72773 + tmp |= (uint32_t)priority_bit_map << offset;
72774 +
72775 + iowrite32be(tmp,&cpg_rg[reg_num]);
72776 +}
72777 +
72778 +/*****************************************************************************/
72779 +/* API Init unit functions */
72780 +/*****************************************************************************/
72781 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
72782 +{
72783 + memset(cfg, 0, sizeof(struct fman_cfg));
72784 +
72785 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
72786 + cfg->dma_err = DEFAULT_DMA_ERR;
72787 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
72788 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
72789 + cfg->en_iram_test_mode = FALSE;
72790 + cfg->en_muram_test_mode = FALSE;
72791 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
72792 +
72793 + if (!is_master)
72794 + return;
72795 +
72796 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
72797 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
72798 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
72799 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
72800 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
72801 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
72802 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
72803 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
72804 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
72805 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
72806 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
72807 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
72808 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
72809 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
72810 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
72811 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
72812 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
72813 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
72814 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
72815 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
72816 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
72817 +
72818 + cfg->pedantic_dma = FALSE;
72819 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
72820 + cfg->dma_stop_on_bus_error = FALSE;
72821 + cfg->qmi_deq_option_support = FALSE;
72822 +}
72823 +
72824 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
72825 +{
72826 + uint32_t tmp_reg;
72827 +
72828 + /* read the values from the registers as they are initialized by the HW with
72829 + * the required values.
72830 + */
72831 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
72832 + cfg->total_fifo_size =
72833 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
72834 +
72835 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
72836 + cfg->total_num_of_tasks =
72837 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
72838 +
72839 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
72840 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
72841 +
72842 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
72843 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
72844 +
72845 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
72846 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
72847 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
72848 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
72849 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
72850 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
72851 +
72852 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
72853 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
72854 +
72855 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
72856 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
72857 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
72858 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
72859 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
72860 +
72861 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
72862 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
72863 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
72864 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
72865 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
72866 +
72867 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
72868 + cfg->dma_sos_emergency = tmp_reg;
72869 +
72870 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
72871 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
72872 +
72873 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
72874 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
72875 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
72876 +}
72877 +
72878 +void fman_reset(struct fman_fpm_regs *fpm_rg)
72879 +{
72880 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
72881 +}
72882 +
72883 +/**************************************************************************//**
72884 + @Function FM_Init
72885 +
72886 + @Description Initializes the FM module
72887 +
72888 + @Param[in] h_Fm - FM module descriptor
72889 +
72890 + @Return E_OK on success; Error code otherwise.
72891 +*//***************************************************************************/
72892 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
72893 +{
72894 + uint32_t tmp_reg;
72895 +
72896 + /**********************/
72897 + /* Init DMA Registers */
72898 + /**********************/
72899 + /* clear status reg events */
72900 + /* oren - check!!! */
72901 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
72902 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
72903 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
72904 + &dma_rg->fmdmsr);
72905 +
72906 + /* configure mode register */
72907 + tmp_reg = 0;
72908 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
72909 + if (cfg->dma_aid_override)
72910 + tmp_reg |= DMA_MODE_AID_OR;
72911 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
72912 + tmp_reg |= DMA_MODE_BER;
72913 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
72914 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
72915 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
72916 + tmp_reg |= DMA_MODE_ECC;
72917 + if (cfg->dma_stop_on_bus_error)
72918 + tmp_reg |= DMA_MODE_SBER;
72919 + if(cfg->dma_axi_dbg_num_of_beats)
72920 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
72921 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
72922 +
72923 + if (cfg->dma_en_emergency) {
72924 + tmp_reg |= cfg->dma_emergency_bus_select;
72925 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
72926 + if (cfg->dma_en_emergency_smoother)
72927 + iowrite32be(cfg->dma_emergency_switch_counter,
72928 + &dma_rg->fmdmemsr);
72929 + }
72930 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
72931 + DMA_MODE_CEN_SHIFT;
72932 + tmp_reg |= DMA_MODE_SECURE_PROT;
72933 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
72934 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
72935 +
72936 + if (cfg->pedantic_dma)
72937 + tmp_reg |= DMA_MODE_EMER_READ;
72938 +
72939 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
72940 +
72941 + /* configure thresholds register */
72942 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
72943 + DMA_THRESH_COMMQ_SHIFT) |
72944 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
72945 + DMA_THRESH_READ_INT_BUF_SHIFT) |
72946 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
72947 +
72948 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
72949 +
72950 + /* configure hysteresis register */
72951 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
72952 + DMA_THRESH_COMMQ_SHIFT) |
72953 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
72954 + DMA_THRESH_READ_INT_BUF_SHIFT) |
72955 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
72956 +
72957 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
72958 +
72959 + /* configure emergency threshold */
72960 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
72961 +
72962 + /* configure Watchdog */
72963 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
72964 + &dma_rg->fmdmwcr);
72965 +
72966 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
72967 +
72968 + return 0;
72969 +}
72970 +
72971 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
72972 +{
72973 + uint32_t tmp_reg;
72974 + int i;
72975 +
72976 + /**********************/
72977 + /* Init FPM Registers */
72978 + /**********************/
72979 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
72980 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
72981 +
72982 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
72983 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
72984 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
72985 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
72986 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
72987 +
72988 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
72989 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
72990 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
72991 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
72992 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
72993 +
72994 + /* define exceptions and error behavior */
72995 + tmp_reg = 0;
72996 + /* Clear events */
72997 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
72998 + FPM_EV_MASK_SINGLE_ECC);
72999 + /* enable interrupts */
73000 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
73001 + tmp_reg |= FPM_EV_MASK_STALL_EN;
73002 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
73003 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
73004 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
73005 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
73006 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
73007 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
73008 + if (!cfg->halt_on_external_activ)
73009 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
73010 + if (!cfg->halt_on_unrecov_ecc_err)
73011 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
73012 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
73013 +
73014 + /* clear all fmCtls event registers */
73015 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
73016 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
73017 +
73018 + /* RAM ECC - enable and clear events*/
73019 + /* first we need to clear all parser memory,
73020 + * as it is uninitialized and may cause ECC errors */
73021 + /* event bits */
73022 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
73023 + /* Rams enable not effected by RCR bit, but by a COP configuration */
73024 + if (cfg->external_ecc_rams_enable)
73025 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
73026 +
73027 + /* enable test mode */
73028 + if (cfg->en_muram_test_mode)
73029 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
73030 + if (cfg->en_iram_test_mode)
73031 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
73032 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
73033 +
73034 + tmp_reg = 0;
73035 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
73036 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
73037 + fman_enable_rams_ecc(fpm_rg);
73038 + }
73039 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
73040 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
73041 + fman_enable_rams_ecc(fpm_rg);
73042 + }
73043 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
73044 +
73045 + return 0;
73046 +}
73047 +
73048 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
73049 +{
73050 + uint32_t tmp_reg;
73051 +
73052 + /**********************/
73053 + /* Init BMI Registers */
73054 + /**********************/
73055 +
73056 + /* define common resources */
73057 + tmp_reg = cfg->fifo_base_addr;
73058 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
73059 +
73060 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
73061 + BMI_CFG1_FIFO_SIZE_SHIFT);
73062 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
73063 +
73064 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
73065 + BMI_CFG2_TASKS_SHIFT);
73066 + /* num of DMA's will be dynamically updated when each port is set */
73067 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
73068 +
73069 + /* define unmaskable exceptions, enable and clear events */
73070 + tmp_reg = 0;
73071 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
73072 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
73073 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
73074 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
73075 + &bmi_rg->fmbm_ievr);
73076 +
73077 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
73078 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
73079 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
73080 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
73081 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
73082 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
73083 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
73084 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
73085 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
73086 +
73087 + return 0;
73088 +}
73089 +
73090 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
73091 +{
73092 + uint32_t tmp_reg;
73093 + uint16_t period_in_fm_clocks;
73094 + uint8_t remainder;
73095 + /**********************/
73096 + /* Init QMI Registers */
73097 + /**********************/
73098 + /* Clear error interrupt events */
73099 +
73100 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
73101 + &qmi_rg->fmqm_eie);
73102 + tmp_reg = 0;
73103 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
73104 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
73105 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
73106 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
73107 + /* enable events */
73108 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
73109 +
73110 + if (cfg->tnum_aging_period) {
73111 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
73112 + period_in_fm_clocks = (uint16_t)
73113 + (cfg->tnum_aging_period * cfg->clk_freq);
73114 + /* period_in_fm_clocks must be a 64 multiply */
73115 + remainder = (uint8_t)(period_in_fm_clocks % 64);
73116 + if (remainder)
73117 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
73118 + else{
73119 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
73120 + if (!tmp_reg)
73121 + tmp_reg = 1;
73122 + }
73123 + tmp_reg <<= QMI_TAPC_TAP;
73124 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
73125 + }
73126 + tmp_reg = 0;
73127 + /* Clear interrupt events */
73128 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
73129 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
73130 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
73131 + /* enable events */
73132 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
73133 +
73134 + return 0;
73135 +}
73136 +
73137 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
73138 +{
73139 + uint32_t cfg_reg = 0;
73140 +
73141 + /**********************/
73142 + /* Enable all modules */
73143 + /**********************/
73144 + /* clear & enable global counters - calculate reg and save for later,
73145 + because it's the same reg for QMI enable */
73146 + cfg_reg = QMI_CFG_EN_COUNTERS;
73147 + if (cfg->qmi_deq_option_support)
73148 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
73149 + (uint32_t)cfg->qmi_def_tnums_thresh);
73150 +
73151 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
73152 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
73153 + &fman_rg->qmi_rg->fmqm_gc);
73154 +
73155 + return 0;
73156 +}
73157 +
73158 +void fman_free_resources(struct fman_rg *fman_rg)
73159 +{
73160 + /* disable BMI and QMI */
73161 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
73162 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
73163 +
73164 + /* release BMI resources */
73165 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
73166 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
73167 +
73168 + /* disable ECC */
73169 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
73170 +}
73171 +
73172 +/****************************************************/
73173 +/* API Run-time Control uint functions */
73174 +/****************************************************/
73175 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
73176 +{
73177 + return ioread32be(&fpm_rg->fm_npi);
73178 +}
73179 +
73180 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
73181 +{
73182 + uint32_t event;
73183 +
73184 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
73185 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
73186 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
73187 +
73188 + return event;
73189 +}
73190 +
73191 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
73192 +{
73193 + return ioread32be(&fpm_rg->fm_epi);
73194 +}
73195 +
73196 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
73197 +{
73198 + int i;
73199 + uint8_t shift;
73200 + uint32_t tmp = 0;
73201 +
73202 + for (i = 0; i < 64; i++) {
73203 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
73204 + /* Add this port to tmp_reg */
73205 + /* (each 8 ports result in one register)*/
73206 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
73207 + tmp |= ((weights[i] - 1) << shift);
73208 + }
73209 + if (i % 8 == 7) { /* last in this set */
73210 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
73211 + tmp = 0;
73212 + }
73213 + }
73214 +}
73215 +
73216 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
73217 +{
73218 + uint32_t tmp;
73219 +
73220 + tmp = ioread32be(&fpm_rg->fm_rcr);
73221 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
73222 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
73223 + &fpm_rg->fm_rcr);
73224 + else
73225 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
73226 + FPM_RAM_IRAM_ECC_EN,
73227 + &fpm_rg->fm_rcr);
73228 +}
73229 +
73230 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
73231 +{
73232 + uint32_t tmp;
73233 +
73234 + tmp = ioread32be(&fpm_rg->fm_rcr);
73235 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
73236 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
73237 + &fpm_rg->fm_rcr);
73238 + else
73239 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
73240 + &fpm_rg->fm_rcr);
73241 +}
73242 +
73243 +int fman_set_exception(struct fman_rg *fman_rg,
73244 + enum fman_exceptions exception,
73245 + bool enable)
73246 +{
73247 + uint32_t tmp;
73248 +
73249 + switch (exception) {
73250 + case(E_FMAN_EX_DMA_BUS_ERROR):
73251 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
73252 + if (enable)
73253 + tmp |= DMA_MODE_BER;
73254 + else
73255 + tmp &= ~DMA_MODE_BER;
73256 + /* disable bus error */
73257 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
73258 + break;
73259 + case(E_FMAN_EX_DMA_READ_ECC):
73260 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
73261 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
73262 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
73263 + if (enable)
73264 + tmp |= DMA_MODE_ECC;
73265 + else
73266 + tmp &= ~DMA_MODE_ECC;
73267 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
73268 + break;
73269 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
73270 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
73271 + if (enable)
73272 + tmp |= FPM_EV_MASK_STALL_EN;
73273 + else
73274 + tmp &= ~FPM_EV_MASK_STALL_EN;
73275 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
73276 + break;
73277 + case(E_FMAN_EX_FPM_SINGLE_ECC):
73278 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
73279 + if (enable)
73280 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
73281 + else
73282 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
73283 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
73284 + break;
73285 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
73286 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
73287 + if (enable)
73288 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
73289 + else
73290 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
73291 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
73292 + break;
73293 + case(E_FMAN_EX_QMI_SINGLE_ECC):
73294 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
73295 + if (enable)
73296 + tmp |= QMI_INTR_EN_SINGLE_ECC;
73297 + else
73298 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
73299 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
73300 + break;
73301 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
73302 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
73303 + if (enable)
73304 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
73305 + else
73306 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
73307 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
73308 + break;
73309 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
73310 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
73311 + if (enable)
73312 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
73313 + else
73314 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
73315 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
73316 + break;
73317 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
73318 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73319 + if (enable)
73320 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
73321 + else
73322 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
73323 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73324 + break;
73325 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
73326 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73327 + if (enable)
73328 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
73329 + else
73330 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
73331 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73332 + break;
73333 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
73334 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73335 + if (enable)
73336 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
73337 + else
73338 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
73339 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73340 + break;
73341 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
73342 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73343 + if (enable)
73344 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
73345 + else
73346 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
73347 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73348 + break;
73349 + case(E_FMAN_EX_IRAM_ECC):
73350 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
73351 + if (enable) {
73352 + /* enable ECC if not enabled */
73353 + fman_enable_rams_ecc(fman_rg->fpm_rg);
73354 + /* enable ECC interrupts */
73355 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
73356 + } else {
73357 + /* ECC mechanism may be disabled,
73358 + * depending on driver status */
73359 + fman_disable_rams_ecc(fman_rg->fpm_rg);
73360 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
73361 + }
73362 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
73363 + break;
73364 + case(E_FMAN_EX_MURAM_ECC):
73365 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
73366 + if (enable) {
73367 + /* enable ECC if not enabled */
73368 + fman_enable_rams_ecc(fman_rg->fpm_rg);
73369 + /* enable ECC interrupts */
73370 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
73371 + } else {
73372 + /* ECC mechanism may be disabled,
73373 + * depending on driver status */
73374 + fman_disable_rams_ecc(fman_rg->fpm_rg);
73375 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
73376 + }
73377 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
73378 + break;
73379 + default:
73380 + return -EINVAL;
73381 + }
73382 + return 0;
73383 +}
73384 +
73385 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
73386 + uint8_t *major,
73387 + uint8_t *minor)
73388 +{
73389 + uint32_t tmp;
73390 +
73391 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
73392 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
73393 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
73394 +
73395 +}
73396 +
73397 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
73398 + enum fman_counters reg_name)
73399 +{
73400 + uint32_t ret_val;
73401 +
73402 + switch (reg_name) {
73403 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
73404 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
73405 + break;
73406 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
73407 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
73408 + break;
73409 + case(E_FMAN_COUNTERS_DEQ_0):
73410 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
73411 + break;
73412 + case(E_FMAN_COUNTERS_DEQ_1):
73413 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
73414 + break;
73415 + case(E_FMAN_COUNTERS_DEQ_2):
73416 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
73417 + break;
73418 + case(E_FMAN_COUNTERS_DEQ_3):
73419 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
73420 + break;
73421 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
73422 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
73423 + break;
73424 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
73425 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
73426 + break;
73427 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
73428 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
73429 + break;
73430 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
73431 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
73432 + break;
73433 + default:
73434 + ret_val = 0;
73435 + }
73436 + return ret_val;
73437 +}
73438 +
73439 +int fman_modify_counter(struct fman_rg *fman_rg,
73440 + enum fman_counters reg_name,
73441 + uint32_t val)
73442 +{
73443 + /* When applicable (when there is an 'enable counters' bit,
73444 + * check that counters are enabled */
73445 + switch (reg_name) {
73446 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
73447 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
73448 + case(E_FMAN_COUNTERS_DEQ_0):
73449 + case(E_FMAN_COUNTERS_DEQ_1):
73450 + case(E_FMAN_COUNTERS_DEQ_2):
73451 + case(E_FMAN_COUNTERS_DEQ_3):
73452 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
73453 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
73454 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
73455 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
73456 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
73457 + QMI_CFG_EN_COUNTERS))
73458 + return -EINVAL;
73459 + break;
73460 + default:
73461 + break;
73462 + }
73463 + /* Set counter */
73464 + switch (reg_name) {
73465 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
73466 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
73467 + break;
73468 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
73469 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
73470 + break;
73471 + case(E_FMAN_COUNTERS_DEQ_0):
73472 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
73473 + break;
73474 + case(E_FMAN_COUNTERS_DEQ_1):
73475 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
73476 + break;
73477 + case(E_FMAN_COUNTERS_DEQ_2):
73478 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
73479 + break;
73480 + case(E_FMAN_COUNTERS_DEQ_3):
73481 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
73482 + break;
73483 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
73484 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
73485 + break;
73486 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
73487 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
73488 + break;
73489 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
73490 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
73491 + break;
73492 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
73493 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
73494 + break;
73495 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
73496 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
73497 + break;
73498 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
73499 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
73500 + break;
73501 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
73502 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
73503 + break;
73504 + default:
73505 + break;
73506 + }
73507 + return 0;
73508 +}
73509 +
73510 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
73511 + bool is_write,
73512 + bool enable)
73513 +{
73514 + uint32_t msk;
73515 +
73516 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
73517 +
73518 + if (enable)
73519 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
73520 + &dma_rg->fmdmmr);
73521 + else /* disable */
73522 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
73523 + &dma_rg->fmdmmr);
73524 +}
73525 +
73526 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
73527 +{
73528 + uint32_t tmp;
73529 +
73530 + tmp = ioread32be(&dma_rg->fmdmmr) |
73531 + (pri << DMA_MODE_BUS_PRI_SHIFT);
73532 +
73533 + iowrite32be(tmp, &dma_rg->fmdmmr);
73534 +}
73535 +
73536 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
73537 +{
73538 + return ioread32be(&dma_rg->fmdmsr);
73539 +}
73540 +
73541 +void fman_force_intr(struct fman_rg *fman_rg,
73542 + enum fman_exceptions exception)
73543 +{
73544 + switch (exception) {
73545 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
73546 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
73547 + &fman_rg->qmi_rg->fmqm_eif);
73548 + break;
73549 + case E_FMAN_EX_QMI_SINGLE_ECC:
73550 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
73551 + &fman_rg->qmi_rg->fmqm_if);
73552 + break;
73553 + case E_FMAN_EX_QMI_DOUBLE_ECC:
73554 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
73555 + &fman_rg->qmi_rg->fmqm_eif);
73556 + break;
73557 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
73558 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
73559 + &fman_rg->bmi_rg->fmbm_ifr);
73560 + break;
73561 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
73562 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
73563 + &fman_rg->bmi_rg->fmbm_ifr);
73564 + break;
73565 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
73566 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
73567 + &fman_rg->bmi_rg->fmbm_ifr);
73568 + break;
73569 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
73570 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
73571 + &fman_rg->bmi_rg->fmbm_ifr);
73572 + break;
73573 + default:
73574 + break;
73575 + }
73576 +}
73577 +
73578 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
73579 +{
73580 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
73581 +}
73582 +void fman_resume(struct fman_fpm_regs *fpm_rg)
73583 +{
73584 + uint32_t tmp;
73585 +
73586 + tmp = ioread32be(&fpm_rg->fmfp_ee);
73587 + /* clear tmp_reg event bits in order not to clear standing events */
73588 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
73589 + FPM_EV_MASK_STALL |
73590 + FPM_EV_MASK_SINGLE_ECC);
73591 + tmp |= FPM_EV_MASK_RELEASE_FM;
73592 +
73593 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
73594 +}
73595 --- /dev/null
73596 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
73597 @@ -0,0 +1,1214 @@
73598 +/*
73599 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73600 + *
73601 + * Redistribution and use in source and binary forms, with or without
73602 + * modification, are permitted provided that the following conditions are met:
73603 + * * Redistributions of source code must retain the above copyright
73604 + * notice, this list of conditions and the following disclaimer.
73605 + * * Redistributions in binary form must reproduce the above copyright
73606 + * notice, this list of conditions and the following disclaimer in the
73607 + * documentation and/or other materials provided with the distribution.
73608 + * * Neither the name of Freescale Semiconductor nor the
73609 + * names of its contributors may be used to endorse or promote products
73610 + * derived from this software without specific prior written permission.
73611 + *
73612 + *
73613 + * ALTERNATIVELY, this software may be distributed under the terms of the
73614 + * GNU General Public License ("GPL") as published by the Free Software
73615 + * Foundation, either version 2 of that License or (at your option) any
73616 + * later version.
73617 + *
73618 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73619 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73620 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73621 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73622 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73623 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73624 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73625 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73626 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73627 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73628 + */
73629 +
73630 +
73631 +/******************************************************************************
73632 + @File fm_common.h
73633 +
73634 + @Description FM internal structures and definitions.
73635 +*//***************************************************************************/
73636 +#ifndef __FM_COMMON_H
73637 +#define __FM_COMMON_H
73638 +
73639 +#include "error_ext.h"
73640 +#include "std_ext.h"
73641 +#include "fm_pcd_ext.h"
73642 +#include "fm_ext.h"
73643 +#include "fm_port_ext.h"
73644 +
73645 +
73646 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
73647 +
73648 +#define CLS_PLAN_NUM_PER_GRP 8
73649 +
73650 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
73651 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
73652 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
73653 +
73654 +
73655 +
73656 +/**************************************************************************//**
73657 + @Description Modules registers offsets
73658 +*//***************************************************************************/
73659 +#define FM_MM_MURAM 0x00000000
73660 +#define FM_MM_BMI 0x00080000
73661 +#define FM_MM_QMI 0x00080400
73662 +#define FM_MM_PRS 0x000c7000
73663 +#define FM_MM_KG 0x000C1000
73664 +#define FM_MM_DMA 0x000C2000
73665 +#define FM_MM_FPM 0x000C3000
73666 +#define FM_MM_PLCR 0x000C0000
73667 +#define FM_MM_IMEM 0x000C4000
73668 +#define FM_MM_CGP 0x000DB000
73669 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
73670 +#if (DPAA_VERSION >= 11)
73671 +#define FM_MM_SP 0x000dc000
73672 +#endif /* (DPAA_VERSION >= 11) */
73673 +
73674 +
73675 +/**************************************************************************//**
73676 + @Description Enum for inter-module interrupts registration
73677 +*//***************************************************************************/
73678 +typedef enum e_FmEventModules{
73679 + e_FM_MOD_PRS, /**< Parser event */
73680 + e_FM_MOD_KG, /**< Keygen event */
73681 + e_FM_MOD_PLCR, /**< Policer event */
73682 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
73683 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
73684 + e_FM_MOD_TMR, /**< Timer event */
73685 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
73686 + e_FM_MOD_MACSEC,
73687 + e_FM_MOD_DUMMY_LAST
73688 +} e_FmEventModules;
73689 +
73690 +/**************************************************************************//**
73691 + @Description Enum for interrupts types
73692 +*//***************************************************************************/
73693 +typedef enum e_FmIntrType {
73694 + e_FM_INTR_TYPE_ERR,
73695 + e_FM_INTR_TYPE_NORMAL
73696 +} e_FmIntrType;
73697 +
73698 +/**************************************************************************//**
73699 + @Description Enum for inter-module interrupts registration
73700 +*//***************************************************************************/
73701 +typedef enum e_FmInterModuleEvent
73702 +{
73703 + e_FM_EV_PRS = 0, /**< Parser event */
73704 + e_FM_EV_ERR_PRS, /**< Parser error event */
73705 + e_FM_EV_KG, /**< Keygen event */
73706 + e_FM_EV_ERR_KG, /**< Keygen error event */
73707 + e_FM_EV_PLCR, /**< Policer event */
73708 + e_FM_EV_ERR_PLCR, /**< Policer error event */
73709 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
73710 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
73711 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
73712 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
73713 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
73714 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
73715 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
73716 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
73717 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
73718 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
73719 + e_FM_EV_ERR_MACSEC_MAC0,
73720 + e_FM_EV_TMR, /**< Timer event */
73721 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
73722 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
73723 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
73724 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
73725 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
73726 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
73727 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
73728 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
73729 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
73730 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
73731 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
73732 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
73733 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
73734 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
73735 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
73736 + e_FM_EV_DUMMY_LAST
73737 +} e_FmInterModuleEvent;
73738 +
73739 +
73740 +#if defined(__MWERKS__) && !defined(__GNUC__)
73741 +#pragma pack(push,1)
73742 +#endif /* defined(__MWERKS__) && ... */
73743 +
73744 +/**************************************************************************//**
73745 + @Description PCD KG scheme registers
73746 +*//***************************************************************************/
73747 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
73748 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
73749 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
73750 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
73751 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
73752 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
73753 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
73754 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
73755 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
73756 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
73757 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
73758 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
73759 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
73760 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
73761 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
73762 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
73763 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
73764 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
73765 +} _PackedType t_FmPcdPlcrProfileRegs;
73766 +
73767 +
73768 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
73769 + volatile uint32_t portIdAndCapwapReassmTbl;
73770 + volatile uint32_t fqidForTimeOutFrames;
73771 + volatile uint32_t timeoutRequestTime;
73772 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
73773 +
73774 +/**************************************************************************//**
73775 + @Description PCD CTRL Parameters Page
73776 +*//***************************************************************************/
73777 +typedef _Packed struct t_FmPcdCtrlParamsPage {
73778 + volatile uint8_t reserved0[16];
73779 + volatile uint32_t iprIpv4Nia;
73780 + volatile uint32_t iprIpv6Nia;
73781 + volatile uint8_t reserved1[24];
73782 + volatile uint32_t ipfOptionsCounter;
73783 + volatile uint8_t reserved2[12];
73784 + volatile uint32_t misc;
73785 + volatile uint32_t errorsDiscardMask;
73786 + volatile uint32_t discardMask;
73787 + volatile uint8_t reserved3[4];
73788 + volatile uint32_t postBmiFetchNia;
73789 + volatile uint8_t reserved4[172];
73790 +} _PackedType t_FmPcdCtrlParamsPage;
73791 +
73792 +
73793 +
73794 +#if defined(__MWERKS__) && !defined(__GNUC__)
73795 +#pragma pack(pop)
73796 +#endif /* defined(__MWERKS__) && ... */
73797 +
73798 +
73799 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
73800 +typedef uint32_t t_FmFmanCtrl;
73801 +
73802 +#define FPM_PORT_FM_CTL1 0x00000001
73803 +#define FPM_PORT_FM_CTL2 0x00000002
73804 +
73805 +
73806 +
73807 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
73808 + uint32_t numOfBuffers;
73809 + uint8_t bufferPoolId;
73810 +} t_FmPcdCcFragScratchPoolCmdParams;
73811 +
73812 +typedef struct t_FmPcdCcReassmTimeoutParams {
73813 + bool activate;
73814 + uint8_t tsbs;
73815 + uint32_t iprcpt;
73816 +} t_FmPcdCcReassmTimeoutParams;
73817 +
73818 +typedef struct {
73819 + uint8_t baseEntry;
73820 + uint16_t numOfClsPlanEntries;
73821 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
73822 +} t_FmPcdKgInterModuleClsPlanSet;
73823 +
73824 +/**************************************************************************//**
73825 + @Description Structure for binding a port to keygen schemes.
73826 +*//***************************************************************************/
73827 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
73828 + uint8_t hardwarePortId;
73829 + uint8_t netEnvId;
73830 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
73831 + uint8_t numOfSchemes;
73832 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
73833 +} t_FmPcdKgInterModuleBindPortToSchemes;
73834 +
73835 +typedef struct {
73836 + uint32_t nextCcNodeInfo;
73837 + t_List node;
73838 +} t_CcNodeInfo;
73839 +
73840 +typedef struct
73841 +{
73842 + t_Handle h_CcNode;
73843 + uint16_t index;
73844 + t_List node;
73845 +}t_CcNodeInformation;
73846 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
73847 +
73848 +typedef enum e_ModifyState
73849 +{
73850 + e_MODIFY_STATE_ADD = 0,
73851 + e_MODIFY_STATE_REMOVE,
73852 + e_MODIFY_STATE_CHANGE
73853 +} e_ModifyState;
73854 +
73855 +typedef struct
73856 +{
73857 + t_Handle h_Manip;
73858 + t_List node;
73859 +}t_ManipInfo;
73860 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
73861 +
73862 +typedef struct {
73863 + uint32_t type;
73864 + uint8_t prOffset;
73865 + uint16_t dataOffset;
73866 + uint8_t internalBufferOffset;
73867 + uint8_t numOfTasks;
73868 + uint8_t numOfExtraTasks;
73869 + uint8_t hardwarePortId;
73870 + t_FmRevisionInfo revInfo;
73871 + uint32_t nia;
73872 + uint32_t discardMask;
73873 +} t_GetCcParams;
73874 +
73875 +typedef struct {
73876 + uint32_t type;
73877 + int psoSize;
73878 + uint32_t nia;
73879 + t_FmFmanCtrl orFmanCtrl;
73880 + bool overwrite;
73881 + uint8_t ofpDpde;
73882 +} t_SetCcParams;
73883 +
73884 +typedef struct {
73885 + t_GetCcParams getCcParams;
73886 + t_SetCcParams setCcParams;
73887 +} t_FmPortGetSetCcParams;
73888 +
73889 +typedef struct {
73890 + uint32_t type;
73891 + bool sleep;
73892 +} t_FmSetParams;
73893 +
73894 +typedef struct {
73895 + uint32_t type;
73896 + uint32_t fmqm_gs;
73897 + uint32_t fm_npi;
73898 + uint32_t fm_cld;
73899 + uint32_t fmfp_extc;
73900 +} t_FmGetParams;
73901 +
73902 +typedef struct {
73903 + t_FmSetParams setParams;
73904 + t_FmGetParams getParams;
73905 +} t_FmGetSetParams;
73906 +
73907 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
73908 +
73909 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
73910 +{
73911 + uint32_t intFlags;
73912 + if (h_Spinlock)
73913 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
73914 + else
73915 + intFlags = XX_DisableAllIntr();
73916 +
73917 + if (*p_Flag)
73918 + {
73919 + if (h_Spinlock)
73920 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
73921 + else
73922 + XX_RestoreAllIntr(intFlags);
73923 + return FALSE;
73924 + }
73925 + *p_Flag = TRUE;
73926 +
73927 + if (h_Spinlock)
73928 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
73929 + else
73930 + XX_RestoreAllIntr(intFlags);
73931 +
73932 + return TRUE;
73933 +}
73934 +
73935 +#define RELEASE_LOCK(_flag) _flag = FALSE;
73936 +
73937 +/**************************************************************************//**
73938 + @Collection Defines used for manipulation CC and BMI
73939 + @{
73940 +*//***************************************************************************/
73941 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
73942 +#define OFFSET_OF_PR 0x40000000
73943 +#define MANIP_EXTRA_SPACE 0x20000000
73944 +#define NUM_OF_TASKS 0x10000000
73945 +#define OFFSET_OF_DATA 0x08000000
73946 +#define HW_PORT_ID 0x04000000
73947 +#define FM_REV 0x02000000
73948 +#define GET_NIA_FPNE 0x01000000
73949 +#define GET_NIA_PNDN 0x00800000
73950 +#define NUM_OF_EXTRA_TASKS 0x00400000
73951 +#define DISCARD_MASK 0x00200000
73952 +
73953 +#define UPDATE_NIA_PNEN 0x80000000
73954 +#define UPDATE_PSO 0x40000000
73955 +#define UPDATE_NIA_PNDN 0x20000000
73956 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
73957 +#define UPDATE_OFP_DPTE 0x08000000
73958 +#define UPDATE_NIA_FENE 0x04000000
73959 +#define UPDATE_NIA_CMNE 0x02000000
73960 +#define UPDATE_NIA_FPNE 0x01000000
73961 +/* @} */
73962 +
73963 +/**************************************************************************//**
73964 + @Collection Defines used for manipulation CC and CC
73965 + @{
73966 +*//***************************************************************************/
73967 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
73968 +#define UPDATE_CC_WITH_TREE 0x40000000
73969 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
73970 +#define UPDATE_KG_NIA_CC_WA 0x10000000
73971 +#define UPDATE_KG_OPT_MODE 0x08000000
73972 +#define UPDATE_KG_NIA 0x04000000
73973 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
73974 +/* @} */
73975 +
73976 +#define UPDATE_FPM_BRKC_SLP 0x80000000
73977 +#define UPDATE_FPM_EXTC 0x40000000
73978 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
73979 +#define GET_FMQM_GS 0x10000000
73980 +#define GET_FM_NPI 0x08000000
73981 +#define GET_FMFP_EXTC 0x04000000
73982 +#define CLEAR_IRAM_READY 0x02000000
73983 +#define UPDATE_FM_CLD 0x01000000
73984 +#define GET_FM_CLD 0x00800000
73985 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
73986 + FM_MAX_NUM_OF_1G_RX_PORTS + \
73987 + FM_MAX_NUM_OF_10G_RX_PORTS + \
73988 + FM_MAX_NUM_OF_1G_TX_PORTS + \
73989 + FM_MAX_NUM_OF_10G_TX_PORTS)
73990 +
73991 +#define MODULE_NAME_SIZE 30
73992 +#define DUMMY_PORT_ID 0
73993 +
73994 +#define FM_LIODN_OFFSET_MASK 0x3FF
73995 +
73996 +/**************************************************************************//**
73997 + @Description NIA Description
73998 +*//***************************************************************************/
73999 +#define NIA_ENG_MASK 0x007C0000
74000 +#define NIA_AC_MASK 0x0003ffff
74001 +
74002 +#define NIA_ORDER_RESTOR 0x00800000
74003 +#define NIA_ENG_FM_CTL 0x00000000
74004 +#define NIA_ENG_PRS 0x00440000
74005 +#define NIA_ENG_KG 0x00480000
74006 +#define NIA_ENG_PLCR 0x004C0000
74007 +#define NIA_ENG_BMI 0x00500000
74008 +#define NIA_ENG_QMI_ENQ 0x00540000
74009 +#define NIA_ENG_QMI_DEQ 0x00580000
74010 +
74011 +#define NIA_FM_CTL_AC_CC 0x00000006
74012 +#define NIA_FM_CTL_AC_HC 0x0000000C
74013 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
74014 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
74015 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
74016 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
74017 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
74018 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
74019 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
74020 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
74021 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
74022 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
74023 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
74024 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
74025 +/* V3 only */
74026 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
74027 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
74028 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
74029 +
74030 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
74031 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
74032 +#define NIA_BMI_AC_RELEASE 0x000000C0
74033 +#define NIA_BMI_AC_DISCARD 0x000000C1
74034 +#define NIA_BMI_AC_TX 0x00000274
74035 +#define NIA_BMI_AC_FETCH 0x00000208
74036 +#define NIA_BMI_AC_MASK 0x000003FF
74037 +
74038 +#define NIA_KG_DIRECT 0x00000100
74039 +#define NIA_KG_CC_EN 0x00000200
74040 +#define NIA_PLCR_ABSOLUTE 0x00008000
74041 +
74042 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
74043 +
74044 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
74045 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
74046 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74047 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
74048 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
74049 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
74050 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74051 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
74052 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
74053 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
74054 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
74055 +#else
74056 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
74057 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74058 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
74059 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
74060 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
74061 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74062 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
74063 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
74064 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
74065 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
74066 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
74067 +
74068 +/**************************************************************************//**
74069 + @Description CTRL Parameters Page defines
74070 +*//***************************************************************************/
74071 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
74072 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
74073 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
74074 +
74075 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
74076 +
74077 +/**************************************************************************//**
74078 + @Description Port Id defines
74079 +*//***************************************************************************/
74080 +#if (DPAA_VERSION == 10)
74081 +#define BASE_OH_PORTID 1
74082 +#else
74083 +#define BASE_OH_PORTID 2
74084 +#endif /* (DPAA_VERSION == 10) */
74085 +#define BASE_1G_RX_PORTID 8
74086 +#define BASE_10G_RX_PORTID 0x10
74087 +#define BASE_1G_TX_PORTID 0x28
74088 +#define BASE_10G_TX_PORTID 0x30
74089 +
74090 +#define FM_PCD_PORT_OH_BASE_INDX 0
74091 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
74092 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
74093 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
74094 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
74095 +
74096 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
74097 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
74098 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
74099 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
74100 +#else
74101 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
74102 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
74103 +#endif
74104 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
74105 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
74106 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
74107 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
74108 +#else
74109 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
74110 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
74111 +#endif
74112 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
74113 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
74114 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
74115 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
74116 +#else
74117 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
74118 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
74119 +#endif
74120 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
74121 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
74122 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
74123 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
74124 +#else
74125 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
74126 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
74127 +#endif
74128 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
74129 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
74130 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
74131 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
74132 +#else
74133 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
74134 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
74135 +#endif
74136 +
74137 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
74138 +
74139 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
74140 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
74141 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
74142 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
74143 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
74144 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
74145 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
74146 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
74147 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
74148 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
74149 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
74150 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
74151 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
74152 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
74153 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
74154 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
74155 + else { \
74156 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
74157 + ASSERT_COND(TRUE); \
74158 + } \
74159 +}
74160 +
74161 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
74162 +do { \
74163 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
74164 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
74165 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
74166 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
74167 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
74168 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
74169 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
74170 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
74171 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
74172 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
74173 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
74174 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
74175 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
74176 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
74177 + else ASSERT_COND(FALSE); \
74178 +} while (0)
74179 +
74180 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
74181 +do { \
74182 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
74183 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
74184 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
74185 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
74186 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
74187 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
74188 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
74189 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
74190 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
74191 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
74192 + else ASSERT_COND(FALSE); \
74193 +} while (0)
74194 +
74195 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
74196 +#define BMI_FIFO_UNITS 0x100
74197 +
74198 +typedef struct {
74199 + void (*f_Isr) (t_Handle h_Arg);
74200 + t_Handle h_SrcHandle;
74201 + uint8_t guestId;
74202 +} t_FmIntrSrc;
74203 +
74204 +#define ILLEGAL_HDR_NUM 0xFF
74205 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
74206 +
74207 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
74208 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
74209 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
74210 +
74211 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
74212 +{
74213 + switch (hdr)
74214 + { case (HEADER_TYPE_ETH): return 0;
74215 + case (HEADER_TYPE_LLC_SNAP): return 1;
74216 + case (HEADER_TYPE_VLAN): return 2;
74217 + case (HEADER_TYPE_PPPoE): return 3;
74218 + case (HEADER_TYPE_PPP): return 3;
74219 + case (HEADER_TYPE_MPLS): return 4;
74220 + case (HEADER_TYPE_IPv4): return 5;
74221 + case (HEADER_TYPE_IPv6): return 6;
74222 + case (HEADER_TYPE_GRE): return 7;
74223 + case (HEADER_TYPE_MINENCAP): return 8;
74224 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
74225 + case (HEADER_TYPE_TCP): return 10;
74226 + case (HEADER_TYPE_UDP): return 11;
74227 + case (HEADER_TYPE_IPSEC_AH):
74228 + case (HEADER_TYPE_IPSEC_ESP): return 12;
74229 + case (HEADER_TYPE_SCTP): return 13;
74230 + case (HEADER_TYPE_DCCP): return 14;
74231 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
74232 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
74233 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
74234 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
74235 + default:
74236 + return ILLEGAL_HDR_NUM;
74237 + }
74238 +}
74239 +
74240 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
74241 +
74242 +
74243 +/**************************************************************************//**
74244 + @Description A structure for initializing a keygen classification plan group
74245 +*//***************************************************************************/
74246 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
74247 + uint8_t netEnvId; /* IN */
74248 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
74249 + uint8_t clsPlanGrpId; /* OUT */
74250 + bool emptyClsPlanGrp; /* OUT */
74251 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
74252 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
74253 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
74254 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
74255 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
74256 +} t_FmPcdKgInterModuleClsPlanGrpParams;
74257 +
74258 +typedef struct t_FmPcdLock {
74259 + t_Handle h_Spinlock;
74260 + volatile bool flag;
74261 + t_List node;
74262 +} t_FmPcdLock;
74263 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
74264 +
74265 +
74266 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
74267 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
74268 +
74269 +
74270 +/***********************************************************************/
74271 +/* Common API for FM-PCD module */
74272 +/***********************************************************************/
74273 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
74274 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
74275 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
74276 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
74277 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
74278 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
74279 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
74280 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
74281 +uint32_t FmPcdLock(t_Handle h_FmPcd);
74282 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
74283 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
74284 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
74285 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
74286 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
74287 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
74288 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
74289 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
74290 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
74291 +t_Handle FmGetPcd(t_Handle h_Fm);
74292 +/***********************************************************************/
74293 +/* Common API for FM-PCD KG module */
74294 +/***********************************************************************/
74295 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
74296 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
74297 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
74298 +
74299 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
74300 +#if (DPAA_VERSION >= 11)
74301 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
74302 +#endif /* (DPAA_VERSION >= 11) */
74303 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
74304 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
74305 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
74306 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
74307 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
74308 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
74309 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
74310 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
74311 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
74312 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
74313 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
74314 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
74315 +
74316 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
74317 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
74318 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
74319 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
74320 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
74321 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
74322 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
74323 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
74324 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
74325 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
74326 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
74327 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
74328 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
74329 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
74330 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
74331 +
74332 +/***********************************************************************/
74333 +/* Common API for FM-PCD parser module */
74334 +/***********************************************************************/
74335 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
74336 +
74337 +/***********************************************************************/
74338 +/* Common API for FM-PCD policer module */
74339 +/***********************************************************************/
74340 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
74341 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
74342 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74343 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
74344 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
74345 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
74346 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
74347 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
74348 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
74349 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
74350 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
74351 + e_FmPcdProfileTypeSelection profileType,
74352 + t_Handle h_FmPort,
74353 + uint16_t relativeProfile,
74354 + uint16_t *p_AbsoluteId);
74355 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74356 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74357 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
74358 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74359 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74360 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
74361 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
74362 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
74363 +
74364 +/***********************************************************************/
74365 +/* Common API for FM-PCD CC module */
74366 +/***********************************************************************/
74367 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
74368 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
74369 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
74370 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
74371 +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);
74372 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
74373 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
74374 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
74375 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
74376 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
74377 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
74378 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
74379 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
74380 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
74381 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
74382 +
74383 +/***********************************************************************/
74384 +/* Common API for FM-PCD Manip module */
74385 +/***********************************************************************/
74386 +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);
74387 +
74388 +/***********************************************************************/
74389 +/* Common API for FM-Port module */
74390 +/***********************************************************************/
74391 +#if (DPAA_VERSION >= 11)
74392 +typedef enum e_FmPortGprFuncType
74393 +{
74394 + e_FM_PORT_GPR_EMPTY = 0,
74395 + e_FM_PORT_GPR_MURAM_PAGE
74396 +} e_FmPortGprFuncType;
74397 +
74398 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
74399 +#endif /* DPAA_VERSION >= 11) */
74400 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
74401 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
74402 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
74403 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
74404 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
74405 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
74406 +
74407 +
74408 +#if (DPAA_VERSION >= 11)
74409 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
74410 +#endif /* (DPAA_VERSION >= 11) */
74411 +
74412 +/**************************************************************************//**
74413 + @Function FmRegisterIntr
74414 +
74415 + @Description Used to register an inter-module event handler to be processed by FM
74416 +
74417 + @Param[in] h_Fm A handle to an FM Module.
74418 + @Param[in] mod The module that causes the event
74419 + @Param[in] modId Module id - if more than 1 instansiation of this
74420 + mode exists,0 otherwise.
74421 + @Param[in] intrType Interrupt type (error/normal) selection.
74422 + @Param[in] f_Isr The interrupt service routine.
74423 + @Param[in] h_Arg Argument to be passed to f_Isr.
74424 +
74425 + @Return None.
74426 +*//***************************************************************************/
74427 +void FmRegisterIntr(t_Handle h_Fm,
74428 + e_FmEventModules mod,
74429 + uint8_t modId,
74430 + e_FmIntrType intrType,
74431 + void (*f_Isr) (t_Handle h_Arg),
74432 + t_Handle h_Arg);
74433 +
74434 +/**************************************************************************//**
74435 + @Function FmUnregisterIntr
74436 +
74437 + @Description Used to un-register an inter-module event handler that was processed by FM
74438 +
74439 + @Param[in] h_Fm A handle to an FM Module.
74440 + @Param[in] mod The module that causes the event
74441 + @Param[in] modId Module id - if more than 1 instansiation of this
74442 + mode exists,0 otherwise.
74443 + @Param[in] intrType Interrupt type (error/normal) selection.
74444 +
74445 + @Return None.
74446 +*//***************************************************************************/
74447 +void FmUnregisterIntr(t_Handle h_Fm,
74448 + e_FmEventModules mod,
74449 + uint8_t modId,
74450 + e_FmIntrType intrType);
74451 +
74452 +/**************************************************************************//**
74453 + @Function FmRegisterFmCtlIntr
74454 +
74455 + @Description Used to register to one of the fmCtl events in the FM module
74456 +
74457 + @Param[in] h_Fm A handle to an FM Module.
74458 + @Param[in] eventRegId FmCtl event id (0-7).
74459 + @Param[in] f_Isr The interrupt service routine.
74460 +
74461 + @Return E_OK on success; Error code otherwise.
74462 +
74463 + @Cautions Allowed only following FM_Init().
74464 +*//***************************************************************************/
74465 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
74466 +
74467 +
74468 +/**************************************************************************//**
74469 + @Description enum for defining MAC types
74470 +*//***************************************************************************/
74471 +typedef enum e_FmMacType {
74472 + e_FM_MAC_10G = 0, /**< 10G MAC */
74473 + e_FM_MAC_1G /**< 1G MAC */
74474 +} e_FmMacType;
74475 +
74476 +/**************************************************************************//**
74477 + @Description Structure for port-FM communication during FM_PORT_Init.
74478 + Fields commented 'IN' are passed by the port module to be used
74479 + by the FM module.
74480 + Fields commented 'OUT' will be filled by FM before returning to port.
74481 + Some fields are optional (depending on configuration) and
74482 + will be analized by the port and FM modules accordingly.
74483 +*//***************************************************************************/
74484 +typedef struct t_FmInterModulePortInitParams {
74485 + uint8_t hardwarePortId; /**< IN. port Id */
74486 + e_FmPortType portType; /**< IN. Port type */
74487 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
74488 + uint16_t liodnOffset; /**< IN. Port's requested resource */
74489 + uint8_t numOfTasks; /**< IN. Port's requested resource */
74490 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
74491 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
74492 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
74493 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
74494 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
74495 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
74496 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
74497 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
74498 + LIODN base for this port, to be
74499 + used together with LIODN offset. */
74500 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
74501 +} t_FmInterModulePortInitParams;
74502 +
74503 +/**************************************************************************//**
74504 + @Description Structure for port-FM communication during FM_PORT_Free.
74505 +*//***************************************************************************/
74506 +typedef struct t_FmInterModulePortFreeParams {
74507 + uint8_t hardwarePortId; /**< IN. port Id */
74508 + e_FmPortType portType; /**< IN. Port type */
74509 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
74510 +} t_FmInterModulePortFreeParams;
74511 +
74512 +/**************************************************************************//**
74513 + @Function FmGetPcdPrsBaseAddr
74514 +
74515 + @Description Get the base address of the Parser from the FM module
74516 +
74517 + @Param[in] h_Fm A handle to an FM Module.
74518 +
74519 + @Return Base address.
74520 +*//***************************************************************************/
74521 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
74522 +
74523 +/**************************************************************************//**
74524 + @Function FmGetPcdKgBaseAddr
74525 +
74526 + @Description Get the base address of the Keygen from the FM module
74527 +
74528 + @Param[in] h_Fm A handle to an FM Module.
74529 +
74530 + @Return Base address.
74531 +*//***************************************************************************/
74532 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
74533 +
74534 +/**************************************************************************//**
74535 + @Function FmGetPcdPlcrBaseAddr
74536 +
74537 + @Description Get the base address of the Policer from the FM module
74538 +
74539 + @Param[in] h_Fm A handle to an FM Module.
74540 +
74541 + @Return Base address.
74542 +*//***************************************************************************/
74543 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
74544 +
74545 +/**************************************************************************//**
74546 + @Function FmGetMuramHandle
74547 +
74548 + @Description Get the handle of the MURAM from the FM module
74549 +
74550 + @Param[in] h_Fm A handle to an FM Module.
74551 +
74552 + @Return MURAM module handle.
74553 +*//***************************************************************************/
74554 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
74555 +
74556 +/**************************************************************************//**
74557 + @Function FmGetPhysicalMuramBase
74558 +
74559 + @Description Get the physical base address of the MURAM from the FM module
74560 +
74561 + @Param[in] h_Fm A handle to an FM Module.
74562 + @Param[in] fmPhysAddr Physical MURAM base
74563 +
74564 + @Return Physical base address.
74565 +*//***************************************************************************/
74566 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
74567 +
74568 +/**************************************************************************//**
74569 + @Function FmGetTimeStampScale
74570 +
74571 + @Description Used internally by other modules in order to get the timeStamp
74572 + period as requested by the application.
74573 +
74574 + This function returns bit number that is incremented every 1 usec.
74575 + To calculate timestamp period in nsec, use
74576 + 1000 / (1 << FmGetTimeStampScale()).
74577 +
74578 + @Param[in] h_Fm A handle to an FM Module.
74579 +
74580 + @Return Bit that counts 1 usec.
74581 +
74582 + @Cautions Allowed only following FM_Init().
74583 +*//***************************************************************************/
74584 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
74585 +
74586 +/**************************************************************************//**
74587 + @Function FmResumeStalledPort
74588 +
74589 + @Description Used internally by FM port to release a stalled port.
74590 +
74591 + @Param[in] h_Fm A handle to an FM Module.
74592 + @Param[in] hardwarePortId HW port id.
74593 +
74594 + @Return E_OK on success; Error code otherwise.
74595 +
74596 + @Cautions Allowed only following FM_Init().
74597 +*//***************************************************************************/
74598 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
74599 +
74600 +/**************************************************************************//**
74601 + @Function FmIsPortStalled
74602 +
74603 + @Description Used internally by FM port to read the port's status.
74604 +
74605 + @Param[in] h_Fm A handle to an FM Module.
74606 + @Param[in] hardwarePortId HW port id.
74607 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
74608 +
74609 + @Return E_OK on success; Error code otherwise.
74610 +
74611 + @Cautions Allowed only following FM_Init().
74612 +*//***************************************************************************/
74613 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
74614 +
74615 +/**************************************************************************//**
74616 + @Function FmResetMac
74617 +
74618 + @Description Used by MAC driver to reset the MAC registers
74619 +
74620 + @Param[in] h_Fm A handle to an FM Module.
74621 + @Param[in] type MAC type.
74622 + @Param[in] macId MAC id - according to type.
74623 +
74624 + @Return E_OK on success; Error code otherwise.
74625 +
74626 + @Cautions Allowed only following FM_Init().
74627 +*//***************************************************************************/
74628 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
74629 +
74630 +/**************************************************************************//**
74631 + @Function FmGetClockFreq
74632 +
74633 + @Description Used by MAC driver to get the FM clock frequency
74634 +
74635 + @Param[in] h_Fm A handle to an FM Module.
74636 +
74637 + @Return clock-freq on success; 0 otherwise.
74638 +
74639 + @Cautions Allowed only following FM_Init().
74640 +*//***************************************************************************/
74641 +uint16_t FmGetClockFreq(t_Handle h_Fm);
74642 +
74643 +/**************************************************************************//**
74644 + @Function FmGetMacClockFreq
74645 +
74646 + @Description Used by MAC driver to get the MAC clock frequency
74647 +
74648 + @Param[in] h_Fm A handle to an FM Module.
74649 +
74650 + @Return clock-freq on success; 0 otherwise.
74651 +
74652 + @Cautions Allowed only following FM_Init().
74653 +*//***************************************************************************/
74654 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
74655 +
74656 +/**************************************************************************//**
74657 + @Function FmGetId
74658 +
74659 + @Description Used by PCD driver to read rhe FM id
74660 +
74661 + @Param[in] h_Fm A handle to an FM Module.
74662 +
74663 + @Return E_OK on success; Error code otherwise.
74664 +
74665 + @Cautions Allowed only following FM_Init().
74666 +*//***************************************************************************/
74667 +uint8_t FmGetId(t_Handle h_Fm);
74668 +
74669 +/**************************************************************************//**
74670 + @Function FmReset
74671 +
74672 + @Description Used to reset the FM
74673 +
74674 + @Param[in] h_Fm A handle to an FM Module.
74675 +
74676 + @Return E_OK on success; Error code otherwise.
74677 +*//***************************************************************************/
74678 +t_Error FmReset(t_Handle h_Fm);
74679 +
74680 +/**************************************************************************//**
74681 + @Function FmGetSetPortParams
74682 +
74683 + @Description Used by FM-PORT driver to pass and receive parameters between
74684 + PORT and FM modules.
74685 +
74686 + @Param[in] h_Fm A handle to an FM Module.
74687 + @Param[in,out] p_PortParams A structure of FM Port parameters.
74688 +
74689 + @Return E_OK on success; Error code otherwise.
74690 +
74691 + @Cautions Allowed only following FM_Init().
74692 +*//***************************************************************************/
74693 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
74694 +
74695 +/**************************************************************************//**
74696 + @Function FmFreePortParams
74697 +
74698 + @Description Used by FM-PORT driver to free port's resources within the FM.
74699 +
74700 + @Param[in] h_Fm A handle to an FM Module.
74701 + @Param[in,out] p_PortParams A structure of FM Port parameters.
74702 +
74703 + @Return None.
74704 +
74705 + @Cautions Allowed only following FM_Init().
74706 +*//***************************************************************************/
74707 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
74708 +
74709 +/**************************************************************************//**
74710 + @Function FmSetNumOfRiscsPerPort
74711 +
74712 + @Description Used by FM-PORT driver to pass parameter between
74713 + PORT and FM modules for working with number of RISC..
74714 +
74715 + @Param[in] h_Fm A handle to an FM Module.
74716 + @Param[in] hardwarePortId hardware port Id.
74717 + @Param[in] numOfFmanCtrls number of Fman Controllers.
74718 + @Param[in] orFmanCtrl Fman Controller for order restoration.
74719 +
74720 + @Return None.
74721 +
74722 + @Cautions Allowed only following FM_Init().
74723 +*//***************************************************************************/
74724 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
74725 +
74726 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
74727 +/**************************************************************************//*
74728 + @Function FmDumpPortRegs
74729 +
74730 + @Description Dumps FM port registers which are part of FM common registers
74731 +
74732 + @Param[in] h_Fm A handle to an FM Module.
74733 + @Param[in] hardwarePortId HW port id.
74734 +
74735 + @Return E_OK on success; Error code otherwise.
74736 +
74737 + @Cautions Allowed only FM_Init().
74738 +*//***************************************************************************/
74739 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
74740 +#endif /* (defined(DEBUG_ERRORS) && ... */
74741 +
74742 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
74743 +void FmUnregisterPcd(t_Handle h_Fm);
74744 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
74745 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
74746 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
74747 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
74748 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
74749 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
74750 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
74751 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
74752 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
74753 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
74754 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
74755 +bool FmIsMaster(t_Handle h_Fm);
74756 +uint8_t FmGetGuestId(t_Handle h_Fm);
74757 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
74758 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
74759 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
74760 +
74761 +
74762 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
74763 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
74764 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
74765 +
74766 +void FmMuramClear(t_Handle h_FmMuram);
74767 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
74768 + uint8_t hardwarePortId,
74769 + uint8_t *p_NumOfOpenDmas,
74770 + uint8_t *p_NumOfExtraOpenDmas,
74771 + bool initialConfig);
74772 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
74773 + uint8_t hardwarePortId,
74774 + uint8_t *p_NumOfTasks,
74775 + uint8_t *p_NumOfExtraTasks,
74776 + bool initialConfig);
74777 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
74778 + uint8_t hardwarePortId,
74779 + uint32_t *p_SizeOfFifo,
74780 + uint32_t *p_ExtraSizeOfFifo,
74781 + bool initialConfig);
74782 +
74783 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
74784 + uint32_t congestionGroupId,
74785 + uint8_t priorityBitMap);
74786 +
74787 +#if (DPAA_VERSION >= 11)
74788 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
74789 + e_FmPortType portType,
74790 + uint8_t portId,
74791 + uint8_t numOfStorageProfiles);
74792 +
74793 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
74794 + e_FmPortType portType,
74795 + uint8_t portId);
74796 +
74797 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
74798 + e_FmPortType portType,
74799 + uint8_t portId,
74800 + uint16_t relativeProfile,
74801 + uint16_t *p_AbsoluteId);
74802 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
74803 + e_FmPortType portType,
74804 + uint8_t portId,
74805 + uint16_t relativeProfile);
74806 +
74807 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
74808 +#endif /* (DPAA_VERSION >= 11) */
74809 +
74810 +
74811 +#endif /* __FM_COMMON_H */
74812 --- /dev/null
74813 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
74814 @@ -0,0 +1,93 @@
74815 +/*
74816 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74817 + *
74818 + * Redistribution and use in source and binary forms, with or without
74819 + * modification, are permitted provided that the following conditions are met:
74820 + * * Redistributions of source code must retain the above copyright
74821 + * notice, this list of conditions and the following disclaimer.
74822 + * * Redistributions in binary form must reproduce the above copyright
74823 + * notice, this list of conditions and the following disclaimer in the
74824 + * documentation and/or other materials provided with the distribution.
74825 + * * Neither the name of Freescale Semiconductor nor the
74826 + * names of its contributors may be used to endorse or promote products
74827 + * derived from this software without specific prior written permission.
74828 + *
74829 + *
74830 + * ALTERNATIVELY, this software may be distributed under the terms of the
74831 + * GNU General Public License ("GPL") as published by the Free Software
74832 + * Foundation, either version 2 of that License or (at your option) any
74833 + * later version.
74834 + *
74835 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74836 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74837 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74838 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74839 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74840 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74841 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74842 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74843 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74844 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74845 + */
74846 +
74847 +
74848 +#ifndef __FM_HC_H
74849 +#define __FM_HC_H
74850 +
74851 +#include "std_ext.h"
74852 +#include "error_ext.h"
74853 +#include "fsl_fman_kg.h"
74854 +
74855 +#define __ERR_MODULE__ MODULE_FM_PCD
74856 +
74857 +
74858 +typedef struct t_FmHcParams {
74859 + t_Handle h_Fm;
74860 + t_Handle h_FmPcd;
74861 + t_FmPcdHcParams params;
74862 +} t_FmHcParams;
74863 +
74864 +
74865 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
74866 +void FmHcFree(t_Handle h_FmHc);
74867 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
74868 + uint8_t memId);
74869 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
74870 +
74871 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
74872 +
74873 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
74874 + t_Handle h_Scheme,
74875 + struct fman_kg_scheme_regs *p_SchemeRegs,
74876 + bool updateCounter);
74877 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
74878 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
74879 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
74880 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
74881 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
74882 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
74883 +
74884 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
74885 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
74886 +
74887 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
74888 +
74889 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
74890 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
74891 +
74892 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
74893 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
74894 +
74895 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
74896 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
74897 +
74898 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
74899 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
74900 +
74901 +t_Error FmHcPcdSync(t_Handle h_FmHc);
74902 +t_Handle FmHcGetPort(t_Handle h_FmHc);
74903 +
74904 +
74905 +
74906 +
74907 +#endif /* __FM_HC_H */
74908 --- /dev/null
74909 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
74910 @@ -0,0 +1,117 @@
74911 +/*
74912 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74913 + *
74914 + * Redistribution and use in source and binary forms, with or without
74915 + * modification, are permitted provided that the following conditions are met:
74916 + * * Redistributions of source code must retain the above copyright
74917 + * notice, this list of conditions and the following disclaimer.
74918 + * * Redistributions in binary form must reproduce the above copyright
74919 + * notice, this list of conditions and the following disclaimer in the
74920 + * documentation and/or other materials provided with the distribution.
74921 + * * Neither the name of Freescale Semiconductor nor the
74922 + * names of its contributors may be used to endorse or promote products
74923 + * derived from this software without specific prior written permission.
74924 + *
74925 + *
74926 + * ALTERNATIVELY, this software may be distributed under the terms of the
74927 + * GNU General Public License ("GPL") as published by the Free Software
74928 + * Foundation, either version 2 of that License or (at your option) any
74929 + * later version.
74930 + *
74931 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74932 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74933 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74934 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74935 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74936 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74937 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74938 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74939 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74940 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74941 + */
74942 +
74943 +
74944 +/******************************************************************************
74945 + @File fm_sp_common.h
74946 +
74947 + @Description FM SP ...
74948 +*//***************************************************************************/
74949 +#ifndef __FM_SP_COMMON_H
74950 +#define __FM_SP_COMMON_H
74951 +
74952 +#include "std_ext.h"
74953 +#include "error_ext.h"
74954 +#include "list_ext.h"
74955 +
74956 +#include "fm_ext.h"
74957 +#include "fm_pcd_ext.h"
74958 +#include "fsl_fman.h"
74959 +
74960 +/**************************************************************************//**
74961 + @Description defaults
74962 +*//***************************************************************************/
74963 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
74964 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
74965 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
74966 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
74967 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
74968 +
74969 +/**************************************************************************//**
74970 + @Description structure for defining internal context copying
74971 +*//***************************************************************************/
74972 +typedef struct
74973 +{
74974 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
74975 + context is copied to (Rx) or taken from (Tx, Op). */
74976 + uint8_t intContextOffset; /**< Offset within internal context to copy from
74977 + (Rx) or to copy to (Tx, Op). */
74978 + uint16_t size; /**< Internal offset size to be copied */
74979 +} t_FmSpIntContextDataCopy;
74980 +
74981 +/**************************************************************************//**
74982 + @Description struct for defining external buffer margins
74983 +*//***************************************************************************/
74984 +typedef struct {
74985 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
74986 + of the external buffer (must be divisible by 16) */
74987 + uint16_t endMargins; /**< number of bytes to be left at the end
74988 + of the external buffer(must be divisible by 16) */
74989 +} t_FmSpBufMargins;
74990 +
74991 +typedef struct {
74992 + uint32_t dataOffset;
74993 + uint32_t prsResultOffset;
74994 + uint32_t timeStampOffset;
74995 + uint32_t hashResultOffset;
74996 + uint32_t pcdInfoOffset;
74997 + uint32_t manipOffset;
74998 +} t_FmSpBufferOffsets;
74999 +
75000 +
75001 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
75002 + t_FmBufferPrefixContent *p_BufferPrefixContent,
75003 + t_FmSpBufMargins *p_FmPortBufMargins,
75004 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
75005 + uint8_t *internalBufferOffset);
75006 +
75007 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
75008 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
75009 + t_FmBackupBmPools *p_FmBackupBmPools,
75010 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
75011 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
75012 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
75013 +
75014 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
75015 + uint8_t hardwarePortId,
75016 + uint16_t numOfStorageProfiles,
75017 + uint16_t *base,
75018 + uint8_t *log2Num);
75019 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
75020 + t_Handle h_FmPort,
75021 + uint16_t relativeProfile,
75022 + uint16_t *p_AbsoluteId);
75023 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
75024 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
75025 +
75026 +
75027 +#endif /* __FM_SP_COMMON_H */
75028 --- /dev/null
75029 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
75030 @@ -0,0 +1,12 @@
75031 +#
75032 +# Makefile for the Freescale Ethernet controllers
75033 +#
75034 +ccflags-y += -DVERSION=\"\"
75035 +#
75036 +#Include netcomm SW specific definitions
75037 +
75038 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
75039 +
75040 +obj-y += fsl-ncsw-etc.o
75041 +
75042 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
75043 --- /dev/null
75044 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
75045 @@ -0,0 +1,95 @@
75046 +/*
75047 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75048 + *
75049 + * Redistribution and use in source and binary forms, with or without
75050 + * modification, are permitted provided that the following conditions are met:
75051 + * * Redistributions of source code must retain the above copyright
75052 + * notice, this list of conditions and the following disclaimer.
75053 + * * Redistributions in binary form must reproduce the above copyright
75054 + * notice, this list of conditions and the following disclaimer in the
75055 + * documentation and/or other materials provided with the distribution.
75056 + * * Neither the name of Freescale Semiconductor nor the
75057 + * names of its contributors may be used to endorse or promote products
75058 + * derived from this software without specific prior written permission.
75059 + *
75060 + *
75061 + * ALTERNATIVELY, this software may be distributed under the terms of the
75062 + * GNU General Public License ("GPL") as published by the Free Software
75063 + * Foundation, either version 2 of that License or (at your option) any
75064 + * later version.
75065 + *
75066 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75067 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75068 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75069 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75070 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75071 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75072 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75073 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75074 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75075 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75076 + */
75077 +
75078 +
75079 +/*
75080 +
75081 + @File error.c
75082 +
75083 + @Description General errors and events reporting utilities.
75084 +*//***************************************************************************/
75085 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
75086 +#include "error_ext.h"
75087 +
75088 +
75089 +const char *dbgLevelStrings[] =
75090 +{
75091 + "CRITICAL"
75092 + ,"MAJOR"
75093 + ,"MINOR"
75094 + ,"WARNING"
75095 + ,"INFO"
75096 + ,"TRACE"
75097 +};
75098 +
75099 +
75100 +char * ErrTypeStrings (e_ErrorType err)
75101 +{
75102 + switch (err)
75103 + {
75104 + case (E_OK): return "OK";
75105 + case (E_WRITE_FAILED): return "Write Access Failed";
75106 + case (E_NO_DEVICE): return "No Device";
75107 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
75108 + case (E_NO_MEMORY): return "Memory Allocation Failed";
75109 + case (E_INVALID_ADDRESS): return "Invalid Address";
75110 + case (E_BUSY): return "Resource Is Busy";
75111 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
75112 + case (E_INVALID_OPERATION): return "Invalid Operation";
75113 + case (E_INVALID_VALUE): return "Invalid Value";
75114 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
75115 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
75116 + case (E_INVALID_STATE): return "Invalid State";
75117 + case (E_INVALID_HANDLE): return "Invalid Handle";
75118 + case (E_INVALID_ID): return "Invalid ID";
75119 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
75120 + case (E_INVALID_SELECTION): return "Invalid Selection";
75121 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
75122 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
75123 + case (E_INVALID_CLOCK): return "Invalid Clock";
75124 + case (E_CONFLICT): return "Conflict In Settings";
75125 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
75126 + case (E_NOT_FOUND): return "Resource Not Found";
75127 + case (E_FULL): return "Resource Is Full";
75128 + case (E_EMPTY): return "Resource Is Empty";
75129 + case (E_ALREADY_FREE): return "Resource Already Free";
75130 + case (E_READ_FAILED): return "Read Access Failed";
75131 + case (E_INVALID_FRAME): return "Invalid Frame";
75132 + case (E_SEND_FAILED): return "Send Operation Failed";
75133 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
75134 + case (E_TIMEOUT): return "Operation Timed Out";
75135 + default:
75136 + break;
75137 + }
75138 + return NULL;
75139 +}
75140 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
75141 --- /dev/null
75142 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
75143 @@ -0,0 +1,71 @@
75144 +/*
75145 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75146 + *
75147 + * Redistribution and use in source and binary forms, with or without
75148 + * modification, are permitted provided that the following conditions are met:
75149 + * * Redistributions of source code must retain the above copyright
75150 + * notice, this list of conditions and the following disclaimer.
75151 + * * Redistributions in binary form must reproduce the above copyright
75152 + * notice, this list of conditions and the following disclaimer in the
75153 + * documentation and/or other materials provided with the distribution.
75154 + * * Neither the name of Freescale Semiconductor nor the
75155 + * names of its contributors may be used to endorse or promote products
75156 + * derived from this software without specific prior written permission.
75157 + *
75158 + *
75159 + * ALTERNATIVELY, this software may be distributed under the terms of the
75160 + * GNU General Public License ("GPL") as published by the Free Software
75161 + * Foundation, either version 2 of that License or (at your option) any
75162 + * later version.
75163 + *
75164 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75165 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75166 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75167 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75168 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75169 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75170 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75171 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75172 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75173 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75174 + */
75175 +
75176 +
75177 +/**************************************************************************//**
75178 +
75179 + @File list.c
75180 +
75181 + @Description Implementation of list.
75182 +*//***************************************************************************/
75183 +#include "std_ext.h"
75184 +#include "list_ext.h"
75185 +
75186 +
75187 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
75188 +{
75189 + t_List *p_First = LIST_FIRST(p_NewList);
75190 +
75191 + if (p_First != p_NewList)
75192 + {
75193 + t_List *p_Last = LIST_LAST(p_NewList);
75194 + t_List *p_Cur = LIST_NEXT(p_Head);
75195 +
75196 + LIST_PREV(p_First) = p_Head;
75197 + LIST_FIRST(p_Head) = p_First;
75198 + LIST_NEXT(p_Last) = p_Cur;
75199 + LIST_LAST(p_Cur) = p_Last;
75200 + }
75201 +}
75202 +
75203 +
75204 +int LIST_NumOfObjs(t_List *p_List)
75205 +{
75206 + t_List *p_Tmp;
75207 + int numOfObjs = 0;
75208 +
75209 + if (!LIST_IsEmpty(p_List))
75210 + LIST_FOR_EACH(p_Tmp, p_List)
75211 + numOfObjs++;
75212 +
75213 + return numOfObjs;
75214 +}
75215 --- /dev/null
75216 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
75217 @@ -0,0 +1,620 @@
75218 +/*
75219 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75220 + *
75221 + * Redistribution and use in source and binary forms, with or without
75222 + * modification, are permitted provided that the following conditions are met:
75223 + * * Redistributions of source code must retain the above copyright
75224 + * notice, this list of conditions and the following disclaimer.
75225 + * * Redistributions in binary form must reproduce the above copyright
75226 + * notice, this list of conditions and the following disclaimer in the
75227 + * documentation and/or other materials provided with the distribution.
75228 + * * Neither the name of Freescale Semiconductor nor the
75229 + * names of its contributors may be used to endorse or promote products
75230 + * derived from this software without specific prior written permission.
75231 + *
75232 + *
75233 + * ALTERNATIVELY, this software may be distributed under the terms of the
75234 + * GNU General Public License ("GPL") as published by the Free Software
75235 + * Foundation, either version 2 of that License or (at your option) any
75236 + * later version.
75237 + *
75238 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75239 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75240 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75241 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75242 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75243 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75244 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75245 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75246 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75247 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75248 + */
75249 +
75250 +
75251 +
75252 +#include "std_ext.h"
75253 +#include "xx_ext.h"
75254 +#include "memcpy_ext.h"
75255 +
75256 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
75257 +{
75258 + int i;
75259 +
75260 + for(i = 0; i < size; ++i)
75261 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
75262 +
75263 + return pDst;
75264 +}
75265 +
75266 +void * MemSet8(void* pDst, int c, uint32_t size)
75267 +{
75268 + int i;
75269 +
75270 + for(i = 0; i < size; ++i)
75271 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
75272 +
75273 + return pDst;
75274 +}
75275 +
75276 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
75277 +{
75278 + uint32_t leftAlign;
75279 + uint32_t rightAlign;
75280 + uint32_t lastWord;
75281 + uint32_t currWord;
75282 + uint32_t *p_Src32;
75283 + uint32_t *p_Dst32;
75284 + uint8_t *p_Src8;
75285 + uint8_t *p_Dst8;
75286 +
75287 + p_Src8 = (uint8_t*)(pSrc);
75288 + p_Dst8 = (uint8_t*)(pDst);
75289 + /* first copy byte by byte till the source first alignment
75290 + * this step is necessary to ensure we do not even try to access
75291 + * data which is before the source buffer, hence it is not ours.
75292 + */
75293 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75294 + {
75295 + *p_Dst8++ = *p_Src8++;
75296 + size--;
75297 + }
75298 +
75299 + /* align destination (possibly disaligning source)*/
75300 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75301 + {
75302 + *p_Dst8++ = *p_Src8++;
75303 + size--;
75304 + }
75305 +
75306 + /* dest is aligned and source is not necessarily aligned */
75307 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75308 + rightAlign = 32 - leftAlign;
75309 +
75310 +
75311 + if (leftAlign == 0)
75312 + {
75313 + /* source is also aligned */
75314 + p_Src32 = (uint32_t*)(p_Src8);
75315 + p_Dst32 = (uint32_t*)(p_Dst8);
75316 + while (size >> 2) /* size >= 4 */
75317 + {
75318 + *p_Dst32++ = *p_Src32++;
75319 + size -= 4;
75320 + }
75321 + p_Src8 = (uint8_t*)(p_Src32);
75322 + p_Dst8 = (uint8_t*)(p_Dst32);
75323 + }
75324 + else
75325 + {
75326 + /* source is not aligned (destination is aligned)*/
75327 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75328 + p_Dst32 = (uint32_t*)(p_Dst8);
75329 + lastWord = *p_Src32++;
75330 + while(size >> 3) /* size >= 8 */
75331 + {
75332 + currWord = *p_Src32;
75333 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
75334 + lastWord = currWord;
75335 + p_Src32++;
75336 + p_Dst32++;
75337 + size -= 4;
75338 + }
75339 + p_Dst8 = (uint8_t*)(p_Dst32);
75340 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75341 + }
75342 +
75343 + /* complete the left overs */
75344 + while (size--)
75345 + *p_Dst8++ = *p_Src8++;
75346 +
75347 + return pDst;
75348 +}
75349 +
75350 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
75351 +{
75352 + uint32_t leftAlign;
75353 + uint32_t rightAlign;
75354 + uint32_t lastWord;
75355 + uint32_t currWord;
75356 + uint32_t *p_Src32;
75357 + uint32_t *p_Dst32;
75358 + uint8_t *p_Src8;
75359 + uint8_t *p_Dst8;
75360 +
75361 + p_Src8 = (uint8_t*)(pSrc);
75362 + p_Dst8 = (uint8_t*)(pDst);
75363 + /* first copy byte by byte till the source first alignment
75364 + * this step is necessary to ensure we do not even try to access
75365 + * data which is before the source buffer, hence it is not ours.
75366 + */
75367 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75368 + {
75369 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
75370 + p_Dst8++;p_Src8++;
75371 + size--;
75372 + }
75373 +
75374 + /* align destination (possibly disaligning source)*/
75375 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75376 + {
75377 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
75378 + p_Dst8++;p_Src8++;
75379 + size--;
75380 + }
75381 +
75382 + /* dest is aligned and source is not necessarily aligned */
75383 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75384 + rightAlign = 32 - leftAlign;
75385 +
75386 + if (leftAlign == 0)
75387 + {
75388 + /* source is also aligned */
75389 + p_Src32 = (uint32_t*)(p_Src8);
75390 + p_Dst32 = (uint32_t*)(p_Dst8);
75391 + while (size >> 2) /* size >= 4 */
75392 + {
75393 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
75394 + p_Dst32++;p_Src32++;
75395 + size -= 4;
75396 + }
75397 + p_Src8 = (uint8_t*)(p_Src32);
75398 + p_Dst8 = (uint8_t*)(p_Dst32);
75399 + }
75400 + else
75401 + {
75402 + /* source is not aligned (destination is aligned)*/
75403 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75404 + p_Dst32 = (uint32_t*)(p_Dst8);
75405 + lastWord = GET_UINT32(*p_Src32);
75406 + p_Src32++;
75407 + while(size >> 3) /* size >= 8 */
75408 + {
75409 + currWord = GET_UINT32(*p_Src32);
75410 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
75411 + lastWord = currWord;
75412 + p_Src32++;p_Dst32++;
75413 + size -= 4;
75414 + }
75415 + p_Dst8 = (uint8_t*)(p_Dst32);
75416 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75417 + }
75418 +
75419 + /* complete the left overs */
75420 + while (size--)
75421 + {
75422 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
75423 + p_Dst8++;p_Src8++;
75424 + }
75425 +
75426 + return pDst;
75427 +}
75428 +
75429 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
75430 +{
75431 + uint32_t leftAlign;
75432 + uint32_t rightAlign;
75433 + uint32_t lastWord;
75434 + uint32_t currWord;
75435 + uint32_t *p_Src32;
75436 + uint32_t *p_Dst32;
75437 + uint8_t *p_Src8;
75438 + uint8_t *p_Dst8;
75439 +
75440 + p_Src8 = (uint8_t*)(pSrc);
75441 + p_Dst8 = (uint8_t*)(pDst);
75442 + /* first copy byte by byte till the source first alignment
75443 + * this step is necessary to ensure we do not even try to access
75444 + * data which is before the source buffer, hence it is not ours.
75445 + */
75446 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75447 + {
75448 + WRITE_UINT8(*p_Dst8, *p_Src8);
75449 + p_Dst8++;p_Src8++;
75450 + size--;
75451 + }
75452 +
75453 + /* align destination (possibly disaligning source)*/
75454 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75455 + {
75456 + WRITE_UINT8(*p_Dst8, *p_Src8);
75457 + p_Dst8++;p_Src8++;
75458 + size--;
75459 + }
75460 +
75461 + /* dest is aligned and source is not necessarily aligned */
75462 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75463 + rightAlign = 32 - leftAlign;
75464 +
75465 + if (leftAlign == 0)
75466 + {
75467 + /* source is also aligned */
75468 + p_Src32 = (uint32_t*)(p_Src8);
75469 + p_Dst32 = (uint32_t*)(p_Dst8);
75470 + while (size >> 2) /* size >= 4 */
75471 + {
75472 + WRITE_UINT32(*p_Dst32, *p_Src32);
75473 + p_Dst32++;p_Src32++;
75474 + size -= 4;
75475 + }
75476 + p_Src8 = (uint8_t*)(p_Src32);
75477 + p_Dst8 = (uint8_t*)(p_Dst32);
75478 + }
75479 + else
75480 + {
75481 + /* source is not aligned (destination is aligned)*/
75482 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75483 + p_Dst32 = (uint32_t*)(p_Dst8);
75484 + lastWord = *p_Src32++;
75485 + while(size >> 3) /* size >= 8 */
75486 + {
75487 + currWord = *p_Src32;
75488 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
75489 + lastWord = currWord;
75490 + p_Src32++;p_Dst32++;
75491 + size -= 4;
75492 + }
75493 + p_Dst8 = (uint8_t*)(p_Dst32);
75494 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75495 + }
75496 +
75497 + /* complete the left overs */
75498 + while (size--)
75499 + {
75500 + WRITE_UINT8(*p_Dst8, *p_Src8);
75501 + p_Dst8++;p_Src8++;
75502 + }
75503 +
75504 + return pDst;
75505 +}
75506 +
75507 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
75508 +{
75509 + uint32_t leftAlign;
75510 + uint32_t rightAlign;
75511 + uint32_t lastWord;
75512 + uint32_t currWord;
75513 + uint32_t *p_Src32;
75514 + uint32_t *p_Dst32;
75515 + uint8_t *p_Src8;
75516 + uint8_t *p_Dst8;
75517 +
75518 + p_Src8 = (uint8_t*)(pSrc);
75519 + p_Dst8 = (uint8_t*)(pDst);
75520 + /* first copy byte by byte till the source first alignment
75521 + * this step is necessary to ensure we do not even try to access
75522 + * data which is before the source buffer, hence it is not ours.
75523 + */
75524 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75525 + {
75526 + *p_Dst8 = GET_UINT8(*p_Src8);
75527 + p_Dst8++;p_Src8++;
75528 + size--;
75529 + }
75530 +
75531 + /* align destination (possibly disaligning source)*/
75532 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75533 + {
75534 + *p_Dst8 = GET_UINT8(*p_Src8);
75535 + p_Dst8++;p_Src8++;
75536 + size--;
75537 + }
75538 +
75539 + /* dest is aligned and source is not necessarily aligned */
75540 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75541 + rightAlign = 32 - leftAlign;
75542 +
75543 + if (leftAlign == 0)
75544 + {
75545 + /* source is also aligned */
75546 + p_Src32 = (uint32_t*)(p_Src8);
75547 + p_Dst32 = (uint32_t*)(p_Dst8);
75548 + while (size >> 2) /* size >= 4 */
75549 + {
75550 + *p_Dst32 = GET_UINT32(*p_Src32);
75551 + p_Dst32++;p_Src32++;
75552 + size -= 4;
75553 + }
75554 + p_Src8 = (uint8_t*)(p_Src32);
75555 + p_Dst8 = (uint8_t*)(p_Dst32);
75556 + }
75557 + else
75558 + {
75559 + /* source is not aligned (destination is aligned)*/
75560 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75561 + p_Dst32 = (uint32_t*)(p_Dst8);
75562 + lastWord = GET_UINT32(*p_Src32);
75563 + p_Src32++;
75564 + while(size >> 3) /* size >= 8 */
75565 + {
75566 + currWord = GET_UINT32(*p_Src32);
75567 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
75568 + lastWord = currWord;
75569 + p_Src32++;p_Dst32++;
75570 + size -= 4;
75571 + }
75572 + p_Dst8 = (uint8_t*)(p_Dst32);
75573 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75574 + }
75575 +
75576 + /* complete the left overs */
75577 + while (size--)
75578 + {
75579 + *p_Dst8 = GET_UINT8(*p_Src8);
75580 + p_Dst8++;p_Src8++;
75581 + }
75582 +
75583 + return pDst;
75584 +}
75585 +
75586 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
75587 +{
75588 + uint32_t leftAlign;
75589 + uint32_t rightAlign;
75590 + uint64_t lastWord;
75591 + uint64_t currWord;
75592 + uint64_t *pSrc64;
75593 + uint64_t *pDst64;
75594 + uint8_t *p_Src8;
75595 + uint8_t *p_Dst8;
75596 +
75597 + p_Src8 = (uint8_t*)(pSrc);
75598 + p_Dst8 = (uint8_t*)(pDst);
75599 + /* first copy byte by byte till the source first alignment
75600 + * this step is necessarily to ensure we do not even try to access
75601 + * data which is before the source buffer, hence it is not ours.
75602 + */
75603 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
75604 + {
75605 + *p_Dst8++ = *p_Src8++;
75606 + size--;
75607 + }
75608 +
75609 + /* align destination (possibly disaligning source)*/
75610 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
75611 + {
75612 + *p_Dst8++ = *p_Src8++;
75613 + size--;
75614 + }
75615 +
75616 + /* dest is aligned and source is not necessarily aligned */
75617 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
75618 + rightAlign = 64 - leftAlign;
75619 +
75620 +
75621 + if (leftAlign == 0)
75622 + {
75623 + /* source is also aligned */
75624 + pSrc64 = (uint64_t*)(p_Src8);
75625 + pDst64 = (uint64_t*)(p_Dst8);
75626 + while (size >> 3) /* size >= 8 */
75627 + {
75628 + *pDst64++ = *pSrc64++;
75629 + size -= 8;
75630 + }
75631 + p_Src8 = (uint8_t*)(pSrc64);
75632 + p_Dst8 = (uint8_t*)(pDst64);
75633 + }
75634 + else
75635 + {
75636 + /* source is not aligned (destination is aligned)*/
75637 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
75638 + pDst64 = (uint64_t*)(p_Dst8);
75639 + lastWord = *pSrc64++;
75640 + while(size >> 4) /* size >= 16 */
75641 + {
75642 + currWord = *pSrc64;
75643 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
75644 + lastWord = currWord;
75645 + pSrc64++;
75646 + pDst64++;
75647 + size -= 8;
75648 + }
75649 + p_Dst8 = (uint8_t*)(pDst64);
75650 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
75651 + }
75652 +
75653 + /* complete the left overs */
75654 + while (size--)
75655 + *p_Dst8++ = *p_Src8++;
75656 +
75657 + return pDst;
75658 +}
75659 +
75660 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
75661 +{
75662 + uint32_t val32;
75663 + uint32_t *p_Dst32;
75664 + uint8_t *p_Dst8;
75665 +
75666 + p_Dst8 = (uint8_t*)(pDst);
75667 +
75668 + /* generate four 8-bit val's in 32-bit container */
75669 + val32 = (uint32_t) val;
75670 + val32 |= (val32 << 8);
75671 + val32 |= (val32 << 16);
75672 +
75673 + /* align destination to 32 */
75674 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75675 + {
75676 + *p_Dst8++ = val;
75677 + size--;
75678 + }
75679 +
75680 + /* 32-bit chunks */
75681 + p_Dst32 = (uint32_t*)(p_Dst8);
75682 + while (size >> 2) /* size >= 4 */
75683 + {
75684 + *p_Dst32++ = val32;
75685 + size -= 4;
75686 + }
75687 +
75688 + /* complete the leftovers */
75689 + p_Dst8 = (uint8_t*)(p_Dst32);
75690 + while (size--)
75691 + *p_Dst8++ = val;
75692 +
75693 + return pDst;
75694 +}
75695 +
75696 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
75697 +{
75698 + uint32_t val32;
75699 + uint32_t *p_Dst32;
75700 + uint8_t *p_Dst8;
75701 +
75702 + p_Dst8 = (uint8_t*)(pDst);
75703 +
75704 + /* generate four 8-bit val's in 32-bit container */
75705 + val32 = (uint32_t) val;
75706 + val32 |= (val32 << 8);
75707 + val32 |= (val32 << 16);
75708 +
75709 + /* align destination to 32 */
75710 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75711 + {
75712 + WRITE_UINT8(*p_Dst8, val);
75713 + p_Dst8++;
75714 + size--;
75715 + }
75716 +
75717 + /* 32-bit chunks */
75718 + p_Dst32 = (uint32_t*)(p_Dst8);
75719 + while (size >> 2) /* size >= 4 */
75720 + {
75721 + WRITE_UINT32(*p_Dst32, val32);
75722 + p_Dst32++;
75723 + size -= 4;
75724 + }
75725 +
75726 + /* complete the leftovers */
75727 + p_Dst8 = (uint8_t*)(p_Dst32);
75728 + while (size--)
75729 + {
75730 + WRITE_UINT8(*p_Dst8, val);
75731 + p_Dst8++;
75732 + }
75733 +
75734 + return pDst;
75735 +}
75736 +
75737 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
75738 +{
75739 + uint64_t val64;
75740 + uint64_t *pDst64;
75741 + uint8_t *p_Dst8;
75742 +
75743 + p_Dst8 = (uint8_t*)(pDst);
75744 +
75745 + /* generate four 8-bit val's in 32-bit container */
75746 + val64 = (uint64_t) val;
75747 + val64 |= (val64 << 8);
75748 + val64 |= (val64 << 16);
75749 + val64 |= (val64 << 24);
75750 + val64 |= (val64 << 32);
75751 +
75752 + /* align destination to 64 */
75753 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
75754 + {
75755 + *p_Dst8++ = val;
75756 + size--;
75757 + }
75758 +
75759 + /* 64-bit chunks */
75760 + pDst64 = (uint64_t*)(p_Dst8);
75761 + while (size >> 4) /* size >= 8 */
75762 + {
75763 + *pDst64++ = val64;
75764 + size -= 8;
75765 + }
75766 +
75767 + /* complete the leftovers */
75768 + p_Dst8 = (uint8_t*)(pDst64);
75769 + while (size--)
75770 + *p_Dst8++ = val;
75771 +
75772 + return pDst;
75773 +}
75774 +
75775 +void MemDisp(uint8_t *p, int size)
75776 +{
75777 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
75778 + uint8_t *p_Limit;
75779 +
75780 + if (space)
75781 + {
75782 + p_Limit = (p - space + 4);
75783 +
75784 + XX_Print("0x%08X: ", (p - space));
75785 +
75786 + while (space--)
75787 + {
75788 + XX_Print("--");
75789 + }
75790 + while (size && (p < p_Limit))
75791 + {
75792 + XX_Print("%02x", *(uint8_t*)p);
75793 + size--;
75794 + p++;
75795 + }
75796 +
75797 + XX_Print(" ");
75798 + p_Limit += 12;
75799 +
75800 + while ((size > 3) && (p < p_Limit))
75801 + {
75802 + XX_Print("%08x ", *(uint32_t*)p);
75803 + size -= 4;
75804 + p += 4;
75805 + }
75806 + XX_Print("\r\n");
75807 + }
75808 +
75809 + while (size > 15)
75810 + {
75811 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
75812 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
75813 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
75814 + size -= 16;
75815 + p += 16;
75816 + }
75817 +
75818 + if (size)
75819 + {
75820 + XX_Print("0x%08X: ", p);
75821 +
75822 + while (size > 3)
75823 + {
75824 + XX_Print("%08x ", *(uint32_t *)p);
75825 + size -= 4;
75826 + p += 4;
75827 + }
75828 + while (size)
75829 + {
75830 + XX_Print("%02x", *(uint8_t *)p);
75831 + size--;
75832 + p++;
75833 + }
75834 +
75835 + XX_Print("\r\n");
75836 + }
75837 +}
75838 --- /dev/null
75839 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
75840 @@ -0,0 +1,1155 @@
75841 +/*
75842 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75843 + *
75844 + * Redistribution and use in source and binary forms, with or without
75845 + * modification, are permitted provided that the following conditions are met:
75846 + * * Redistributions of source code must retain the above copyright
75847 + * notice, this list of conditions and the following disclaimer.
75848 + * * Redistributions in binary form must reproduce the above copyright
75849 + * notice, this list of conditions and the following disclaimer in the
75850 + * documentation and/or other materials provided with the distribution.
75851 + * * Neither the name of Freescale Semiconductor nor the
75852 + * names of its contributors may be used to endorse or promote products
75853 + * derived from this software without specific prior written permission.
75854 + *
75855 + *
75856 + * ALTERNATIVELY, this software may be distributed under the terms of the
75857 + * GNU General Public License ("GPL") as published by the Free Software
75858 + * Foundation, either version 2 of that License or (at your option) any
75859 + * later version.
75860 + *
75861 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75862 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75863 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75864 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75865 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75866 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75867 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75868 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75869 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75870 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75871 + */
75872 +
75873 +
75874 +#include "string_ext.h"
75875 +#include "error_ext.h"
75876 +#include "std_ext.h"
75877 +#include "part_ext.h"
75878 +#include "xx_ext.h"
75879 +
75880 +#include "mm.h"
75881 +
75882 +
75883 +
75884 +
75885 +/**********************************************************************
75886 + * MM internal routines set *
75887 + **********************************************************************/
75888 +
75889 +/****************************************************************
75890 + * Routine: CreateBusyBlock
75891 + *
75892 + * Description:
75893 + * Initializes a new busy block of "size" bytes and started
75894 + * rom "base" address. Each busy block has a name that
75895 + * specified the purpose of the memory allocation.
75896 + *
75897 + * Arguments:
75898 + * base - base address of the busy block
75899 + * size - size of the busy block
75900 + * name - name that specified the busy block
75901 + *
75902 + * Return value:
75903 + * A pointer to new created structure returned on success;
75904 + * Otherwise, NULL.
75905 + ****************************************************************/
75906 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
75907 +{
75908 + t_BusyBlock *p_BusyBlock;
75909 + uint32_t n;
75910 +
75911 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
75912 + if ( !p_BusyBlock )
75913 + {
75914 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75915 + return NULL;
75916 + }
75917 +
75918 + p_BusyBlock->base = base;
75919 + p_BusyBlock->end = base + size;
75920 +
75921 + n = strlen(name);
75922 + if (n >= MM_MAX_NAME_LEN)
75923 + n = MM_MAX_NAME_LEN - 1;
75924 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
75925 + p_BusyBlock->name[n] = '\0';
75926 + p_BusyBlock->p_Next = 0;
75927 +
75928 + return p_BusyBlock;
75929 +}
75930 +
75931 +/****************************************************************
75932 + * Routine: CreateNewBlock
75933 + *
75934 + * Description:
75935 + * Initializes a new memory block of "size" bytes and started
75936 + * from "base" address.
75937 + *
75938 + * Arguments:
75939 + * base - base address of the memory block
75940 + * size - size of the memory block
75941 + *
75942 + * Return value:
75943 + * A pointer to new created structure returned on success;
75944 + * Otherwise, NULL.
75945 + ****************************************************************/
75946 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
75947 +{
75948 + t_MemBlock *p_MemBlock;
75949 +
75950 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
75951 + if ( !p_MemBlock )
75952 + {
75953 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75954 + return NULL;
75955 + }
75956 +
75957 + p_MemBlock->base = base;
75958 + p_MemBlock->end = base+size;
75959 + p_MemBlock->p_Next = 0;
75960 +
75961 + return p_MemBlock;
75962 +}
75963 +
75964 +/****************************************************************
75965 + * Routine: CreateFreeBlock
75966 + *
75967 + * Description:
75968 + * Initializes a new free block of of "size" bytes and
75969 + * started from "base" address.
75970 + *
75971 + * Arguments:
75972 + * base - base address of the free block
75973 + * size - size of the free block
75974 + *
75975 + * Return value:
75976 + * A pointer to new created structure returned on success;
75977 + * Otherwise, NULL.
75978 + ****************************************************************/
75979 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
75980 +{
75981 + t_FreeBlock *p_FreeBlock;
75982 +
75983 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
75984 + if ( !p_FreeBlock )
75985 + {
75986 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75987 + return NULL;
75988 + }
75989 +
75990 + p_FreeBlock->base = base;
75991 + p_FreeBlock->end = base + size;
75992 + p_FreeBlock->p_Next = 0;
75993 +
75994 + return p_FreeBlock;
75995 +}
75996 +
75997 +/****************************************************************
75998 + * Routine: AddFree
75999 + *
76000 + * Description:
76001 + * Adds a new free block to the free lists. It updates each
76002 + * free list to include a new free block.
76003 + * Note, that all free block in each free list are ordered
76004 + * by their base address.
76005 + *
76006 + * Arguments:
76007 + * p_MM - pointer to the MM object
76008 + * base - base address of a given free block
76009 + * end - end address of a given free block
76010 + *
76011 + * Return value:
76012 + *
76013 + *
76014 + ****************************************************************/
76015 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
76016 +{
76017 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
76018 + uint64_t alignment;
76019 + uint64_t alignBase;
76020 + int i;
76021 +
76022 + /* Updates free lists to include a just released block */
76023 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76024 + {
76025 + p_PrevB = p_NewB = 0;
76026 + p_CurrB = p_MM->freeBlocks[i];
76027 +
76028 + alignment = (uint64_t)(0x1 << i);
76029 + alignBase = MAKE_ALIGNED(base, alignment);
76030 +
76031 + /* Goes to the next free list if there is no block to free */
76032 + if (alignBase >= end)
76033 + continue;
76034 +
76035 + /* Looks for a free block that should be updated */
76036 + while ( p_CurrB )
76037 + {
76038 + if ( alignBase <= p_CurrB->end )
76039 + {
76040 + if ( end > p_CurrB->end )
76041 + {
76042 + t_FreeBlock *p_NextB;
76043 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
76044 + {
76045 + p_NextB = p_CurrB->p_Next;
76046 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
76047 + XX_Free(p_NextB);
76048 + }
76049 +
76050 + p_NextB = p_CurrB->p_Next;
76051 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
76052 + {
76053 + p_CurrB->end = end;
76054 + }
76055 + else
76056 + {
76057 + p_CurrB->end = p_NextB->end;
76058 + p_CurrB->p_Next = p_NextB->p_Next;
76059 + XX_Free(p_NextB);
76060 + }
76061 + }
76062 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
76063 + {
76064 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
76065 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76066 +
76067 + p_NewB->p_Next = p_CurrB;
76068 + if (p_PrevB)
76069 + p_PrevB->p_Next = p_NewB;
76070 + else
76071 + p_MM->freeBlocks[i] = p_NewB;
76072 + break;
76073 + }
76074 +
76075 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
76076 + {
76077 + p_CurrB->base = alignBase;
76078 + }
76079 +
76080 + /* if size of the free block is less then alignment
76081 + * deletes that free block from the free list. */
76082 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
76083 + {
76084 + if ( p_PrevB )
76085 + p_PrevB->p_Next = p_CurrB->p_Next;
76086 + else
76087 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
76088 + XX_Free(p_CurrB);
76089 + p_CurrB = NULL;
76090 + }
76091 + break;
76092 + }
76093 + else
76094 + {
76095 + p_PrevB = p_CurrB;
76096 + p_CurrB = p_CurrB->p_Next;
76097 + }
76098 + }
76099 +
76100 + /* If no free block found to be updated, insert a new free block
76101 + * to the end of the free list.
76102 + */
76103 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
76104 + {
76105 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
76106 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76107 +
76108 + if (p_PrevB)
76109 + p_PrevB->p_Next = p_NewB;
76110 + else
76111 + p_MM->freeBlocks[i] = p_NewB;
76112 + }
76113 +
76114 + /* Update boundaries of the new free block */
76115 + if ((alignment == 1) && !p_NewB)
76116 + {
76117 + if ( p_CurrB && base > p_CurrB->base )
76118 + base = p_CurrB->base;
76119 + if ( p_CurrB && end < p_CurrB->end )
76120 + end = p_CurrB->end;
76121 + }
76122 + }
76123 +
76124 + return (E_OK);
76125 +}
76126 +
76127 +/****************************************************************
76128 + * Routine: CutFree
76129 + *
76130 + * Description:
76131 + * Cuts a free block from holdBase to holdEnd from the free lists.
76132 + * That is, it updates all free lists of the MM object do
76133 + * not include a block of memory from holdBase to holdEnd.
76134 + * For each free lists it seek for a free block that holds
76135 + * either holdBase or holdEnd. If such block is found it updates it.
76136 + *
76137 + * Arguments:
76138 + * p_MM - pointer to the MM object
76139 + * holdBase - base address of the allocated block
76140 + * holdEnd - end address of the allocated block
76141 + *
76142 + * Return value:
76143 + * E_OK is returned on success,
76144 + * otherwise returns an error code.
76145 + *
76146 + ****************************************************************/
76147 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
76148 +{
76149 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
76150 + uint64_t alignBase, base, end;
76151 + uint64_t alignment;
76152 + int i;
76153 +
76154 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76155 + {
76156 + p_PrevB = p_NewB = 0;
76157 + p_CurrB = p_MM->freeBlocks[i];
76158 +
76159 + alignment = (uint64_t)(0x1 << i);
76160 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
76161 +
76162 + while ( p_CurrB )
76163 + {
76164 + base = p_CurrB->base;
76165 + end = p_CurrB->end;
76166 +
76167 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
76168 + {
76169 + if ( alignBase >= end ||
76170 + (alignBase < end && ((end-alignBase) < alignment)) )
76171 + {
76172 + if (p_PrevB)
76173 + p_PrevB->p_Next = p_CurrB->p_Next;
76174 + else
76175 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
76176 + XX_Free(p_CurrB);
76177 + }
76178 + else
76179 + {
76180 + p_CurrB->base = alignBase;
76181 + }
76182 + break;
76183 + }
76184 + else if ( (holdBase > base) && (holdEnd <= end) )
76185 + {
76186 + if ( (holdBase-base) >= alignment )
76187 + {
76188 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
76189 + {
76190 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
76191 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76192 + p_NewB->p_Next = p_CurrB->p_Next;
76193 + p_CurrB->p_Next = p_NewB;
76194 + }
76195 + p_CurrB->end = holdBase;
76196 + }
76197 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
76198 + {
76199 + p_CurrB->base = alignBase;
76200 + }
76201 + else
76202 + {
76203 + if (p_PrevB)
76204 + p_PrevB->p_Next = p_CurrB->p_Next;
76205 + else
76206 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
76207 + XX_Free(p_CurrB);
76208 + }
76209 + break;
76210 + }
76211 + else
76212 + {
76213 + p_PrevB = p_CurrB;
76214 + p_CurrB = p_CurrB->p_Next;
76215 + }
76216 + }
76217 + }
76218 +
76219 + return (E_OK);
76220 +}
76221 +
76222 +/****************************************************************
76223 + * Routine: AddBusy
76224 + *
76225 + * Description:
76226 + * Adds a new busy block to the list of busy blocks. Note,
76227 + * that all busy blocks are ordered by their base address in
76228 + * the busy list.
76229 + *
76230 + * Arguments:
76231 + * MM - handler to the MM object
76232 + * p_NewBusyB - pointer to the a busy block
76233 + *
76234 + * Return value:
76235 + * None.
76236 + *
76237 + ****************************************************************/
76238 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
76239 +{
76240 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
76241 +
76242 + /* finds a place of a new busy block in the list of busy blocks */
76243 + p_PrevBusyB = 0;
76244 + p_CurrBusyB = p_MM->busyBlocks;
76245 +
76246 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
76247 + {
76248 + p_PrevBusyB = p_CurrBusyB;
76249 + p_CurrBusyB = p_CurrBusyB->p_Next;
76250 + }
76251 +
76252 + /* insert the new busy block into the list of busy blocks */
76253 + if ( p_CurrBusyB )
76254 + p_NewBusyB->p_Next = p_CurrBusyB;
76255 + if ( p_PrevBusyB )
76256 + p_PrevBusyB->p_Next = p_NewBusyB;
76257 + else
76258 + p_MM->busyBlocks = p_NewBusyB;
76259 +}
76260 +
76261 +/****************************************************************
76262 + * Routine: CutBusy
76263 + *
76264 + * Description:
76265 + * Cuts a block from base to end from the list of busy blocks.
76266 + * This is done by updating the list of busy blocks do not
76267 + * include a given block, that block is going to be free. If a
76268 + * given block is a part of some other busy block, so that
76269 + * busy block is updated. If there are number of busy blocks
76270 + * included in the given block, so all that blocks are removed
76271 + * from the busy list and the end blocks are updated.
76272 + * If the given block devides some block into two parts, a new
76273 + * busy block is added to the busy list.
76274 + *
76275 + * Arguments:
76276 + * p_MM - pointer to the MM object
76277 + * base - base address of a given busy block
76278 + * end - end address of a given busy block
76279 + *
76280 + * Return value:
76281 + * E_OK on success, E_NOMEMORY otherwise.
76282 + *
76283 + ****************************************************************/
76284 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
76285 +{
76286 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
76287 +
76288 + p_CurrB = p_MM->busyBlocks;
76289 + p_PrevB = p_NewB = 0;
76290 +
76291 + while ( p_CurrB )
76292 + {
76293 + if ( base < p_CurrB->end )
76294 + {
76295 + if ( end > p_CurrB->end )
76296 + {
76297 + t_BusyBlock *p_NextB;
76298 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
76299 + {
76300 + p_NextB = p_CurrB->p_Next;
76301 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
76302 + XX_Free(p_NextB);
76303 + }
76304 +
76305 + p_NextB = p_CurrB->p_Next;
76306 + if ( p_NextB && end > p_NextB->base )
76307 + {
76308 + p_NextB->base = end;
76309 + }
76310 + }
76311 +
76312 + if ( base <= p_CurrB->base )
76313 + {
76314 + if ( end < p_CurrB->end && end > p_CurrB->base )
76315 + {
76316 + p_CurrB->base = end;
76317 + }
76318 + else if ( end >= p_CurrB->end )
76319 + {
76320 + if ( p_PrevB )
76321 + p_PrevB->p_Next = p_CurrB->p_Next;
76322 + else
76323 + p_MM->busyBlocks = p_CurrB->p_Next;
76324 + XX_Free(p_CurrB);
76325 + }
76326 + }
76327 + else
76328 + {
76329 + if ( end < p_CurrB->end && end > p_CurrB->base )
76330 + {
76331 + if ((p_NewB = CreateBusyBlock(end,
76332 + p_CurrB->end-end,
76333 + p_CurrB->name)) == NULL)
76334 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76335 + p_NewB->p_Next = p_CurrB->p_Next;
76336 + p_CurrB->p_Next = p_NewB;
76337 + }
76338 + p_CurrB->end = base;
76339 + }
76340 + break;
76341 + }
76342 + else
76343 + {
76344 + p_PrevB = p_CurrB;
76345 + p_CurrB = p_CurrB->p_Next;
76346 + }
76347 + }
76348 +
76349 + return (E_OK);
76350 +}
76351 +
76352 +/****************************************************************
76353 + * Routine: MmGetGreaterAlignment
76354 + *
76355 + * Description:
76356 + * Allocates a block of memory according to the given size
76357 + * and the alignment. That routine is called from the MM_Get
76358 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
76359 + * In that case, it goes over free blocks of 64 byte align list
76360 + * and checks if it has the required size of bytes of the required
76361 + * alignment. If no blocks found returns ILLEGAL_BASE.
76362 + * After the block is found and data is allocated, it calls
76363 + * the internal CutFree routine to update all free lists
76364 + * do not include a just allocated block. Of course, each
76365 + * free list contains a free blocks with the same alignment.
76366 + * It is also creates a busy block that holds
76367 + * information about an allocated block.
76368 + *
76369 + * Arguments:
76370 + * MM - handle to the MM object
76371 + * size - size of the MM
76372 + * alignment - index as a power of two defines
76373 + * a required alignment that is greater then 64.
76374 + * name - the name that specifies an allocated block.
76375 + *
76376 + * Return value:
76377 + * base address of an allocated block.
76378 + * ILLEGAL_BASE if can't allocate a block
76379 + *
76380 + ****************************************************************/
76381 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
76382 +{
76383 + t_FreeBlock *p_FreeB;
76384 + t_BusyBlock *p_NewBusyB;
76385 + uint64_t holdBase, holdEnd, alignBase = 0;
76386 +
76387 + /* goes over free blocks of the 64 byte alignment list
76388 + and look for a block of the suitable size and
76389 + base address according to the alignment. */
76390 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
76391 +
76392 + while ( p_FreeB )
76393 + {
76394 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
76395 +
76396 + /* the block is found if the aligned base inside the block
76397 + * and has the anough size. */
76398 + if ( alignBase >= p_FreeB->base &&
76399 + alignBase < p_FreeB->end &&
76400 + size <= (p_FreeB->end - alignBase) )
76401 + break;
76402 + else
76403 + p_FreeB = p_FreeB->p_Next;
76404 + }
76405 +
76406 + /* If such block isn't found */
76407 + if ( !p_FreeB )
76408 + return (uint64_t)(ILLEGAL_BASE);
76409 +
76410 + holdBase = alignBase;
76411 + holdEnd = alignBase + size;
76412 +
76413 + /* init a new busy block */
76414 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
76415 + return (uint64_t)(ILLEGAL_BASE);
76416 +
76417 + /* calls Update routine to update a lists of free blocks */
76418 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
76419 + {
76420 + XX_Free(p_NewBusyB);
76421 + return (uint64_t)(ILLEGAL_BASE);
76422 + }
76423 +
76424 + /* insert the new busy block into the list of busy blocks */
76425 + AddBusy ( p_MM, p_NewBusyB );
76426 +
76427 + return (holdBase);
76428 +}
76429 +
76430 +
76431 +/**********************************************************************
76432 + * MM API routines set *
76433 + **********************************************************************/
76434 +
76435 +/*****************************************************************************/
76436 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
76437 +{
76438 + t_MM *p_MM;
76439 + uint64_t newBase, newSize;
76440 + int i;
76441 +
76442 + if (!size)
76443 + {
76444 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
76445 + }
76446 +
76447 + /* Initializes a new MM object */
76448 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
76449 + if (!p_MM)
76450 + {
76451 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76452 + }
76453 +
76454 + p_MM->h_Spinlock = XX_InitSpinlock();
76455 + if (!p_MM->h_Spinlock)
76456 + {
76457 + XX_Free(p_MM);
76458 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
76459 + }
76460 +
76461 + /* Initializes counter of free memory to total size */
76462 + p_MM->freeMemSize = size;
76463 +
76464 + /* A busy list is empty */
76465 + p_MM->busyBlocks = 0;
76466 +
76467 + /* Initializes a new memory block */
76468 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
76469 + {
76470 + MM_Free(p_MM);
76471 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76472 + }
76473 +
76474 + /* Initializes a new free block for each free list*/
76475 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76476 + {
76477 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
76478 + newSize = size - (newBase - base);
76479 +
76480 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
76481 + {
76482 + MM_Free(p_MM);
76483 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76484 + }
76485 + }
76486 +
76487 + *h_MM = p_MM;
76488 +
76489 + return (E_OK);
76490 +}
76491 +
76492 +/*****************************************************************************/
76493 +void MM_Free(t_Handle h_MM)
76494 +{
76495 + t_MM *p_MM = (t_MM *)h_MM;
76496 + t_MemBlock *p_MemBlock;
76497 + t_BusyBlock *p_BusyBlock;
76498 + t_FreeBlock *p_FreeBlock;
76499 + void *p_Block;
76500 + int i;
76501 +
76502 + ASSERT_COND(p_MM);
76503 +
76504 + /* release memory allocated for busy blocks */
76505 + p_BusyBlock = p_MM->busyBlocks;
76506 + while ( p_BusyBlock )
76507 + {
76508 + p_Block = p_BusyBlock;
76509 + p_BusyBlock = p_BusyBlock->p_Next;
76510 + XX_Free(p_Block);
76511 + }
76512 +
76513 + /* release memory allocated for free blocks */
76514 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76515 + {
76516 + p_FreeBlock = p_MM->freeBlocks[i];
76517 + while ( p_FreeBlock )
76518 + {
76519 + p_Block = p_FreeBlock;
76520 + p_FreeBlock = p_FreeBlock->p_Next;
76521 + XX_Free(p_Block);
76522 + }
76523 + }
76524 +
76525 + /* release memory allocated for memory blocks */
76526 + p_MemBlock = p_MM->memBlocks;
76527 + while ( p_MemBlock )
76528 + {
76529 + p_Block = p_MemBlock;
76530 + p_MemBlock = p_MemBlock->p_Next;
76531 + XX_Free(p_Block);
76532 + }
76533 +
76534 + if (p_MM->h_Spinlock)
76535 + XX_FreeSpinlock(p_MM->h_Spinlock);
76536 +
76537 + /* release memory allocated for MM object itself */
76538 + XX_Free(p_MM);
76539 +}
76540 +
76541 +/*****************************************************************************/
76542 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
76543 +{
76544 + t_MM *p_MM = (t_MM *)h_MM;
76545 + t_FreeBlock *p_FreeB;
76546 + t_BusyBlock *p_NewBusyB;
76547 + uint64_t holdBase, holdEnd, j, i = 0;
76548 + uint32_t intFlags;
76549 +
76550 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
76551 +
76552 + /* checks that alignment value is greater then zero */
76553 + if (alignment == 0)
76554 + {
76555 + alignment = 1;
76556 + }
76557 +
76558 + j = alignment;
76559 +
76560 + /* checks if alignment is a power of two, if it correct and if the
76561 + required size is multiple of the given alignment. */
76562 + while ((j & 0x1) == 0)
76563 + {
76564 + i++;
76565 + j = j >> 1;
76566 + }
76567 +
76568 + /* if the given alignment isn't power of two, returns an error */
76569 + if (j != 1)
76570 + {
76571 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
76572 + return (uint64_t)ILLEGAL_BASE;
76573 + }
76574 +
76575 + if (i > MM_MAX_ALIGNMENT)
76576 + {
76577 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
76578 + }
76579 +
76580 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76581 + /* look for a block of the size greater or equal to the required size. */
76582 + p_FreeB = p_MM->freeBlocks[i];
76583 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
76584 + p_FreeB = p_FreeB->p_Next;
76585 +
76586 + /* If such block is found */
76587 + if ( !p_FreeB )
76588 + {
76589 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76590 + return (uint64_t)(ILLEGAL_BASE);
76591 + }
76592 +
76593 + holdBase = p_FreeB->base;
76594 + holdEnd = holdBase + size;
76595 +
76596 + /* init a new busy block */
76597 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
76598 + {
76599 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76600 + return (uint64_t)(ILLEGAL_BASE);
76601 + }
76602 +
76603 + /* calls Update routine to update a lists of free blocks */
76604 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
76605 + {
76606 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76607 + XX_Free(p_NewBusyB);
76608 + return (uint64_t)(ILLEGAL_BASE);
76609 + }
76610 +
76611 + /* Decreasing the allocated memory size from free memory size */
76612 + p_MM->freeMemSize -= size;
76613 +
76614 + /* insert the new busy block into the list of busy blocks */
76615 + AddBusy ( p_MM, p_NewBusyB );
76616 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76617 +
76618 + return (holdBase);
76619 +}
76620 +
76621 +/*****************************************************************************/
76622 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
76623 +{
76624 + t_MM *p_MM = (t_MM *)h_MM;
76625 + t_FreeBlock *p_FreeB;
76626 + t_BusyBlock *p_NewBusyB;
76627 + uint32_t intFlags;
76628 + bool blockIsFree = FALSE;
76629 +
76630 + ASSERT_COND(p_MM);
76631 +
76632 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76633 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
76634 + free list with alignment 1 */
76635 +
76636 + while ( p_FreeB )
76637 + {
76638 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
76639 + {
76640 + blockIsFree = TRUE;
76641 + break;
76642 + }
76643 + else
76644 + p_FreeB = p_FreeB->p_Next;
76645 + }
76646 +
76647 + if ( !blockIsFree )
76648 + {
76649 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76650 + return (uint64_t)(ILLEGAL_BASE);
76651 + }
76652 +
76653 + /* init a new busy block */
76654 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
76655 + {
76656 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76657 + return (uint64_t)(ILLEGAL_BASE);
76658 + }
76659 +
76660 + /* calls Update routine to update a lists of free blocks */
76661 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
76662 + {
76663 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76664 + XX_Free(p_NewBusyB);
76665 + return (uint64_t)(ILLEGAL_BASE);
76666 + }
76667 +
76668 + /* Decreasing the allocated memory size from free memory size */
76669 + p_MM->freeMemSize -= size;
76670 +
76671 + /* insert the new busy block into the list of busy blocks */
76672 + AddBusy ( p_MM, p_NewBusyB );
76673 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76674 +
76675 + return (base);
76676 +}
76677 +
76678 +/*****************************************************************************/
76679 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
76680 +{
76681 + t_MM *p_MM = (t_MM *)h_MM;
76682 + t_FreeBlock *p_FreeB;
76683 + t_BusyBlock *p_NewBusyB;
76684 + uint64_t holdBase, holdEnd, j = alignment, i=0;
76685 + uint32_t intFlags;
76686 +
76687 + ASSERT_COND(p_MM);
76688 +
76689 + /* checks if alignment is a power of two, if it correct and if the
76690 + required size is multiple of the given alignment. */
76691 + while ((j & 0x1) == 0)
76692 + {
76693 + i++;
76694 + j = j >> 1;
76695 + }
76696 +
76697 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
76698 + {
76699 + return (uint64_t)(ILLEGAL_BASE);
76700 + }
76701 +
76702 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76703 + p_FreeB = p_MM->freeBlocks[i];
76704 +
76705 + /* look for the first block that contains the minimum
76706 + base address. If the whole required size may be fit
76707 + into it, use that block, otherwise look for the next
76708 + block of size greater or equal to the required size. */
76709 + while ( p_FreeB && (min >= p_FreeB->end))
76710 + p_FreeB = p_FreeB->p_Next;
76711 +
76712 + /* If such block is found */
76713 + if ( !p_FreeB )
76714 + {
76715 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76716 + return (uint64_t)(ILLEGAL_BASE);
76717 + }
76718 +
76719 + /* if this block is large enough, use this block */
76720 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
76721 + if ((holdBase + size) <= p_FreeB->end )
76722 + {
76723 + holdEnd = holdBase + size;
76724 + }
76725 + else
76726 + {
76727 + p_FreeB = p_FreeB->p_Next;
76728 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
76729 + p_FreeB = p_FreeB->p_Next;
76730 +
76731 + /* If such block is found */
76732 + if ( !p_FreeB )
76733 + {
76734 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76735 + return (uint64_t)(ILLEGAL_BASE);
76736 + }
76737 +
76738 + holdBase = p_FreeB->base;
76739 + holdEnd = holdBase + size;
76740 + }
76741 +
76742 + /* init a new busy block */
76743 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
76744 + {
76745 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76746 + return (uint64_t)(ILLEGAL_BASE);
76747 + }
76748 +
76749 + /* calls Update routine to update a lists of free blocks */
76750 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
76751 + {
76752 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76753 + XX_Free(p_NewBusyB);
76754 + return (uint64_t)(ILLEGAL_BASE);
76755 + }
76756 +
76757 + /* Decreasing the allocated memory size from free memory size */
76758 + p_MM->freeMemSize -= size;
76759 +
76760 + /* insert the new busy block into the list of busy blocks */
76761 + AddBusy( p_MM, p_NewBusyB );
76762 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76763 +
76764 + return (holdBase);
76765 +}
76766 +
76767 +/*****************************************************************************/
76768 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
76769 +{
76770 + t_MM *p_MM = (t_MM *)h_MM;
76771 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
76772 + uint64_t size;
76773 + uint32_t intFlags;
76774 +
76775 + ASSERT_COND(p_MM);
76776 +
76777 + /* Look for a busy block that have the given base value.
76778 + * That block will be returned back to the memory.
76779 + */
76780 + p_PrevBusyB = 0;
76781 +
76782 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76783 + p_BusyB = p_MM->busyBlocks;
76784 + while ( p_BusyB && base != p_BusyB->base )
76785 + {
76786 + p_PrevBusyB = p_BusyB;
76787 + p_BusyB = p_BusyB->p_Next;
76788 + }
76789 +
76790 + if ( !p_BusyB )
76791 + {
76792 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76793 + return (uint64_t)(0);
76794 + }
76795 +
76796 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
76797 + {
76798 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76799 + return (uint64_t)(0);
76800 + }
76801 +
76802 + /* removes a busy block form the list of busy blocks */
76803 + if ( p_PrevBusyB )
76804 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
76805 + else
76806 + p_MM->busyBlocks = p_BusyB->p_Next;
76807 +
76808 + size = p_BusyB->end - p_BusyB->base;
76809 +
76810 + /* Adding the deallocated memory size to free memory size */
76811 + p_MM->freeMemSize += size;
76812 +
76813 + XX_Free(p_BusyB);
76814 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76815 +
76816 + return (size);
76817 +}
76818 +
76819 +/*****************************************************************************/
76820 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
76821 +{
76822 + t_MM *p_MM = (t_MM *)h_MM;
76823 + uint64_t end = base + size;
76824 + uint32_t intFlags;
76825 +
76826 + ASSERT_COND(p_MM);
76827 +
76828 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76829 +
76830 + if ( CutBusy( p_MM, base, end ) != E_OK )
76831 + {
76832 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76833 + return (uint64_t)(0);
76834 + }
76835 +
76836 + if ( AddFree ( p_MM, base, end ) != E_OK )
76837 + {
76838 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76839 + return (uint64_t)(0);
76840 + }
76841 +
76842 + /* Adding the deallocated memory size to free memory size */
76843 + p_MM->freeMemSize += size;
76844 +
76845 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76846 +
76847 + return (size);
76848 +}
76849 +
76850 +/*****************************************************************************/
76851 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
76852 +{
76853 + t_MM *p_MM = (t_MM *)h_MM;
76854 + t_MemBlock *p_MemB, *p_NewMemB;
76855 + t_Error errCode;
76856 + uint32_t intFlags;
76857 +
76858 + ASSERT_COND(p_MM);
76859 +
76860 + /* find a last block in the list of memory blocks to insert a new
76861 + * memory block
76862 + */
76863 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76864 +
76865 + p_MemB = p_MM->memBlocks;
76866 + while ( p_MemB->p_Next )
76867 + {
76868 + if ( base >= p_MemB->base && base < p_MemB->end )
76869 + {
76870 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76871 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
76872 + }
76873 + p_MemB = p_MemB->p_Next;
76874 + }
76875 + /* check for a last memory block */
76876 + if ( base >= p_MemB->base && base < p_MemB->end )
76877 + {
76878 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76879 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
76880 + }
76881 +
76882 + /* create a new memory block */
76883 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
76884 + {
76885 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76886 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76887 + }
76888 +
76889 + /* append a new memory block to the end of the list of memory blocks */
76890 + p_MemB->p_Next = p_NewMemB;
76891 +
76892 + /* add a new free block to the free lists */
76893 + errCode = AddFree(p_MM, base, base+size);
76894 + if (errCode)
76895 + {
76896 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76897 + p_MemB->p_Next = 0;
76898 + XX_Free(p_NewMemB);
76899 + return ((t_Error)errCode);
76900 + }
76901 +
76902 + /* Adding the new block size to free memory size */
76903 + p_MM->freeMemSize += size;
76904 +
76905 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76906 +
76907 + return (E_OK);
76908 +}
76909 +
76910 +/*****************************************************************************/
76911 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
76912 +{
76913 + t_MM *p_MM = (t_MM*)h_MM;
76914 + t_MemBlock *p_MemBlock;
76915 + int i;
76916 +
76917 + ASSERT_COND(p_MM);
76918 +
76919 + p_MemBlock = p_MM->memBlocks;
76920 + for (i=0; i < index; i++)
76921 + p_MemBlock = p_MemBlock->p_Next;
76922 +
76923 + if ( p_MemBlock )
76924 + return (p_MemBlock->base);
76925 + else
76926 + return (uint64_t)ILLEGAL_BASE;
76927 +}
76928 +
76929 +/*****************************************************************************/
76930 +uint64_t MM_GetBase(t_Handle h_MM)
76931 +{
76932 + t_MM *p_MM = (t_MM*)h_MM;
76933 + t_MemBlock *p_MemBlock;
76934 +
76935 + ASSERT_COND(p_MM);
76936 +
76937 + p_MemBlock = p_MM->memBlocks;
76938 + return p_MemBlock->base;
76939 +}
76940 +
76941 +/*****************************************************************************/
76942 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
76943 +{
76944 + t_MM *p_MM = (t_MM*)h_MM;
76945 + t_MemBlock *p_MemBlock;
76946 +
76947 + ASSERT_COND(p_MM);
76948 +
76949 + p_MemBlock = p_MM->memBlocks;
76950 +
76951 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
76952 + return TRUE;
76953 + else
76954 + return FALSE;
76955 +}
76956 +
76957 +/*****************************************************************************/
76958 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
76959 +{
76960 + t_MM *p_MM = (t_MM*)h_MM;
76961 +
76962 + ASSERT_COND(p_MM);
76963 +
76964 + return p_MM->freeMemSize;
76965 +}
76966 +
76967 +/*****************************************************************************/
76968 +void MM_Dump(t_Handle h_MM)
76969 +{
76970 + t_MM *p_MM = (t_MM *)h_MM;
76971 + t_FreeBlock *p_FreeB;
76972 + t_BusyBlock *p_BusyB;
76973 + int i;
76974 +
76975 + p_BusyB = p_MM->busyBlocks;
76976 + XX_Print("List of busy blocks:\n");
76977 + while (p_BusyB)
76978 + {
76979 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
76980 + p_BusyB = p_BusyB->p_Next;
76981 + }
76982 +
76983 + XX_Print("\nLists of free blocks according to alignment:\n");
76984 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76985 + {
76986 + XX_Print("%d alignment:\n", (0x1 << i));
76987 + p_FreeB = p_MM->freeBlocks[i];
76988 + while (p_FreeB)
76989 + {
76990 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
76991 + p_FreeB = p_FreeB->p_Next;
76992 + }
76993 + XX_Print("\n");
76994 + }
76995 +}
76996 --- /dev/null
76997 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
76998 @@ -0,0 +1,105 @@
76999 +/*
77000 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77001 + *
77002 + * Redistribution and use in source and binary forms, with or without
77003 + * modification, are permitted provided that the following conditions are met:
77004 + * * Redistributions of source code must retain the above copyright
77005 + * notice, this list of conditions and the following disclaimer.
77006 + * * Redistributions in binary form must reproduce the above copyright
77007 + * notice, this list of conditions and the following disclaimer in the
77008 + * documentation and/or other materials provided with the distribution.
77009 + * * Neither the name of Freescale Semiconductor nor the
77010 + * names of its contributors may be used to endorse or promote products
77011 + * derived from this software without specific prior written permission.
77012 + *
77013 + *
77014 + * ALTERNATIVELY, this software may be distributed under the terms of the
77015 + * GNU General Public License ("GPL") as published by the Free Software
77016 + * Foundation, either version 2 of that License or (at your option) any
77017 + * later version.
77018 + *
77019 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77020 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77021 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77022 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77023 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77024 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77025 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77026 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77027 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77028 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77029 + */
77030 +
77031 +
77032 +/****************************************************************
77033 + *
77034 + * File: mm.h
77035 + *
77036 + *
77037 + * Description:
77038 + * MM (Memory Management) object definitions.
77039 + * It also includes definitions of the Free Block, Busy Block
77040 + * and Memory Block structures used by the MM object.
77041 + *
77042 + ****************************************************************/
77043 +
77044 +#ifndef __MM_H
77045 +#define __MM_H
77046 +
77047 +
77048 +#include "mm_ext.h"
77049 +
77050 +#define __ERR_MODULE__ MODULE_MM
77051 +
77052 +
77053 +#define MAKE_ALIGNED(addr, align) \
77054 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
77055 +
77056 +
77057 +/* t_MemBlock data structure defines parameters of the Memory Block */
77058 +typedef struct t_MemBlock
77059 +{
77060 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
77061 +
77062 + uint64_t base; /* Base address of the memory block */
77063 + uint64_t end; /* End address of the memory block */
77064 +} t_MemBlock;
77065 +
77066 +
77067 +/* t_FreeBlock data structure defines parameters of the Free Block */
77068 +typedef struct t_FreeBlock
77069 +{
77070 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
77071 +
77072 + uint64_t base; /* Base address of the block */
77073 + uint64_t end; /* End address of the block */
77074 +} t_FreeBlock;
77075 +
77076 +
77077 +/* t_BusyBlock data structure defines parameters of the Busy Block */
77078 +typedef struct t_BusyBlock
77079 +{
77080 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
77081 +
77082 + uint64_t base; /* Base address of the block */
77083 + uint64_t end; /* End address of the block */
77084 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
77085 + something specified by the Name */
77086 +} t_BusyBlock;
77087 +
77088 +
77089 +/* t_MM data structure defines parameters of the MM object */
77090 +typedef struct t_MM
77091 +{
77092 + t_Handle h_Spinlock;
77093 +
77094 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
77095 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
77096 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
77097 + /* Alignment lists of free blocks (Free lists) */
77098 +
77099 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
77100 +} t_MM;
77101 +
77102 +
77103 +#endif /* __MM_H */
77104 --- /dev/null
77105 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
77106 @@ -0,0 +1,81 @@
77107 +/*
77108 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77109 + *
77110 + * Redistribution and use in source and binary forms, with or without
77111 + * modification, are permitted provided that the following conditions are met:
77112 + * * Redistributions of source code must retain the above copyright
77113 + * notice, this list of conditions and the following disclaimer.
77114 + * * Redistributions in binary form must reproduce the above copyright
77115 + * notice, this list of conditions and the following disclaimer in the
77116 + * documentation and/or other materials provided with the distribution.
77117 + * * Neither the name of Freescale Semiconductor nor the
77118 + * names of its contributors may be used to endorse or promote products
77119 + * derived from this software without specific prior written permission.
77120 + *
77121 + *
77122 + * ALTERNATIVELY, this software may be distributed under the terms of the
77123 + * GNU General Public License ("GPL") as published by the Free Software
77124 + * Foundation, either version 2 of that License or (at your option) any
77125 + * later version.
77126 + *
77127 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77128 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77129 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77130 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77131 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77132 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77133 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77134 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77135 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77136 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77137 + */
77138 +
77139 +
77140 +/*------------------------------------------------------*/
77141 +/* File: sprint.c */
77142 +/* */
77143 +/* Description: */
77144 +/* Debug routines (externals) */
77145 +/*------------------------------------------------------*/
77146 +#include "string_ext.h"
77147 +#include "stdlib_ext.h"
77148 +#include "stdarg_ext.h"
77149 +#include "sprint_ext.h"
77150 +#include "std_ext.h"
77151 +#include "xx_ext.h"
77152 +
77153 +
77154 +int Sprint(char * buf, const char *fmt, ...)
77155 +{
77156 + va_list args;
77157 + int i;
77158 +
77159 + va_start(args, fmt);
77160 + i=vsprintf(buf,fmt,args);
77161 + va_end(args);
77162 + return i;
77163 +}
77164 +
77165 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
77166 +{
77167 + va_list args;
77168 + int i;
77169 +
77170 + va_start(args, fmt);
77171 + i=vsnprintf(buf,size,fmt,args);
77172 + va_end(args);
77173 + return i;
77174 +}
77175 +
77176 +#ifndef NCSW_VXWORKS
77177 +int Sscan(const char * buf, const char * fmt, ...)
77178 +{
77179 + va_list args;
77180 + int i;
77181 +
77182 + va_start(args,fmt);
77183 + i = vsscanf(buf,fmt,args);
77184 + va_end(args);
77185 + return i;
77186 +}
77187 +#endif /* NCSW_VXWORKS */
77188 --- /dev/null
77189 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
77190 @@ -0,0 +1,57 @@
77191 +/*
77192 + * Copyright 2012 Freescale Semiconductor Inc.
77193 + *
77194 + * Redistribution and use in source and binary forms, with or without
77195 + * modification, are permitted provided that the following conditions are met:
77196 + * * Redistributions of source code must retain the above copyright
77197 + * notice, this list of conditions and the following disclaimer.
77198 + * * Redistributions in binary form must reproduce the above copyright
77199 + * notice, this list of conditions and the following disclaimer in the
77200 + * documentation and/or other materials provided with the distribution.
77201 + * * Neither the name of Freescale Semiconductor nor the
77202 + * names of its contributors may be used to endorse or promote products
77203 + * derived from this software without specific prior written permission.
77204 + *
77205 + *
77206 + * ALTERNATIVELY, this software may be distributed under the terms of the
77207 + * GNU General Public License ("GPL") as published by the Free Software
77208 + * Foundation, either version 2 of that License or (at your option) any
77209 + * later version.
77210 + *
77211 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77212 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77213 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77214 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77215 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77216 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77217 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77218 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77219 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77220 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77221 + */
77222 +
77223 +#ifndef __dflags_h
77224 +#define __dflags_h
77225 +
77226 +
77227 +#define NCSW_LINUX
77228 +
77229 +#define T4240
77230 +#define NCSW_PPC_CORE
77231 +
77232 +#define DEBUG_ERRORS 1
77233 +
77234 +#if defined(DEBUG)
77235 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
77236 +
77237 +#define DEBUG_XX_MALLOC
77238 +#define DEBUG_MEM_LEAKS
77239 +
77240 +#else
77241 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
77242 +#endif /* (DEBUG) */
77243 +
77244 +#define REPORT_EVENTS 1
77245 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
77246 +
77247 +#endif /* __dflags_h */
77248 --- /dev/null
77249 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
77250 @@ -0,0 +1,56 @@
77251 +/*
77252 + * Copyright 2012 Freescale Semiconductor Inc.
77253 + *
77254 + * Redistribution and use in source and binary forms, with or without
77255 + * modification, are permitted provided that the following conditions are met:
77256 + * * Redistributions of source code must retain the above copyright
77257 + * notice, this list of conditions and the following disclaimer.
77258 + * * Redistributions in binary form must reproduce the above copyright
77259 + * notice, this list of conditions and the following disclaimer in the
77260 + * documentation and/or other materials provided with the distribution.
77261 + * * Neither the name of Freescale Semiconductor nor the
77262 + * names of its contributors may be used to endorse or promote products
77263 + * derived from this software without specific prior written permission.
77264 + *
77265 + *
77266 + * ALTERNATIVELY, this software may be distributed under the terms of the
77267 + * GNU General Public License ("GPL") as published by the Free Software
77268 + * Foundation, either version 2 of that License or (at your option) any
77269 + * later version.
77270 + *
77271 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77272 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77273 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77274 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77275 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77276 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77277 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77278 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77279 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77280 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77281 + */
77282 +
77283 +#ifndef __dflags_h
77284 +#define __dflags_h
77285 +
77286 +
77287 +#define NCSW_LINUX
77288 +
77289 +#define NCSW_PPC_CORE
77290 +
77291 +#define DEBUG_ERRORS 1
77292 +
77293 +#if defined(DEBUG)
77294 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
77295 +
77296 +#define DEBUG_XX_MALLOC
77297 +#define DEBUG_MEM_LEAKS
77298 +
77299 +#else
77300 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
77301 +#endif /* (DEBUG) */
77302 +
77303 +#define REPORT_EVENTS 1
77304 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
77305 +
77306 +#endif /* __dflags_h */
77307 --- /dev/null
77308 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
77309 @@ -0,0 +1,364 @@
77310 +/*
77311 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77312 + *
77313 + * Redistribution and use in source and binary forms, with or without
77314 + * modification, are permitted provided that the following conditions are met:
77315 + * * Redistributions of source code must retain the above copyright
77316 + * notice, this list of conditions and the following disclaimer.
77317 + * * Redistributions in binary form must reproduce the above copyright
77318 + * notice, this list of conditions and the following disclaimer in the
77319 + * documentation and/or other materials provided with the distribution.
77320 + * * Neither the name of Freescale Semiconductor nor the
77321 + * names of its contributors may be used to endorse or promote products
77322 + * derived from this software without specific prior written permission.
77323 + *
77324 + *
77325 + * ALTERNATIVELY, this software may be distributed under the terms of the
77326 + * GNU General Public License ("GPL") as published by the Free Software
77327 + * Foundation, either version 2 of that License or (at your option) any
77328 + * later version.
77329 + *
77330 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77331 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77332 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77333 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77334 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77335 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77336 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77337 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77338 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77339 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77340 + */
77341 +
77342 +
77343 +/*------------------------------------------------------*/
77344 +/* */
77345 +/* File: crc_mac_addr_ext.h */
77346 +/* */
77347 +/* Description: */
77348 +/* Define a macro that calculate the crc value of */
77349 +/* an Ethernet MAC address (48 bitd address */
77350 +/*------------------------------------------------------*/
77351 +
77352 +#ifndef __crc_mac_addr_ext_h
77353 +#define __crc_mac_addr_ext_h
77354 +
77355 +#include "std_ext.h"
77356 +
77357 +
77358 +static uint32_t crc_table[256] =
77359 +{
77360 + 0x00000000,
77361 + 0x77073096,
77362 + 0xee0e612c,
77363 + 0x990951ba,
77364 + 0x076dc419,
77365 + 0x706af48f,
77366 + 0xe963a535,
77367 + 0x9e6495a3,
77368 + 0x0edb8832,
77369 + 0x79dcb8a4,
77370 + 0xe0d5e91e,
77371 + 0x97d2d988,
77372 + 0x09b64c2b,
77373 + 0x7eb17cbd,
77374 + 0xe7b82d07,
77375 + 0x90bf1d91,
77376 + 0x1db71064,
77377 + 0x6ab020f2,
77378 + 0xf3b97148,
77379 + 0x84be41de,
77380 + 0x1adad47d,
77381 + 0x6ddde4eb,
77382 + 0xf4d4b551,
77383 + 0x83d385c7,
77384 + 0x136c9856,
77385 + 0x646ba8c0,
77386 + 0xfd62f97a,
77387 + 0x8a65c9ec,
77388 + 0x14015c4f,
77389 + 0x63066cd9,
77390 + 0xfa0f3d63,
77391 + 0x8d080df5,
77392 + 0x3b6e20c8,
77393 + 0x4c69105e,
77394 + 0xd56041e4,
77395 + 0xa2677172,
77396 + 0x3c03e4d1,
77397 + 0x4b04d447,
77398 + 0xd20d85fd,
77399 + 0xa50ab56b,
77400 + 0x35b5a8fa,
77401 + 0x42b2986c,
77402 + 0xdbbbc9d6,
77403 + 0xacbcf940,
77404 + 0x32d86ce3,
77405 + 0x45df5c75,
77406 + 0xdcd60dcf,
77407 + 0xabd13d59,
77408 + 0x26d930ac,
77409 + 0x51de003a,
77410 + 0xc8d75180,
77411 + 0xbfd06116,
77412 + 0x21b4f4b5,
77413 + 0x56b3c423,
77414 + 0xcfba9599,
77415 + 0xb8bda50f,
77416 + 0x2802b89e,
77417 + 0x5f058808,
77418 + 0xc60cd9b2,
77419 + 0xb10be924,
77420 + 0x2f6f7c87,
77421 + 0x58684c11,
77422 + 0xc1611dab,
77423 + 0xb6662d3d,
77424 + 0x76dc4190,
77425 + 0x01db7106,
77426 + 0x98d220bc,
77427 + 0xefd5102a,
77428 + 0x71b18589,
77429 + 0x06b6b51f,
77430 + 0x9fbfe4a5,
77431 + 0xe8b8d433,
77432 + 0x7807c9a2,
77433 + 0x0f00f934,
77434 + 0x9609a88e,
77435 + 0xe10e9818,
77436 + 0x7f6a0dbb,
77437 + 0x086d3d2d,
77438 + 0x91646c97,
77439 + 0xe6635c01,
77440 + 0x6b6b51f4,
77441 + 0x1c6c6162,
77442 + 0x856530d8,
77443 + 0xf262004e,
77444 + 0x6c0695ed,
77445 + 0x1b01a57b,
77446 + 0x8208f4c1,
77447 + 0xf50fc457,
77448 + 0x65b0d9c6,
77449 + 0x12b7e950,
77450 + 0x8bbeb8ea,
77451 + 0xfcb9887c,
77452 + 0x62dd1ddf,
77453 + 0x15da2d49,
77454 + 0x8cd37cf3,
77455 + 0xfbd44c65,
77456 + 0x4db26158,
77457 + 0x3ab551ce,
77458 + 0xa3bc0074,
77459 + 0xd4bb30e2,
77460 + 0x4adfa541,
77461 + 0x3dd895d7,
77462 + 0xa4d1c46d,
77463 + 0xd3d6f4fb,
77464 + 0x4369e96a,
77465 + 0x346ed9fc,
77466 + 0xad678846,
77467 + 0xda60b8d0,
77468 + 0x44042d73,
77469 + 0x33031de5,
77470 + 0xaa0a4c5f,
77471 + 0xdd0d7cc9,
77472 + 0x5005713c,
77473 + 0x270241aa,
77474 + 0xbe0b1010,
77475 + 0xc90c2086,
77476 + 0x5768b525,
77477 + 0x206f85b3,
77478 + 0xb966d409,
77479 + 0xce61e49f,
77480 + 0x5edef90e,
77481 + 0x29d9c998,
77482 + 0xb0d09822,
77483 + 0xc7d7a8b4,
77484 + 0x59b33d17,
77485 + 0x2eb40d81,
77486 + 0xb7bd5c3b,
77487 + 0xc0ba6cad,
77488 + 0xedb88320,
77489 + 0x9abfb3b6,
77490 + 0x03b6e20c,
77491 + 0x74b1d29a,
77492 + 0xead54739,
77493 + 0x9dd277af,
77494 + 0x04db2615,
77495 + 0x73dc1683,
77496 + 0xe3630b12,
77497 + 0x94643b84,
77498 + 0x0d6d6a3e,
77499 + 0x7a6a5aa8,
77500 + 0xe40ecf0b,
77501 + 0x9309ff9d,
77502 + 0x0a00ae27,
77503 + 0x7d079eb1,
77504 + 0xf00f9344,
77505 + 0x8708a3d2,
77506 + 0x1e01f268,
77507 + 0x6906c2fe,
77508 + 0xf762575d,
77509 + 0x806567cb,
77510 + 0x196c3671,
77511 + 0x6e6b06e7,
77512 + 0xfed41b76,
77513 + 0x89d32be0,
77514 + 0x10da7a5a,
77515 + 0x67dd4acc,
77516 + 0xf9b9df6f,
77517 + 0x8ebeeff9,
77518 + 0x17b7be43,
77519 + 0x60b08ed5,
77520 + 0xd6d6a3e8,
77521 + 0xa1d1937e,
77522 + 0x38d8c2c4,
77523 + 0x4fdff252,
77524 + 0xd1bb67f1,
77525 + 0xa6bc5767,
77526 + 0x3fb506dd,
77527 + 0x48b2364b,
77528 + 0xd80d2bda,
77529 + 0xaf0a1b4c,
77530 + 0x36034af6,
77531 + 0x41047a60,
77532 + 0xdf60efc3,
77533 + 0xa867df55,
77534 + 0x316e8eef,
77535 + 0x4669be79,
77536 + 0xcb61b38c,
77537 + 0xbc66831a,
77538 + 0x256fd2a0,
77539 + 0x5268e236,
77540 + 0xcc0c7795,
77541 + 0xbb0b4703,
77542 + 0x220216b9,
77543 + 0x5505262f,
77544 + 0xc5ba3bbe,
77545 + 0xb2bd0b28,
77546 + 0x2bb45a92,
77547 + 0x5cb36a04,
77548 + 0xc2d7ffa7,
77549 + 0xb5d0cf31,
77550 + 0x2cd99e8b,
77551 + 0x5bdeae1d,
77552 + 0x9b64c2b0,
77553 + 0xec63f226,
77554 + 0x756aa39c,
77555 + 0x026d930a,
77556 + 0x9c0906a9,
77557 + 0xeb0e363f,
77558 + 0x72076785,
77559 + 0x05005713,
77560 + 0x95bf4a82,
77561 + 0xe2b87a14,
77562 + 0x7bb12bae,
77563 + 0x0cb61b38,
77564 + 0x92d28e9b,
77565 + 0xe5d5be0d,
77566 + 0x7cdcefb7,
77567 + 0x0bdbdf21,
77568 + 0x86d3d2d4,
77569 + 0xf1d4e242,
77570 + 0x68ddb3f8,
77571 + 0x1fda836e,
77572 + 0x81be16cd,
77573 + 0xf6b9265b,
77574 + 0x6fb077e1,
77575 + 0x18b74777,
77576 + 0x88085ae6,
77577 + 0xff0f6a70,
77578 + 0x66063bca,
77579 + 0x11010b5c,
77580 + 0x8f659eff,
77581 + 0xf862ae69,
77582 + 0x616bffd3,
77583 + 0x166ccf45,
77584 + 0xa00ae278,
77585 + 0xd70dd2ee,
77586 + 0x4e048354,
77587 + 0x3903b3c2,
77588 + 0xa7672661,
77589 + 0xd06016f7,
77590 + 0x4969474d,
77591 + 0x3e6e77db,
77592 + 0xaed16a4a,
77593 + 0xd9d65adc,
77594 + 0x40df0b66,
77595 + 0x37d83bf0,
77596 + 0xa9bcae53,
77597 + 0xdebb9ec5,
77598 + 0x47b2cf7f,
77599 + 0x30b5ffe9,
77600 + 0xbdbdf21c,
77601 + 0xcabac28a,
77602 + 0x53b39330,
77603 + 0x24b4a3a6,
77604 + 0xbad03605,
77605 + 0xcdd70693,
77606 + 0x54de5729,
77607 + 0x23d967bf,
77608 + 0xb3667a2e,
77609 + 0xc4614ab8,
77610 + 0x5d681b02,
77611 + 0x2a6f2b94,
77612 + 0xb40bbe37,
77613 + 0xc30c8ea1,
77614 + 0x5a05df1b,
77615 + 0x2d02ef8d
77616 +};
77617 +
77618 +
77619 +#define GET_MAC_ADDR_CRC(addr, crc) \
77620 +{ \
77621 + uint32_t i; \
77622 + uint8_t data; \
77623 + \
77624 + /* CRC calculation */ \
77625 + crc = 0xffffffff; \
77626 + for (i=0; i < 6; i++) \
77627 + { \
77628 + data = (uint8_t)(addr >> ((5-i)*8)); \
77629 + crc = crc^data; \
77630 + crc = crc_table[crc&0xff] ^ (crc>>8); \
77631 + } \
77632 +} \
77633 +
77634 +/* Define a macro for getting the mirrored value of */
77635 +/* a byte size number. (0x11010011 --> 0x11001011) */
77636 +/* Sometimes the mirrored value of the CRC is required */
77637 +static __inline__ uint8_t GetMirror(uint8_t n)
77638 +{
77639 + uint8_t mirror[16] =
77640 + {
77641 + 0x00,
77642 + 0x08,
77643 + 0x04,
77644 + 0x0c,
77645 + 0x02,
77646 + 0x0a,
77647 + 0x06,
77648 + 0x0e,
77649 + 0x01,
77650 + 0x09,
77651 + 0x05,
77652 + 0x0d,
77653 + 0x03,
77654 + 0x0b,
77655 + 0x07,
77656 + 0x0f
77657 + };
77658 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
77659 +}
77660 +
77661 +static __inline__ uint32_t GetMirror32(uint32_t n)
77662 +{
77663 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
77664 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
77665 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
77666 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
77667 +}
77668 +
77669 +#define MIRROR GetMirror
77670 +#define MIRROR_32 GetMirror32
77671 +
77672 +
77673 +#endif /* __crc_mac_addr_ext_h */
77674 --- /dev/null
77675 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
77676 @@ -0,0 +1,210 @@
77677 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
77678 + * All rights reserved.
77679 + *
77680 + * Redistribution and use in source and binary forms, with or without
77681 + * modification, are permitted provided that the following conditions are met:
77682 + * * Redistributions of source code must retain the above copyright
77683 + * notice, this list of conditions and the following disclaimer.
77684 + * * Redistributions in binary form must reproduce the above copyright
77685 + * notice, this list of conditions and the following disclaimer in the
77686 + * documentation and/or other materials provided with the distribution.
77687 + * * Neither the name of Freescale Semiconductor nor the
77688 + * names of its contributors may be used to endorse or promote products
77689 + * derived from this software without specific prior written permission.
77690 + *
77691 + *
77692 + * ALTERNATIVELY, this software may be distributed under the terms of the
77693 + * GNU General Public License ("GPL") as published by the Free Software
77694 + * Foundation, either version 2 of that License or (at your option) any
77695 + * later version.
77696 + *
77697 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77698 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77699 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77700 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77701 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77702 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77703 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77704 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77705 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77706 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77707 + */
77708 +
77709 +
77710 +/**************************************************************************//**
77711 + @File dpaa_ext.h
77712 +
77713 + @Description DPAA Application Programming Interface.
77714 +*//***************************************************************************/
77715 +#ifndef __DPAA_EXT_H
77716 +#define __DPAA_EXT_H
77717 +
77718 +#include "std_ext.h"
77719 +#include "error_ext.h"
77720 +
77721 +
77722 +/**************************************************************************//**
77723 + @Group DPAA_grp Data Path Acceleration Architecture API
77724 +
77725 + @Description DPAA API functions, definitions and enums.
77726 +
77727 + @{
77728 +*//***************************************************************************/
77729 +
77730 +#if defined(__MWERKS__) && !defined(__GNUC__)
77731 +#pragma pack(push,1)
77732 +#endif /* defined(__MWERKS__) && ... */
77733 +
77734 +/**************************************************************************//**
77735 + @Description Frame descriptor
77736 +*//***************************************************************************/
77737 +typedef _Packed struct t_DpaaFD {
77738 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
77739 + volatile uint8_t liodn;
77740 + volatile uint8_t bpid;
77741 + volatile uint8_t elion;
77742 + volatile uint8_t addrh;
77743 + volatile uint32_t addrl;
77744 +#else
77745 + volatile uint32_t addrl;
77746 + volatile uint8_t addrh;
77747 + volatile uint8_t elion;
77748 + volatile uint8_t bpid;
77749 + volatile uint8_t liodn;
77750 + #endif
77751 + volatile uint32_t length; /**< Frame length */
77752 + volatile uint32_t status; /**< FD status */
77753 +} _PackedType t_DpaaFD;
77754 +
77755 +/**************************************************************************//**
77756 + @Description enum for defining frame format
77757 +*//***************************************************************************/
77758 +typedef enum e_DpaaFDFormatType {
77759 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
77760 + small length (9b OFFSET, 20b LENGTH) */
77761 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
77762 + (29b LENGTH ,No OFFSET) */
77763 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
77764 + and small length (9b OFFSET, 20b LENGTH) */
77765 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
77766 + big length (29b LENGTH ,No OFFSET) */
77767 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
77768 + No LENGTH or OFFSET) */
77769 + e_DPAA_FD_FORMAT_TYPE_DUMMY
77770 +} e_DpaaFDFormatType;
77771 +
77772 +/**************************************************************************//**
77773 + @Collection Frame descriptor macros
77774 +*//***************************************************************************/
77775 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
77776 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
77777 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
77778 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
77779 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
77780 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
77781 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
77782 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
77783 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
77784 +
77785 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
77786 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
77787 +#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 */
77788 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
77789 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
77790 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
77791 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
77792 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
77793 +
77794 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
77795 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
77796 +#define DPAA_FD_SET_ADDR(fd,val) \
77797 +do { \
77798 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
77799 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
77800 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
77801 +} while (0) /**< Macro to set FD ADDR field */
77802 +#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 */
77803 +#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 */
77804 +#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 */
77805 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
77806 +/* @} */
77807 +
77808 +/**************************************************************************//**
77809 + @Description Frame Scatter/Gather Table Entry
77810 +*//***************************************************************************/
77811 +typedef _Packed struct t_DpaaSGTE {
77812 + volatile uint32_t addrh; /**< Buffer Address high */
77813 + volatile uint32_t addrl; /**< Buffer Address low */
77814 + volatile uint32_t length; /**< Buffer length */
77815 + volatile uint32_t offset; /**< SGTE offset */
77816 +} _PackedType t_DpaaSGTE;
77817 +
77818 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
77819 +
77820 +/**************************************************************************//**
77821 + @Description Frame Scatter/Gather Table
77822 +*//***************************************************************************/
77823 +typedef _Packed struct t_DpaaSGT {
77824 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
77825 + /**< Structure that holds information about
77826 + a single S/G entry. */
77827 +} _PackedType t_DpaaSGT;
77828 +
77829 +/**************************************************************************//**
77830 + @Description Compound Frame Table
77831 +*//***************************************************************************/
77832 +typedef _Packed struct t_DpaaCompTbl {
77833 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
77834 + the compound-frame output buffer;
77835 + NOTE: this may point to a S/G table */
77836 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
77837 + the compound-frame input buffer;
77838 + NOTE: this may point to a S/G table */
77839 +} _PackedType t_DpaaCompTbl;
77840 +
77841 +/**************************************************************************//**
77842 + @Collection Frame Scatter/Gather Table Entry macros
77843 +*//***************************************************************************/
77844 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
77845 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
77846 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
77847 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
77848 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
77849 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
77850 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
77851 +
77852 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
77853 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
77854 +#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 */
77855 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
77856 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
77857 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
77858 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
77859 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
77860 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
77861 +
77862 +#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 */
77863 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
77864 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
77865 +do { \
77866 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
77867 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
77868 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
77869 +} while (0) /**< Macro to set SGTE ADDR field */
77870 +#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 */
77871 +#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 */
77872 +#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 */
77873 +#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 */
77874 +#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 */
77875 +/* @} */
77876 +
77877 +#if defined(__MWERKS__) && !defined(__GNUC__)
77878 +#pragma pack(pop)
77879 +#endif /* defined(__MWERKS__) && ... */
77880 +
77881 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
77882 +
77883 +/** @} */ /* end of DPAA_grp group */
77884 +
77885 +
77886 +#endif /* __DPAA_EXT_H */
77887 --- /dev/null
77888 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
77889 @@ -0,0 +1,1731 @@
77890 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
77891 + * All rights reserved.
77892 + *
77893 + * Redistribution and use in source and binary forms, with or without
77894 + * modification, are permitted provided that the following conditions are met:
77895 + * * Redistributions of source code must retain the above copyright
77896 + * notice, this list of conditions and the following disclaimer.
77897 + * * Redistributions in binary form must reproduce the above copyright
77898 + * notice, this list of conditions and the following disclaimer in the
77899 + * documentation and/or other materials provided with the distribution.
77900 + * * Neither the name of Freescale Semiconductor nor the
77901 + * names of its contributors may be used to endorse or promote products
77902 + * derived from this software without specific prior written permission.
77903 + *
77904 + *
77905 + * ALTERNATIVELY, this software may be distributed under the terms of the
77906 + * GNU General Public License ("GPL") as published by the Free Software
77907 + * Foundation, either version 2 of that License or (at your option) any
77908 + * later version.
77909 + *
77910 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77911 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77912 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77913 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77914 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77915 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77916 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77917 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77918 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77919 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77920 + */
77921 +
77922 +
77923 +/**************************************************************************//**
77924 + @File fm_ext.h
77925 +
77926 + @Description FM Application Programming Interface.
77927 +*//***************************************************************************/
77928 +#ifndef __FM_EXT
77929 +#define __FM_EXT
77930 +
77931 +#include "error_ext.h"
77932 +#include "std_ext.h"
77933 +#include "dpaa_ext.h"
77934 +#include "fsl_fman_sp.h"
77935 +
77936 +/**************************************************************************//**
77937 + @Group FM_grp Frame Manager API
77938 +
77939 + @Description FM API functions, definitions and enums.
77940 +
77941 + @{
77942 +*//***************************************************************************/
77943 +
77944 +/**************************************************************************//**
77945 + @Group FM_lib_grp FM library
77946 +
77947 + @Description FM API functions, definitions and enums.
77948 +
77949 + The FM module is the main driver module and is a mandatory module
77950 + for FM driver users. This module must be initialized first prior
77951 + to any other drivers modules.
77952 + The FM is a "singleton" module. It is responsible of the common
77953 + HW modules: FPM, DMA, common QMI and common BMI initializations and
77954 + run-time control routines. This module must be initialized always
77955 + when working with any of the FM modules.
77956 + NOTE - We assume that the FM library will be initialized only by core No. 0!
77957 +
77958 + @{
77959 +*//***************************************************************************/
77960 +
77961 +/**************************************************************************//**
77962 + @Description Enum for defining port types
77963 +*//***************************************************************************/
77964 +typedef enum e_FmPortType {
77965 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
77966 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
77967 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
77968 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
77969 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
77970 + e_FM_PORT_TYPE_DUMMY
77971 +} e_FmPortType;
77972 +
77973 +/**************************************************************************//**
77974 + @Collection General FM defines
77975 +*//***************************************************************************/
77976 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
77977 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
77978 +/* @} */
77979 +
77980 +
77981 +#if defined(__MWERKS__) && !defined(__GNUC__)
77982 +#pragma pack(push,1)
77983 +#endif /* defined(__MWERKS__) && ... */
77984 +
77985 +/**************************************************************************//**
77986 + @Description FM physical Address
77987 +*//***************************************************************************/
77988 +typedef _Packed struct t_FmPhysAddr {
77989 + volatile uint8_t high; /**< High part of the physical address */
77990 + volatile uint32_t low; /**< Low part of the physical address */
77991 +} _PackedType t_FmPhysAddr;
77992 +
77993 +/**************************************************************************//**
77994 + @Description Parse results memory layout
77995 +*//***************************************************************************/
77996 +typedef _Packed struct t_FmPrsResult {
77997 + volatile uint8_t lpid; /**< Logical port id */
77998 + volatile uint8_t shimr; /**< Shim header result */
77999 + volatile uint16_t l2r; /**< Layer 2 result */
78000 + volatile uint16_t l3r; /**< Layer 3 result */
78001 + volatile uint8_t l4r; /**< Layer 4 result */
78002 + volatile uint8_t cplan; /**< Classification plan id */
78003 + volatile uint16_t nxthdr; /**< Next Header */
78004 + volatile uint16_t cksum; /**< Running-sum */
78005 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
78006 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
78007 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
78008 + volatile uint8_t shim_off[2]; /**< Shim offset */
78009 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
78010 + volatile uint8_t eth_off; /**< ETH offset */
78011 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
78012 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
78013 + volatile uint8_t etype_off; /**< ETYPE offset */
78014 + volatile uint8_t pppoe_off; /**< PPP offset */
78015 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
78016 + volatile uint8_t ip_off[2]; /**< IP offset */
78017 + volatile uint8_t gre_off; /**< GRE offset */
78018 + volatile uint8_t l4_off; /**< Layer 4 offset */
78019 + volatile uint8_t nxthdr_off; /**< Parser end point */
78020 +} _PackedType t_FmPrsResult;
78021 +
78022 +/**************************************************************************//**
78023 + @Collection FM Parser results
78024 +*//***************************************************************************/
78025 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
78026 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
78027 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
78028 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
78029 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
78030 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
78031 +/* @} */
78032 +
78033 +/**************************************************************************//**
78034 + @Collection FM Frame descriptor macros
78035 +*//***************************************************************************/
78036 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
78037 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
78038 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
78039 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
78040 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
78041 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
78042 +
78043 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
78044 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
78045 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
78046 +
78047 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
78048 +
78049 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
78050 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
78051 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
78052 +
78053 +#ifdef FM_CAPWAP_SUPPORT
78054 +#define FM_FD_ERR_CRE 0x00200000
78055 +#define FM_FD_ERR_CHE 0x00100000
78056 +#endif /* FM_CAPWAP_SUPPORT */
78057 +
78058 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
78059 + error (SGMII and TBI modes), FIFO parity error. PHY
78060 + Sequence error, PHY error control character detected. */
78061 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
78062 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
78063 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
78064 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
78065 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
78066 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
78067 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
78068 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
78069 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
78070 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
78071 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
78072 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
78073 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
78074 +
78075 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
78076 + FM_FD_ERR_LENGTH | \
78077 + FM_FD_ERR_DMA) /**< TX Error FD bits */
78078 +
78079 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
78080 + FM_FD_ERR_LENGTH | \
78081 + FM_FD_ERR_DMA | \
78082 + FM_FD_ERR_IPR | \
78083 + FM_FD_ERR_IPR_TO | \
78084 + FM_FD_ERR_IPR_NCSP | \
78085 + FM_FD_ERR_PHYSICAL | \
78086 + FM_FD_ERR_SIZE | \
78087 + FM_FD_ERR_CLS_DISCARD | \
78088 + FM_FD_ERR_COLOR_RED | \
78089 + FM_FD_ERR_COLOR_YELLOW | \
78090 + FM_FD_ERR_ILL_PLCR | \
78091 + FM_FD_ERR_PLCR_FRAME_LEN | \
78092 + FM_FD_ERR_EXTRACTION | \
78093 + FM_FD_ERR_NO_SCHEME | \
78094 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
78095 + FM_FD_ERR_PRS_TIMEOUT | \
78096 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
78097 + FM_FD_ERR_PRS_HDR_ERR | \
78098 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
78099 +
78100 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
78101 +/* @} */
78102 +
78103 +/**************************************************************************//**
78104 + @Description Context A
78105 +*//***************************************************************************/
78106 +typedef _Packed struct t_FmContextA {
78107 + volatile uint32_t command; /**< ContextA Command */
78108 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
78109 +} _PackedType t_FmContextA;
78110 +
78111 +/**************************************************************************//**
78112 + @Description Context B
78113 +*//***************************************************************************/
78114 +typedef uint32_t t_FmContextB;
78115 +
78116 +/**************************************************************************//**
78117 + @Collection Special Operation options
78118 +*//***************************************************************************/
78119 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
78120 +
78121 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
78122 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
78123 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
78124 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
78125 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
78126 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
78127 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
78128 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
78129 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
78130 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
78131 +/* @} */
78132 +
78133 +/**************************************************************************//**
78134 + @Collection Context A macros
78135 +*//***************************************************************************/
78136 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
78137 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
78138 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
78139 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
78140 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
78141 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
78142 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
78143 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
78144 +
78145 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
78146 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
78147 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
78148 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
78149 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
78150 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
78151 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
78152 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
78153 +
78154 +#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) ))
78155 +#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) ))
78156 +#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) ))
78157 +#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) ))
78158 +#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) ))
78159 +#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) ))
78160 +#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) ))
78161 +#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) ))
78162 +/* @} */
78163 +
78164 +/**************************************************************************//**
78165 + @Collection Context B macros
78166 +*//***************************************************************************/
78167 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
78168 +
78169 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
78170 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
78171 +/* @} */
78172 +
78173 +#if defined(__MWERKS__) && !defined(__GNUC__)
78174 +#pragma pack(pop)
78175 +#endif /* defined(__MWERKS__) && ... */
78176 +
78177 +
78178 +/**************************************************************************//**
78179 + @Description FM Exceptions
78180 +*//***************************************************************************/
78181 +typedef enum e_FmExceptions {
78182 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
78183 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
78184 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
78185 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
78186 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
78187 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
78188 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
78189 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
78190 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
78191 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
78192 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
78193 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
78194 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
78195 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
78196 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
78197 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
78198 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
78199 +} e_FmExceptions;
78200 +
78201 +/**************************************************************************//**
78202 + @Description Enum for defining port DMA swap mode
78203 +*//***************************************************************************/
78204 +typedef enum e_FmDmaSwapOption {
78205 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
78206 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
78207 + in PowerPc Little Endian mode. */
78208 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
78209 + in Big Endian mode */
78210 +} e_FmDmaSwapOption;
78211 +
78212 +/**************************************************************************//**
78213 + @Description Enum for defining port DMA cache attributes
78214 +*//***************************************************************************/
78215 +typedef enum e_FmDmaCacheOption {
78216 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
78217 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
78218 +} e_FmDmaCacheOption;
78219 +
78220 +
78221 +/**************************************************************************//**
78222 + @Group FM_init_grp FM Initialization Unit
78223 +
78224 + @Description FM Initialization Unit
78225 +
78226 + Initialization Flow
78227 + Initialization of the FM Module will be carried out by the application
78228 + according to the following sequence:
78229 + - Calling the configuration routine with basic parameters.
78230 + - Calling the advance initialization routines to change driver's defaults.
78231 + - Calling the initialization routine.
78232 +
78233 + @{
78234 +*//***************************************************************************/
78235 +
78236 +/**************************************************************************//**
78237 + @Function t_FmExceptionsCallback
78238 +
78239 + @Description Exceptions user callback routine, will be called upon an
78240 + exception passing the exception identification.
78241 +
78242 + @Param[in] h_App - User's application descriptor.
78243 + @Param[in] exception - The exception.
78244 +*//***************************************************************************/
78245 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
78246 + e_FmExceptions exception);
78247 +
78248 +
78249 +/**************************************************************************//**
78250 + @Function t_FmBusErrorCallback
78251 +
78252 + @Description Bus error user callback routine, will be called upon a
78253 + bus error, passing parameters describing the errors and the owner.
78254 +
78255 + @Param[in] h_App - User's application descriptor.
78256 + @Param[in] portType - Port type (e_FmPortType)
78257 + @Param[in] portId - Port id - relative to type.
78258 + @Param[in] addr - Address that caused the error
78259 + @Param[in] tnum - Owner of error
78260 + @Param[in] liodn - Logical IO device number
78261 +*//***************************************************************************/
78262 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
78263 + e_FmPortType portType,
78264 + uint8_t portId,
78265 + uint64_t addr,
78266 + uint8_t tnum,
78267 + uint16_t liodn);
78268 +
78269 +/**************************************************************************//**
78270 + @Description A structure for defining buffer prefix area content.
78271 +*//***************************************************************************/
78272 +typedef struct t_FmBufferPrefixContent {
78273 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
78274 + of the external buffer; Note that the private-area will
78275 + start from the base of the buffer address. */
78276 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
78277 + User may use FM_PORT_GetBufferPrsResult() in order to
78278 + get the parser-result from a buffer. */
78279 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
78280 + User may use FM_PORT_GetBufferTimeStamp() in order to
78281 + get the parser-result from a buffer. */
78282 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
78283 + User may use FM_PORT_GetBufferHashResult() in order to
78284 + get the parser-result from a buffer. */
78285 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
78286 + AD, hash-result, key, etc. */
78287 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
78288 + other value for selecting a data alignment (must be a power of 2);
78289 + if write optimization is used, must be >= 16. */
78290 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
78291 + Note that this field impacts the size of the buffer-prefix
78292 + (i.e. it pushes the data offset);
78293 + This field is irrelevant if DPAA_VERSION==10 */
78294 +} t_FmBufferPrefixContent;
78295 +
78296 +/**************************************************************************//**
78297 + @Description A structure of information about each of the external
78298 + buffer pools used by a port or storage-profile.
78299 +*//***************************************************************************/
78300 +typedef struct t_FmExtPoolParams {
78301 + uint8_t id; /**< External buffer pool id */
78302 + uint16_t size; /**< External buffer pool buffer size */
78303 +} t_FmExtPoolParams;
78304 +
78305 +/**************************************************************************//**
78306 + @Description A structure for informing the driver about the external
78307 + buffer pools allocated in the BM and used by a port or a
78308 + storage-profile.
78309 +*//***************************************************************************/
78310 +typedef struct t_FmExtPools {
78311 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
78312 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
78313 + /**< Parameters for each port */
78314 +} t_FmExtPools;
78315 +
78316 +/**************************************************************************//**
78317 + @Description A structure for defining backup BM Pools.
78318 +*//***************************************************************************/
78319 +typedef struct t_FmBackupBmPools {
78320 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
78321 + must be smaller than the total number of
78322 + pools defined for the specified port.*/
78323 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
78324 + /**< numOfBackupPools pool id's, specifying which
78325 + pools should be used only as backup. Pool
78326 + id's specified here must be a subset of the
78327 + pools used by the specified port.*/
78328 +} t_FmBackupBmPools;
78329 +
78330 +/**************************************************************************//**
78331 + @Description A structure for defining BM pool depletion criteria
78332 +*//***************************************************************************/
78333 +typedef struct t_FmBufPoolDepletion {
78334 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
78335 + a number of pools (all together!) are depleted */
78336 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
78337 + pause frames transmission. */
78338 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
78339 + /**< For each pool, TRUE if it should be considered for
78340 + depletion (Note - this pool must be used by this port!). */
78341 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
78342 + a single-pool is depleted; */
78343 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
78344 + /**< For each pool, TRUE if it should be considered for
78345 + depletion (Note - this pool must be used by this port!) */
78346 +#if (DPAA_VERSION >= 11)
78347 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
78348 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
78349 +#endif /* (DPAA_VERSION >= 11) */
78350 +} t_FmBufPoolDepletion;
78351 +
78352 +/**************************************************************************//**
78353 + @Description A Structure for defining Ucode patch for loading.
78354 +*//***************************************************************************/
78355 +typedef struct t_FmFirmwareParams {
78356 + uint32_t size; /**< Size of uCode */
78357 + uint32_t *p_Code; /**< A pointer to the uCode */
78358 +} t_FmFirmwareParams;
78359 +
78360 +/**************************************************************************//**
78361 + @Description A Structure for defining FM initialization parameters
78362 +*//***************************************************************************/
78363 +typedef struct t_FmParams {
78364 + uint8_t fmId; /**< Index of the FM */
78365 + uint8_t guestId; /**< FM Partition Id */
78366 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
78367 + this field is optional when the FM runs in "guest-mode"
78368 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
78369 + use the memory-map instead of calling the IPC where possible;
78370 + NOTE that this should include ALL common registers of the FM including
78371 + the PCD registers area (i.e. until the VSP pages - 880KB). */
78372 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
78373 + to be used by the FM. */
78374 + uint16_t fmClkFreq; /**< In Mhz;
78375 + Relevant when FM not runs in "guest-mode". */
78376 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
78377 + when fmMacClkRatio = 0, ratio is 2:1
78378 + when fmMacClkRatio = 1, ratio is 1:1 */
78379 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
78380 + Relevant when FM not runs in "guest-mode". */
78381 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
78382 + Relevant when FM not runs in "guest-mode". */
78383 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78384 + be passed by the driver upon calling the above callbacks;
78385 + Relevant when FM not runs in "guest-mode". */
78386 + int irq; /**< FM interrupt source for normal events;
78387 + Relevant when FM not runs in "guest-mode". */
78388 + int errIrq; /**< FM interrupt source for errors;
78389 + Relevant when FM not runs in "guest-mode". */
78390 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
78391 + Relevant when FM not runs in "guest-mode". */
78392 +
78393 +#if (DPAA_VERSION >= 11)
78394 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
78395 + i.e. up to 24KB, depending on the specific chip. */
78396 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
78397 + NOTE: this parameter relevant only when working with multiple partitions. */
78398 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
78399 + NOTE: this parameter relevant only when working with multiple partitions. */
78400 +#endif /* (DPAA_VERSION >= 11) */
78401 +} t_FmParams;
78402 +
78403 +
78404 +/**************************************************************************//**
78405 + @Function FM_Config
78406 +
78407 + @Description Creates the FM module and returns its handle (descriptor).
78408 + This descriptor must be passed as first parameter to all other
78409 + FM function calls.
78410 +
78411 + No actual initialization or configuration of FM hardware is
78412 + done by this routine. All FM parameters get default values that
78413 + may be changed by calling one or more of the advance config routines.
78414 +
78415 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
78416 +
78417 + @Return A handle to the FM object, or NULL for Failure.
78418 +*//***************************************************************************/
78419 +t_Handle FM_Config(t_FmParams *p_FmParams);
78420 +
78421 +/**************************************************************************//**
78422 + @Function FM_Init
78423 +
78424 + @Description Initializes the FM module by defining the software structure
78425 + and configuring the hardware registers.
78426 +
78427 + @Param[in] h_Fm - FM module descriptor
78428 +
78429 + @Return E_OK on success; Error code otherwise.
78430 +*//***************************************************************************/
78431 +t_Error FM_Init(t_Handle h_Fm);
78432 +
78433 +/**************************************************************************//**
78434 + @Function FM_Free
78435 +
78436 + @Description Frees all resources that were assigned to FM module.
78437 +
78438 + Calling this routine invalidates the descriptor.
78439 +
78440 + @Param[in] h_Fm - FM module descriptor
78441 +
78442 + @Return E_OK on success; Error code otherwise.
78443 +*//***************************************************************************/
78444 +t_Error FM_Free(t_Handle h_Fm);
78445 +
78446 +
78447 +/**************************************************************************//**
78448 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
78449 +
78450 + @Description Advanced configuration routines are optional routines that may
78451 + be called in order to change the default driver settings.
78452 +
78453 + Note: Advanced configuration routines are not available for guest partition.
78454 + @{
78455 +*//***************************************************************************/
78456 +
78457 +/**************************************************************************//**
78458 + @Description Enum for selecting DMA debug mode
78459 +*//***************************************************************************/
78460 +typedef enum e_FmDmaDbgCntMode {
78461 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
78462 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
78463 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
78464 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
78465 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
78466 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
78467 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
78468 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
78469 +} e_FmDmaDbgCntMode;
78470 +
78471 +/**************************************************************************//**
78472 + @Description Enum for selecting DMA Cache Override
78473 +*//***************************************************************************/
78474 +typedef enum e_FmDmaCacheOverride {
78475 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
78476 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
78477 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
78478 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
78479 +} e_FmDmaCacheOverride;
78480 +
78481 +/**************************************************************************//**
78482 + @Description Enum for selecting DMA External Bus Priority
78483 +*//***************************************************************************/
78484 +typedef enum e_FmDmaExtBusPri {
78485 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
78486 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
78487 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
78488 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
78489 +} e_FmDmaExtBusPri;
78490 +
78491 +/**************************************************************************//**
78492 + @Description Enum for choosing the field that will be output on AID
78493 +*//***************************************************************************/
78494 +typedef enum e_FmDmaAidMode {
78495 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
78496 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
78497 +} e_FmDmaAidMode;
78498 +
78499 +/**************************************************************************//**
78500 + @Description Enum for selecting FPM Catastrophic error behavior
78501 +*//***************************************************************************/
78502 +typedef enum e_FmCatastrophicErr {
78503 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
78504 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
78505 +} e_FmCatastrophicErr;
78506 +
78507 +/**************************************************************************//**
78508 + @Description Enum for selecting FPM DMA Error behavior
78509 +*//***************************************************************************/
78510 +typedef enum e_FmDmaErr {
78511 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
78512 + error (e_FmCatastrophicErr)*/
78513 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
78514 +} e_FmDmaErr;
78515 +
78516 +/**************************************************************************//**
78517 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
78518 +*//***************************************************************************/
78519 +typedef enum e_FmDmaEmergencyLevel {
78520 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
78521 + e_FM_DMA_EM_SOS /**< SOS emergency */
78522 +} e_FmDmaEmergencyLevel;
78523 +
78524 +/**************************************************************************//**
78525 + @Collection Enum for selecting DMA Emergency options
78526 +*//***************************************************************************/
78527 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
78528 +
78529 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
78530 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
78531 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
78532 +/* @} */
78533 +
78534 +/**************************************************************************//**
78535 + @Description A structure for defining DMA emergency level
78536 +*//***************************************************************************/
78537 +typedef struct t_FmDmaEmergency {
78538 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
78539 + should be enabled */
78540 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
78541 +} t_FmDmaEmergency;
78542 +
78543 +/**************************************************************************//*
78544 + @Description structure for defining FM threshold
78545 +*//***************************************************************************/
78546 +typedef struct t_FmThresholds {
78547 + uint8_t dispLimit; /**< The number of times a frames may
78548 + be passed in the FM before assumed to
78549 + be looping. */
78550 + uint8_t prsDispTh; /**< This is the number pf packets that may be
78551 + queued in the parser dispatch queue*/
78552 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
78553 + queued in the policer dispatch queue*/
78554 + uint8_t kgDispTh; /**< This is the number pf packets that may be
78555 + queued in the keygen dispatch queue*/
78556 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
78557 + queued in the BMI dispatch queue*/
78558 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
78559 + queued in the QMI enqueue dispatch queue*/
78560 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
78561 + queued in the QMI dequeue dispatch queue*/
78562 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
78563 + queued in fmCtl1 dispatch queue*/
78564 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
78565 + queued in fmCtl2 dispatch queue*/
78566 +} t_FmThresholds;
78567 +
78568 +/**************************************************************************//*
78569 + @Description structure for defining DMA thresholds
78570 +*//***************************************************************************/
78571 +typedef struct t_FmDmaThresholds {
78572 + uint8_t assertEmergency; /**< When this value is reached,
78573 + assert emergency (Threshold)*/
78574 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
78575 + until this value is reached (Hystheresis) */
78576 +} t_FmDmaThresholds;
78577 +
78578 +/**************************************************************************//**
78579 + @Function t_FmResetOnInitOverrideCallback
78580 +
78581 + @Description FMan specific reset on init user callback routine,
78582 + will be used to override the standard FMan reset on init procedure
78583 +
78584 + @Param[in] h_Fm - FMan handler
78585 +*//***************************************************************************/
78586 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
78587 +
78588 +/**************************************************************************//**
78589 + @Function FM_ConfigResetOnInit
78590 +
78591 + @Description Define whether to reset the FM before initialization.
78592 + Change the default configuration [DEFAULT_resetOnInit].
78593 +
78594 + @Param[in] h_Fm A handle to an FM Module.
78595 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78596 +
78597 + @Return E_OK on success; Error code otherwise.
78598 +
78599 + @Cautions Allowed only following FM_Config() and before FM_Init().
78600 + This routine should NOT be called from guest-partition
78601 + (i.e. guestId != NCSW_MASTER_ID)
78602 +*//***************************************************************************/
78603 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
78604 +
78605 +/**************************************************************************//**
78606 + @Function FM_ConfigResetOnInitOverrideCallback
78607 +
78608 + @Description Define a special reset of FM before initialization.
78609 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
78610 +
78611 + @Param[in] h_Fm A handle to an FM Module.
78612 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
78613 +
78614 + @Return E_OK on success; Error code otherwise.
78615 +
78616 + @Cautions Allowed only following FM_Config() and before FM_Init().
78617 + This routine should NOT be called from guest-partition
78618 + (i.e. guestId != NCSW_MASTER_ID)
78619 +*//***************************************************************************/
78620 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
78621 +
78622 +/**************************************************************************//**
78623 + @Function FM_ConfigTotalFifoSize
78624 +
78625 + @Description Define Total FIFO size for the whole FM.
78626 + Calling this routine changes the total Fifo size in the internal driver
78627 + data base from its default configuration [DEFAULT_totalFifoSize]
78628 +
78629 + @Param[in] h_Fm A handle to an FM Module.
78630 + @Param[in] totalFifoSize The selected new value.
78631 +
78632 + @Return E_OK on success; Error code otherwise.
78633 +
78634 + @Cautions Allowed only following FM_Config() and before FM_Init().
78635 + This routine should NOT be called from guest-partition
78636 + (i.e. guestId != NCSW_MASTER_ID)
78637 +*//***************************************************************************/
78638 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
78639 +
78640 + /**************************************************************************//**
78641 + @Function FM_ConfigDmaCacheOverride
78642 +
78643 + @Description Define cache override mode.
78644 + Calling this routine changes the cache override mode
78645 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
78646 +
78647 + @Param[in] h_Fm A handle to an FM Module.
78648 + @Param[in] cacheOverride The selected new value.
78649 +
78650 + @Return E_OK on success; Error code otherwise.
78651 +
78652 + @Cautions Allowed only following FM_Config() and before FM_Init().
78653 + This routine should NOT be called from guest-partition
78654 + (i.e. guestId != NCSW_MASTER_ID)
78655 +*//***************************************************************************/
78656 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
78657 +
78658 +/**************************************************************************//**
78659 + @Function FM_ConfigDmaAidOverride
78660 +
78661 + @Description Define DMA AID override mode.
78662 + Calling this routine changes the AID override mode
78663 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
78664 +
78665 + @Param[in] h_Fm A handle to an FM Module.
78666 + @Param[in] aidOverride The selected new value.
78667 +
78668 + @Return E_OK on success; Error code otherwise.
78669 +
78670 + @Cautions Allowed only following FM_Config() and before FM_Init().
78671 + This routine should NOT be called from guest-partition
78672 + (i.e. guestId != NCSW_MASTER_ID)
78673 +*//***************************************************************************/
78674 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
78675 +
78676 +/**************************************************************************//**
78677 + @Function FM_ConfigDmaAidMode
78678 +
78679 + @Description Define DMA AID mode.
78680 + Calling this routine changes the AID mode in the internal
78681 + driver data base from its default configuration [DEFAULT_aidMode]
78682 +
78683 + @Param[in] h_Fm A handle to an FM Module.
78684 + @Param[in] aidMode The selected new value.
78685 +
78686 + @Return E_OK on success; Error code otherwise.
78687 +
78688 + @Cautions Allowed only following FM_Config() and before FM_Init().
78689 + This routine should NOT be called from guest-partition
78690 + (i.e. guestId != NCSW_MASTER_ID)
78691 +*//***************************************************************************/
78692 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
78693 +
78694 +/**************************************************************************//**
78695 + @Function FM_ConfigDmaAxiDbgNumOfBeats
78696 +
78697 + @Description Define DMA AXI number of beats.
78698 + Calling this routine changes the AXI number of beats in the internal
78699 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
78700 +
78701 + @Param[in] h_Fm A handle to an FM Module.
78702 + @Param[in] axiDbgNumOfBeats The selected new value.
78703 +
78704 + @Return E_OK on success; Error code otherwise.
78705 +
78706 + @Cautions Allowed only following FM_Config() and before FM_Init().
78707 + This routine should NOT be called from guest-partition
78708 + (i.e. guestId != NCSW_MASTER_ID)
78709 +*//***************************************************************************/
78710 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
78711 +
78712 +/**************************************************************************//**
78713 + @Function FM_ConfigDmaCamNumOfEntries
78714 +
78715 + @Description Define number of CAM entries.
78716 + Calling this routine changes the number of CAM entries in the internal
78717 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
78718 +
78719 + @Param[in] h_Fm A handle to an FM Module.
78720 + @Param[in] numOfEntries The selected new value.
78721 +
78722 + @Return E_OK on success; Error code otherwise.
78723 +
78724 + @Cautions Allowed only following FM_Config() and before FM_Init().
78725 + This routine should NOT be called from guest-partition
78726 + (i.e. guestId != NCSW_MASTER_ID)
78727 +*//***************************************************************************/
78728 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
78729 +
78730 +/**************************************************************************//**
78731 + @Function FM_ConfigEnableCounters
78732 +
78733 + @Description Obsolete, always return E_OK.
78734 +
78735 + @Param[in] h_Fm A handle to an FM Module.
78736 +
78737 + @Return E_OK on success; Error code otherwise.
78738 +*//***************************************************************************/
78739 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
78740 +
78741 +/**************************************************************************//**
78742 + @Function FM_ConfigDmaDbgCounter
78743 +
78744 + @Description Define DMA debug counter.
78745 + Calling this routine changes the number of the DMA debug counter in the internal
78746 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
78747 +
78748 + @Param[in] h_Fm A handle to an FM Module.
78749 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
78750 +
78751 + @Return E_OK on success; Error code otherwise.
78752 +
78753 + @Cautions Allowed only following FM_Config() and before FM_Init().
78754 + This routine should NOT be called from guest-partition
78755 + (i.e. guestId != NCSW_MASTER_ID)
78756 +*//***************************************************************************/
78757 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
78758 +
78759 +/**************************************************************************//**
78760 + @Function FM_ConfigDmaStopOnBusErr
78761 +
78762 + @Description Define bus error behavior.
78763 + Calling this routine changes the bus error behavior definition
78764 + in the internal driver data base from its default
78765 + configuration [DEFAULT_dmaStopOnBusError].
78766 +
78767 + @Param[in] h_Fm A handle to an FM Module.
78768 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
78769 +
78770 + @Return E_OK on success; Error code otherwise.
78771 +
78772 + @Cautions Allowed only following FM_Config() and before FM_Init().
78773 + Only if bus error is enabled.
78774 + This routine should NOT be called from guest-partition
78775 + (i.e. guestId != NCSW_MASTER_ID)
78776 +*//***************************************************************************/
78777 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
78778 +
78779 +/**************************************************************************//**
78780 + @Function FM_ConfigDmaEmergency
78781 +
78782 + @Description Define DMA emergency.
78783 + Calling this routine changes the DMA emergency definition
78784 + in the internal driver data base from its default
78785 + configuration where's it's disabled.
78786 +
78787 + @Param[in] h_Fm A handle to an FM Module.
78788 + @Param[in] p_Emergency An OR mask of all required options.
78789 +
78790 + @Return E_OK on success; Error code otherwise.
78791 +
78792 + @Cautions Allowed only following FM_Config() and before FM_Init().
78793 + This routine should NOT be called from guest-partition
78794 + (i.e. guestId != NCSW_MASTER_ID)
78795 +*//***************************************************************************/
78796 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
78797 +
78798 +/**************************************************************************//**
78799 + @Function FM_ConfigDmaErr
78800 +
78801 + @Description DMA error treatment.
78802 + Calling this routine changes the DMA error treatment
78803 + in the internal driver data base from its default
78804 + configuration [DEFAULT_dmaErr].
78805 +
78806 + @Param[in] h_Fm A handle to an FM Module.
78807 + @Param[in] dmaErr The selected new choice.
78808 +
78809 + @Return E_OK on success; Error code otherwise.
78810 +
78811 + @Cautions Allowed only following FM_Config() and before FM_Init().
78812 + This routine should NOT be called from guest-partition
78813 + (i.e. guestId != NCSW_MASTER_ID)
78814 +*//***************************************************************************/
78815 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
78816 +
78817 +/**************************************************************************//**
78818 + @Function FM_ConfigCatastrophicErr
78819 +
78820 + @Description Define FM behavior on catastrophic error.
78821 + Calling this routine changes the FM behavior on catastrophic
78822 + error in the internal driver data base from its default
78823 + [DEFAULT_catastrophicErr].
78824 +
78825 + @Param[in] h_Fm A handle to an FM Module.
78826 + @Param[in] catastrophicErr The selected new choice.
78827 +
78828 + @Return E_OK on success; Error code otherwise.
78829 +
78830 + @Cautions Allowed only following FM_Config() and before FM_Init().
78831 + This routine should NOT be called from guest-partition
78832 + (i.e. guestId != NCSW_MASTER_ID)
78833 +*//***************************************************************************/
78834 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
78835 +
78836 +/**************************************************************************//**
78837 + @Function FM_ConfigEnableMuramTestMode
78838 +
78839 + @Description Enable MURAM test mode.
78840 + Calling this routine changes the internal driver data base
78841 + from its default selection of test mode where it's disabled.
78842 + This routine is only avaiable on old FM revisions (FMan v2).
78843 +
78844 + @Param[in] h_Fm A handle to an FM Module.
78845 +
78846 + @Return E_OK on success; Error code otherwise.
78847 +
78848 + @Cautions Allowed only following FM_Config() and before FM_Init().
78849 + This routine should NOT be called from guest-partition
78850 + (i.e. guestId != NCSW_MASTER_ID)
78851 +*//***************************************************************************/
78852 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
78853 +
78854 +/**************************************************************************//**
78855 + @Function FM_ConfigEnableIramTestMode
78856 +
78857 + @Description Enable IRAM test mode.
78858 + Calling this routine changes the internal driver data base
78859 + from its default selection of test mode where it's disabled.
78860 + This routine is only avaiable on old FM revisions (FMan v2).
78861 +
78862 + @Param[in] h_Fm A handle to an FM Module.
78863 +
78864 + @Return E_OK on success; Error code otherwise.
78865 +
78866 + @Cautions Allowed only following FM_Config() and before FM_Init().
78867 + This routine should NOT be called from guest-partition
78868 + (i.e. guestId != NCSW_MASTER_ID)
78869 +*//***************************************************************************/
78870 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
78871 +
78872 +/**************************************************************************//**
78873 + @Function FM_ConfigHaltOnExternalActivation
78874 +
78875 + @Description Define FM behavior on external halt activation.
78876 + Calling this routine changes the FM behavior on external halt
78877 + activation in the internal driver data base from its default
78878 + [DEFAULT_haltOnExternalActivation].
78879 +
78880 + @Param[in] h_Fm A handle to an FM Module.
78881 + @Param[in] enable TRUE to enable halt on external halt
78882 + activation.
78883 +
78884 + @Return E_OK on success; Error code otherwise.
78885 +
78886 + @Cautions Allowed only following FM_Config() and before FM_Init().
78887 + This routine should NOT be called from guest-partition
78888 + (i.e. guestId != NCSW_MASTER_ID)
78889 +*//***************************************************************************/
78890 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
78891 +
78892 +/**************************************************************************//**
78893 + @Function FM_ConfigHaltOnUnrecoverableEccError
78894 +
78895 + @Description Define FM behavior on external halt activation.
78896 + Calling this routine changes the FM behavior on unrecoverable
78897 + ECC error in the internal driver data base from its default
78898 + [DEFAULT_haltOnUnrecoverableEccError].
78899 + This routine is only avaiable on old FM revisions (FMan v2).
78900 +
78901 + @Param[in] h_Fm A handle to an FM Module.
78902 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
78903 +
78904 + @Return E_OK on success; Error code otherwise.
78905 +
78906 + @Cautions Allowed only following FM_Config() and before FM_Init().
78907 + This routine should NOT be called from guest-partition
78908 + (i.e. guestId != NCSW_MASTER_ID)
78909 +*//***************************************************************************/
78910 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
78911 +
78912 +/**************************************************************************//**
78913 + @Function FM_ConfigException
78914 +
78915 + @Description Define FM exceptions.
78916 + Calling this routine changes the exceptions defaults in the
78917 + internal driver data base where all exceptions are enabled.
78918 +
78919 + @Param[in] h_Fm A handle to an FM Module.
78920 + @Param[in] exception The exception to be selected.
78921 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
78922 +
78923 + @Return E_OK on success; Error code otherwise.
78924 +
78925 + @Cautions Allowed only following FM_Config() and before FM_Init().
78926 + This routine should NOT be called from guest-partition
78927 + (i.e. guestId != NCSW_MASTER_ID)
78928 +*//***************************************************************************/
78929 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
78930 +
78931 +/**************************************************************************//**
78932 + @Function FM_ConfigExternalEccRamsEnable
78933 +
78934 + @Description Select external ECC enabling.
78935 + Calling this routine changes the ECC enabling control in the internal
78936 + driver data base from its default [DEFAULT_externalEccRamsEnable].
78937 + When this option is enabled Rams ECC enabling is not effected
78938 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
78939 +
78940 + @Param[in] h_Fm A handle to an FM Module.
78941 + @Param[in] enable TRUE to enable this option.
78942 +
78943 + @Return E_OK on success; Error code otherwise.
78944 +
78945 + @Cautions Allowed only following FM_Config() and before FM_Init().
78946 + This routine should NOT be called from guest-partition
78947 + (i.e. guestId != NCSW_MASTER_ID)
78948 +*//***************************************************************************/
78949 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
78950 +
78951 +/**************************************************************************//**
78952 + @Function FM_ConfigTnumAgingPeriod
78953 +
78954 + @Description Define Tnum aging period.
78955 + Calling this routine changes the Tnum aging of dequeue TNUMs
78956 + in the QMI in the internal driver data base from its default
78957 + [DEFAULT_tnumAgingPeriod].
78958 +
78959 + @Param[in] h_Fm A handle to an FM Module.
78960 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
78961 + Note that period is recalculated in units of
78962 + 64 FM clocks. Driver will pick the closest
78963 + possible period.
78964 +
78965 + @Return E_OK on success; Error code otherwise.
78966 +
78967 + @Cautions Allowed only following FM_Config() and before FM_Init().
78968 + This routine should NOT be called from guest-partition
78969 + (i.e. guestId != NCSW_MASTER_ID)
78970 + NOTE that if some MAC is configured for PFC, '0' value is NOT
78971 + allowed.
78972 +*//***************************************************************************/
78973 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
78974 +
78975 +/**************************************************************************//*
78976 + @Function FM_ConfigDmaEmergencySmoother
78977 +
78978 + @Description Define DMA emergency smoother.
78979 + Calling this routine changes the definition of the minimum
78980 + amount of DATA beats transferred on the AXI READ and WRITE
78981 + ports before lowering the emergency level.
78982 + By default smoother is disabled.
78983 +
78984 + @Param[in] h_Fm A handle to an FM Module.
78985 + @Param[in] emergencyCnt emergency switching counter.
78986 +
78987 + @Return E_OK on success; Error code otherwise.
78988 +
78989 + @Cautions Allowed only following FM_Config() and before FM_Init().
78990 + This routine should NOT be called from guest-partition
78991 + (i.e. guestId != NCSW_MASTER_ID)
78992 +*//***************************************************************************/
78993 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
78994 +
78995 +/**************************************************************************//*
78996 + @Function FM_ConfigThresholds
78997 +
78998 + @Description Calling this routine changes the internal driver data base
78999 + from its default FM threshold configuration:
79000 + dispLimit: [DEFAULT_dispLimit]
79001 + prsDispTh: [DEFAULT_prsDispTh]
79002 + plcrDispTh: [DEFAULT_plcrDispTh]
79003 + kgDispTh: [DEFAULT_kgDispTh]
79004 + bmiDispTh: [DEFAULT_bmiDispTh]
79005 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
79006 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
79007 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
79008 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
79009 +
79010 +
79011 + @Param[in] h_Fm A handle to an FM Module.
79012 + @Param[in] p_FmThresholds A structure of threshold parameters.
79013 +
79014 + @Return E_OK on success; Error code otherwise.
79015 +
79016 + @Cautions Allowed only following FM_Config() and before FM_Init().
79017 + This routine should NOT be called from guest-partition
79018 + (i.e. guestId != NCSW_MASTER_ID)
79019 +*//***************************************************************************/
79020 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
79021 +
79022 +/**************************************************************************//*
79023 + @Function FM_ConfigDmaSosEmergencyThreshold
79024 +
79025 + @Description Calling this routine changes the internal driver data base
79026 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
79027 +
79028 + @Param[in] h_Fm A handle to an FM Module.
79029 + @Param[in] dmaSosEmergency The selected new value.
79030 +
79031 + @Return E_OK on success; Error code otherwise.
79032 +
79033 + @Cautions Allowed only following FM_Config() and before FM_Init().
79034 + This routine should NOT be called from guest-partition
79035 + (i.e. guestId != NCSW_MASTER_ID)
79036 +*//***************************************************************************/
79037 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
79038 +
79039 +/**************************************************************************//*
79040 + @Function FM_ConfigDmaWriteBufThresholds
79041 +
79042 + @Description Calling this routine changes the internal driver data base
79043 + from its default configuration of DMA write buffer threshold
79044 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
79045 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
79046 + This routine is only avaiable on old FM revisions (FMan v2).
79047 +
79048 + @Param[in] h_Fm A handle to an FM Module.
79049 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
79050 + When 'assertEmergency' value is reached, emergency is asserted,
79051 + then it is held until 'clearEmergency' value is reached.
79052 +
79053 + @Return E_OK on success; Error code otherwise.
79054 +
79055 + @Cautions Allowed only following FM_Config() and before FM_Init().
79056 + This routine should NOT be called from guest-partition
79057 + (i.e. guestId != NCSW_MASTER_ID)
79058 +*//***************************************************************************/
79059 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
79060 +
79061 + /**************************************************************************//*
79062 + @Function FM_ConfigDmaCommQThresholds
79063 +
79064 + @Description Calling this routine changes the internal driver data base
79065 + from its default configuration of DMA command queue threshold
79066 + assertEmergency: [DEFAULT_dmaCommQLow]
79067 + clearEmergency: [DEFAULT_dmaCommQHigh]
79068 +
79069 + @Param[in] h_Fm A handle to an FM Module.
79070 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
79071 + When 'assertEmergency' value is reached, emergency is asserted,
79072 + then it is held until 'clearEmergency' value is reached..
79073 +
79074 + @Return E_OK on success; Error code otherwise.
79075 +
79076 + @Cautions Allowed only following FM_Config() and before FM_Init().
79077 + This routine should NOT be called from guest-partition
79078 + (i.e. guestId != NCSW_MASTER_ID)
79079 +*//***************************************************************************/
79080 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
79081 +
79082 +/**************************************************************************//*
79083 + @Function FM_ConfigDmaReadBufThresholds
79084 +
79085 + @Description Calling this routine changes the internal driver data base
79086 + from its default configuration of DMA read buffer threshold
79087 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
79088 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
79089 + This routine is only avaiable on old FM revisions (FMan v2).
79090 +
79091 + @Param[in] h_Fm A handle to an FM Module.
79092 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
79093 + When 'assertEmergency' value is reached, emergency is asserted,
79094 + then it is held until 'clearEmergency' value is reached..
79095 +
79096 + @Return E_OK on success; Error code otherwise.
79097 +
79098 + @Cautions Allowed only following FM_Config() and before FM_Init().
79099 + This routine should NOT be called from guest-partition
79100 + (i.e. guestId != NCSW_MASTER_ID)
79101 +*//***************************************************************************/
79102 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
79103 +
79104 +/**************************************************************************//*
79105 + @Function FM_ConfigDmaWatchdog
79106 +
79107 + @Description Calling this routine changes the internal driver data base
79108 + from its default watchdog configuration, which is disabled
79109 + [DEFAULT_dmaWatchdog].
79110 +
79111 + @Param[in] h_Fm A handle to an FM Module.
79112 + @Param[in] watchDogValue The selected new value - in microseconds.
79113 +
79114 + @Return E_OK on success; Error code otherwise.
79115 +
79116 + @Cautions Allowed only following FM_Config() and before FM_Init().
79117 + This routine should NOT be called from guest-partition
79118 + (i.e. guestId != NCSW_MASTER_ID)
79119 +*//***************************************************************************/
79120 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
79121 +
79122 +/** @} */ /* end of FM_advanced_init_grp group */
79123 +/** @} */ /* end of FM_init_grp group */
79124 +
79125 +
79126 +/**************************************************************************//**
79127 + @Group FM_runtime_control_grp FM Runtime Control Unit
79128 +
79129 + @Description FM Runtime control unit API functions, definitions and enums.
79130 + The FM driver provides a set of control routines.
79131 + These routines may only be called after the module was fully
79132 + initialized (both configuration and initialization routines were
79133 + called). They are typically used to get information from hardware
79134 + (status, counters/statistics, revision etc.), to modify a current
79135 + state or to force/enable a required action. Run-time control may
79136 + be called whenever necessary and as many times as needed.
79137 + @{
79138 +*//***************************************************************************/
79139 +
79140 +/**************************************************************************//**
79141 + @Collection General FM defines.
79142 +*//***************************************************************************/
79143 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
79144 + FM_MAX_NUM_OF_1G_RX_PORTS + \
79145 + FM_MAX_NUM_OF_10G_RX_PORTS + \
79146 + FM_MAX_NUM_OF_1G_TX_PORTS + \
79147 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
79148 +/* @} */
79149 +
79150 +/**************************************************************************//*
79151 + @Description A Structure for Port bandwidth requirement. Port is identified
79152 + by type and relative id.
79153 +*//***************************************************************************/
79154 +typedef struct t_FmPortBandwidth {
79155 + e_FmPortType type; /**< FM port type */
79156 + uint8_t relativePortId; /**< Type relative port id */
79157 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
79158 +} t_FmPortBandwidth;
79159 +
79160 +/**************************************************************************//*
79161 + @Description A Structure containing an array of Port bandwidth requirements.
79162 + The user should state the ports requiring bandwidth in terms of
79163 + percentage - i.e. all port's bandwidths in the array must add
79164 + up to 100.
79165 +*//***************************************************************************/
79166 +typedef struct t_FmPortsBandwidthParams {
79167 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
79168 + number of valid entries in the array below */
79169 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
79170 + /**< for each port, it's bandwidth (all port's
79171 + bandwidths must add up to 100.*/
79172 +} t_FmPortsBandwidthParams;
79173 +
79174 +/**************************************************************************//**
79175 + @Description DMA Emergency control on MURAM
79176 +*//***************************************************************************/
79177 +typedef enum e_FmDmaMuramPort {
79178 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
79179 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
79180 +} e_FmDmaMuramPort;
79181 +
79182 +/**************************************************************************//**
79183 + @Description Enum for defining FM counters
79184 +*//***************************************************************************/
79185 +typedef enum e_FmCounters {
79186 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
79187 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
79188 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
79189 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
79190 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
79191 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
79192 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
79193 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
79194 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
79195 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
79196 +} e_FmCounters;
79197 +
79198 +/**************************************************************************//**
79199 + @Description A Structure for returning FM revision information
79200 +*//***************************************************************************/
79201 +typedef struct t_FmRevisionInfo {
79202 + uint8_t majorRev; /**< Major revision */
79203 + uint8_t minorRev; /**< Minor revision */
79204 +} t_FmRevisionInfo;
79205 +
79206 +/**************************************************************************//**
79207 + @Description A Structure for returning FM ctrl code revision information
79208 +*//***************************************************************************/
79209 +typedef struct t_FmCtrlCodeRevisionInfo {
79210 + uint16_t packageRev; /**< Package revision */
79211 + uint8_t majorRev; /**< Major revision */
79212 + uint8_t minorRev; /**< Minor revision */
79213 +} t_FmCtrlCodeRevisionInfo;
79214 +
79215 +/**************************************************************************//**
79216 + @Description A Structure for defining DMA status
79217 +*//***************************************************************************/
79218 +typedef struct t_FmDmaStatus {
79219 + bool cmqNotEmpty; /**< Command queue is not empty */
79220 + bool busError; /**< Bus error occurred */
79221 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
79222 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
79223 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
79224 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
79225 +} t_FmDmaStatus;
79226 +
79227 +/**************************************************************************//**
79228 + @Description A Structure for obtaining FM controller monitor values
79229 +*//***************************************************************************/
79230 +typedef struct t_FmCtrlMon {
79231 + uint8_t percentCnt[2]; /**< Percentage value */
79232 +} t_FmCtrlMon;
79233 +
79234 +
79235 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79236 +/**************************************************************************//**
79237 + @Function FM_DumpRegs
79238 +
79239 + @Description Dumps all FM registers
79240 +
79241 + @Param[in] h_Fm A handle to an FM Module.
79242 +
79243 + @Return E_OK on success;
79244 +
79245 + @Cautions Allowed only following FM_Init().
79246 +*//***************************************************************************/
79247 +t_Error FM_DumpRegs(t_Handle h_Fm);
79248 +#endif /* (defined(DEBUG_ERRORS) && ... */
79249 +
79250 +/**************************************************************************//**
79251 + @Function FM_SetException
79252 +
79253 + @Description Calling this routine enables/disables the specified exception.
79254 +
79255 + @Param[in] h_Fm A handle to an FM Module.
79256 + @Param[in] exception The exception to be selected.
79257 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79258 +
79259 + @Return E_OK on success; Error code otherwise.
79260 +
79261 + @Cautions Allowed only following FM_Init().
79262 + This routine should NOT be called from guest-partition
79263 + (i.e. guestId != NCSW_MASTER_ID)
79264 +*//***************************************************************************/
79265 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
79266 +
79267 +/**************************************************************************//**
79268 + @Function FM_EnableRamsEcc
79269 +
79270 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
79271 + MURAM, Parser, Keygen, Policer, etc.
79272 + Note:
79273 + If FM_ConfigExternalEccRamsEnable was called to enable external
79274 + setting of ECC, this routine effects IRAM ECC only.
79275 + This routine is also called by the driver if an ECC exception is
79276 + enabled.
79277 +
79278 + @Param[in] h_Fm A handle to an FM Module.
79279 +
79280 + @Return E_OK on success; Error code otherwise.
79281 +
79282 + @Cautions Allowed only following FM_Config() and before FM_Init().
79283 + This routine should NOT be called from guest-partition
79284 + (i.e. guestId != NCSW_MASTER_ID)
79285 +*//***************************************************************************/
79286 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
79287 +
79288 +/**************************************************************************//**
79289 + @Function FM_DisableRamsEcc
79290 +
79291 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
79292 + MURAM, Parser, Keygen, Policer, etc.
79293 + Note:
79294 + If FM_ConfigExternalEccRamsEnable was called to enable external
79295 + setting of ECC, this routine effects IRAM ECC only.
79296 + In opposed to FM_EnableRamsEcc, this routine must be called
79297 + explicitly to disable all Rams ECC.
79298 +
79299 + @Param[in] h_Fm A handle to an FM Module.
79300 +
79301 + @Return E_OK on success; Error code otherwise.
79302 +
79303 + @Cautions Allowed only following FM_Config() and before FM_Init().
79304 + This routine should NOT be called from guest-partition
79305 + (i.e. guestId != NCSW_MASTER_ID)
79306 +*//***************************************************************************/
79307 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
79308 +
79309 +/**************************************************************************//**
79310 + @Function FM_GetRevision
79311 +
79312 + @Description Returns the FM revision
79313 +
79314 + @Param[in] h_Fm A handle to an FM Module.
79315 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
79316 +
79317 + @Return E_OK on success; Error code otherwise.
79318 +
79319 + @Cautions Allowed only following FM_Init().
79320 +*//***************************************************************************/
79321 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
79322 +
79323 +/**************************************************************************//**
79324 + @Function FM_GetFmanCtrlCodeRevision
79325 +
79326 + @Description Returns the Fman controller code revision
79327 +
79328 + @Param[in] h_Fm A handle to an FM Module.
79329 + @Param[out] p_RevisionInfo A structure of revision information parameters.
79330 +
79331 + @Return E_OK on success; Error code otherwise.
79332 +
79333 + @Cautions Allowed only following FM_Init().
79334 +*//***************************************************************************/
79335 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
79336 +
79337 +/**************************************************************************//**
79338 + @Function FM_GetCounter
79339 +
79340 + @Description Reads one of the FM counters.
79341 +
79342 + @Param[in] h_Fm A handle to an FM Module.
79343 + @Param[in] counter The requested counter.
79344 +
79345 + @Return Counter's current value.
79346 +
79347 + @Cautions Allowed only following FM_Init().
79348 + Note that it is user's responsibility to call this routine only
79349 + for enabled counters, and there will be no indication if a
79350 + disabled counter is accessed.
79351 +*//***************************************************************************/
79352 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
79353 +
79354 +/**************************************************************************//**
79355 + @Function FM_ModifyCounter
79356 +
79357 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
79358 +
79359 + @Param[in] h_Fm A handle to an FM Module.
79360 + @Param[in] counter The requested counter.
79361 + @Param[in] val The requested value to be written into the counter.
79362 +
79363 + @Return E_OK on success; Error code otherwise.
79364 +
79365 + @Cautions Allowed only following FM_Init().
79366 + This routine should NOT be called from guest-partition
79367 + (i.e. guestId != NCSW_MASTER_ID)
79368 +*//***************************************************************************/
79369 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
79370 +
79371 +/**************************************************************************//**
79372 + @Function FM_Resume
79373 +
79374 + @Description Release FM after halt FM command or after unrecoverable ECC error.
79375 +
79376 + @Param[in] h_Fm A handle to an FM Module.
79377 +
79378 + @Return E_OK on success; Error code otherwise.
79379 +
79380 + @Cautions Allowed only following FM_Init().
79381 + This routine should NOT be called from guest-partition
79382 + (i.e. guestId != NCSW_MASTER_ID)
79383 +*//***************************************************************************/
79384 +void FM_Resume(t_Handle h_Fm);
79385 +
79386 +/**************************************************************************//**
79387 + @Function FM_SetDmaEmergency
79388 +
79389 + @Description Manual emergency set
79390 +
79391 + @Param[in] h_Fm A handle to an FM Module.
79392 + @Param[in] muramPort MURAM direction select.
79393 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
79394 +
79395 + @Return None.
79396 +
79397 + @Cautions Allowed only following FM_Init().
79398 + This routine should NOT be called from guest-partition
79399 + (i.e. guestId != NCSW_MASTER_ID)
79400 +*//***************************************************************************/
79401 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
79402 +
79403 +/**************************************************************************//**
79404 + @Function FM_SetDmaExtBusPri
79405 +
79406 + @Description Set the DMA external bus priority
79407 +
79408 + @Param[in] h_Fm A handle to an FM Module.
79409 + @Param[in] pri External bus priority select
79410 +
79411 + @Return None.
79412 +
79413 + @Cautions Allowed only following FM_Init().
79414 + This routine should NOT be called from guest-partition
79415 + (i.e. guestId != NCSW_MASTER_ID)
79416 +*//***************************************************************************/
79417 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
79418 +
79419 +/**************************************************************************//**
79420 + @Function FM_GetDmaStatus
79421 +
79422 + @Description Reads the DMA current status
79423 +
79424 + @Param[in] h_Fm A handle to an FM Module.
79425 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
79426 +
79427 + @Cautions Allowed only following FM_Init().
79428 +*//***************************************************************************/
79429 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
79430 +
79431 +/**************************************************************************//**
79432 + @Function FM_ErrorIsr
79433 +
79434 + @Description FM interrupt-service-routine for errors.
79435 +
79436 + @Param[in] h_Fm A handle to an FM Module.
79437 +
79438 + @Return E_OK on success; E_EMPTY if no errors found in register, other
79439 + error code otherwise.
79440 +
79441 + @Cautions Allowed only following FM_Init().
79442 + This routine should NOT be called from guest-partition
79443 + (i.e. guestId != NCSW_MASTER_ID)
79444 +*//***************************************************************************/
79445 +t_Error FM_ErrorIsr(t_Handle h_Fm);
79446 +
79447 +/**************************************************************************//**
79448 + @Function FM_EventIsr
79449 +
79450 + @Description FM interrupt-service-routine for normal events.
79451 +
79452 + @Param[in] h_Fm A handle to an FM Module.
79453 +
79454 + @Cautions Allowed only following FM_Init().
79455 + This routine should NOT be called from guest-partition
79456 + (i.e. guestId != NCSW_MASTER_ID)
79457 +*//***************************************************************************/
79458 +void FM_EventIsr(t_Handle h_Fm);
79459 +
79460 +/**************************************************************************//**
79461 + @Function FM_GetSpecialOperationCoding
79462 +
79463 + @Description Return a specific coding according to the input mask.
79464 +
79465 + @Param[in] h_Fm A handle to an FM Module.
79466 + @Param[in] spOper special operation mask.
79467 + @Param[out] p_SpOperCoding special operation code.
79468 +
79469 + @Return E_OK on success; Error code otherwise.
79470 +
79471 + @Cautions Allowed only following FM_Init().
79472 +*//***************************************************************************/
79473 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
79474 + fmSpecialOperations_t spOper,
79475 + uint8_t *p_SpOperCoding);
79476 +
79477 +/**************************************************************************//**
79478 + @Function FM_CtrlMonStart
79479 +
79480 + @Description Start monitoring utilization of all available FM controllers.
79481 +
79482 + In order to obtain FM controllers utilization the following sequence
79483 + should be used:
79484 + -# FM_CtrlMonStart()
79485 + -# FM_CtrlMonStop()
79486 + -# FM_CtrlMonGetCounters() - issued for each FM controller
79487 +
79488 + @Param[in] h_Fm A handle to an FM Module.
79489 +
79490 + @Return E_OK on success; Error code otherwise.
79491 +
79492 + @Cautions Allowed only following FM_Init().
79493 + This routine should NOT be called from guest-partition
79494 + (i.e. guestId != NCSW_MASTER_ID).
79495 +*//***************************************************************************/
79496 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
79497 +
79498 +/**************************************************************************//**
79499 + @Function FM_CtrlMonStop
79500 +
79501 + @Description Stop monitoring utilization of all available FM controllers.
79502 +
79503 + In order to obtain FM controllers utilization the following sequence
79504 + should be used:
79505 + -# FM_CtrlMonStart()
79506 + -# FM_CtrlMonStop()
79507 + -# FM_CtrlMonGetCounters() - issued for each FM controller
79508 +
79509 + @Param[in] h_Fm A handle to an FM Module.
79510 +
79511 + @Return E_OK on success; Error code otherwise.
79512 +
79513 + @Cautions Allowed only following FM_Init().
79514 + This routine should NOT be called from guest-partition
79515 + (i.e. guestId != NCSW_MASTER_ID).
79516 +*//***************************************************************************/
79517 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
79518 +
79519 +/**************************************************************************//**
79520 + @Function FM_CtrlMonGetCounters
79521 +
79522 + @Description Obtain FM controller utilization parameters.
79523 +
79524 + In order to obtain FM controllers utilization the following sequence
79525 + should be used:
79526 + -# FM_CtrlMonStart()
79527 + -# FM_CtrlMonStop()
79528 + -# FM_CtrlMonGetCounters() - issued for each FM controller
79529 +
79530 + @Param[in] h_Fm A handle to an FM Module.
79531 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
79532 + are requested.
79533 + @Param[in] p_Mon Pointer to utilization results structure.
79534 +
79535 + @Return E_OK on success; Error code otherwise.
79536 +
79537 + @Cautions Allowed only following FM_Init().
79538 + This routine should NOT be called from guest-partition
79539 + (i.e. guestId != NCSW_MASTER_ID).
79540 +*//***************************************************************************/
79541 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
79542 +
79543 +
79544 +/**************************************************************************//*
79545 + @Function FM_ForceIntr
79546 +
79547 + @Description Causes an interrupt event on the requested source.
79548 +
79549 + @Param[in] h_Fm A handle to an FM Module.
79550 + @Param[in] exception An exception to be forced.
79551 +
79552 + @Return E_OK on success; Error code if the exception is not enabled,
79553 + or is not able to create interrupt.
79554 +
79555 + @Cautions Allowed only following FM_Init().
79556 + This routine should NOT be called from guest-partition
79557 + (i.e. guestId != NCSW_MASTER_ID)
79558 +*//***************************************************************************/
79559 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
79560 +
79561 +/**************************************************************************//*
79562 + @Function FM_SetPortsBandwidth
79563 +
79564 + @Description Sets relative weights between ports when accessing common resources.
79565 +
79566 + @Param[in] h_Fm A handle to an FM Module.
79567 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
79568 + total must equal 100.
79569 +
79570 + @Return E_OK on success; Error code otherwise.
79571 +
79572 + @Cautions Allowed only following FM_Init().
79573 + This routine should NOT be called from guest-partition
79574 + (i.e. guestId != NCSW_MASTER_ID)
79575 +*//***************************************************************************/
79576 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
79577 +
79578 +/**************************************************************************//*
79579 + @Function FM_GetMuramHandle
79580 +
79581 + @Description Gets the corresponding MURAM handle
79582 +
79583 + @Param[in] h_Fm A handle to an FM Module.
79584 +
79585 + @Return MURAM handle; NULL otherwise.
79586 +
79587 + @Cautions Allowed only following FM_Init().
79588 + This routine should NOT be called from guest-partition
79589 + (i.e. guestId != NCSW_MASTER_ID)
79590 +*//***************************************************************************/
79591 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
79592 +
79593 +/** @} */ /* end of FM_runtime_control_grp group */
79594 +/** @} */ /* end of FM_lib_grp group */
79595 +/** @} */ /* end of FM_grp group */
79596 +
79597 +
79598 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
79599 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
79600 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
79601 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
79602 +typedef t_FmExtPools t_FmPortExtPools;
79603 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
79604 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
79605 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
79606 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
79607 +
79608 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
79609 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
79610 +
79611 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
79612 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
79613 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
79614 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
79615 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
79616 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
79617 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
79618 +
79619 +
79620 +#endif /* __FM_EXT */
79621 --- /dev/null
79622 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
79623 @@ -0,0 +1,887 @@
79624 +/*
79625 + * Copyright 2008-2012 Freescale Semiconductor Inc.
79626 + *
79627 + * Redistribution and use in source and binary forms, with or without
79628 + * modification, are permitted provided that the following conditions are met:
79629 + * * Redistributions of source code must retain the above copyright
79630 + * notice, this list of conditions and the following disclaimer.
79631 + * * Redistributions in binary form must reproduce the above copyright
79632 + * notice, this list of conditions and the following disclaimer in the
79633 + * documentation and/or other materials provided with the distribution.
79634 + * * Neither the name of Freescale Semiconductor nor the
79635 + * names of its contributors may be used to endorse or promote products
79636 + * derived from this software without specific prior written permission.
79637 + *
79638 + *
79639 + * ALTERNATIVELY, this software may be distributed under the terms of the
79640 + * GNU General Public License ("GPL") as published by the Free Software
79641 + * Foundation, either version 2 of that License or (at your option) any
79642 + * later version.
79643 + *
79644 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
79645 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79646 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79647 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
79648 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79649 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79650 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
79651 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79652 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79653 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79654 + */
79655 +
79656 +
79657 +/**************************************************************************//**
79658 + @File fm_mac_ext.h
79659 +
79660 + @Description FM MAC ...
79661 +*//***************************************************************************/
79662 +#ifndef __FM_MAC_EXT_H
79663 +#define __FM_MAC_EXT_H
79664 +
79665 +#include "std_ext.h"
79666 +#include "enet_ext.h"
79667 +
79668 +
79669 +/**************************************************************************//**
79670 +
79671 + @Group FM_grp Frame Manager API
79672 +
79673 + @Description FM API functions, definitions and enums
79674 +
79675 + @{
79676 +*//***************************************************************************/
79677 +
79678 +/**************************************************************************//**
79679 + @Group FM_mac_grp FM MAC
79680 +
79681 + @Description FM MAC API functions, definitions and enums
79682 +
79683 + @{
79684 +*//***************************************************************************/
79685 +
79686 +#define FM_MAC_NO_PFC 0xff
79687 +
79688 +
79689 +/**************************************************************************//**
79690 + @Description FM MAC Exceptions
79691 +*//***************************************************************************/
79692 +typedef enum e_FmMacExceptions {
79693 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
79694 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
79695 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
79696 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
79697 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
79698 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
79699 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
79700 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
79701 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
79702 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
79703 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
79704 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
79705 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
79706 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
79707 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
79708 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
79709 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
79710 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
79711 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
79712 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
79713 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
79714 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
79715 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
79716 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
79717 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
79718 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
79719 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
79720 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
79721 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
79722 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
79723 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
79724 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
79725 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
79726 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
79727 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
79728 + not supported on T4240/B4860 rev1 chips */
79729 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
79730 + /**< mEMAC Magic Packet Indication Interrupt */
79731 +} e_FmMacExceptions;
79732 +
79733 +/**************************************************************************//**
79734 + @Description TM MAC statistics level
79735 +*//***************************************************************************/
79736 +typedef enum e_FmMacStatisticsLevel {
79737 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
79738 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
79739 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
79740 +} e_FmMacStatisticsLevel;
79741 +
79742 +
79743 +#if (DPAA_VERSION >= 11)
79744 +/**************************************************************************//**
79745 + @Description Priority Flow Control Parameters
79746 +*//***************************************************************************/
79747 +typedef struct t_FmMacPfcParams {
79748 + bool pfcEnable; /**< Enable/Disable PFC */
79749 +
79750 + 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*/
79751 +
79752 + 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*/
79753 +
79754 +
79755 +} t_FmMacPfcParams;
79756 +#endif /* (DPAA_VERSION >= 11) */
79757 +
79758 +/**************************************************************************//**
79759 + @Function t_FmMacExceptionCallback
79760 +
79761 + @Description Fm Mac Exception Callback from FM MAC to the user
79762 +
79763 + @Param[in] h_App - Handle to the upper layer handler
79764 +
79765 + @Param[in] exceptions - The exception that occurred
79766 +
79767 + @Return void.
79768 +*//***************************************************************************/
79769 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
79770 +
79771 +
79772 +/**************************************************************************//**
79773 + @Description TM MAC statistics rfc3635
79774 +*//***************************************************************************/
79775 +typedef struct t_FmMacStatistics {
79776 +/* RMON */
79777 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
79778 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
79779 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
79780 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
79781 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
79782 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
79783 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
79784 +/* */
79785 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
79786 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
79787 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
79788 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
79789 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
79790 + This count does not include range length errors */
79791 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
79792 + a valid FCS and otherwise well formed */
79793 +/* Pause */
79794 + uint64_t teStatPause; /**< Pause MAC Control received */
79795 + uint64_t reStatPause; /**< Pause MAC Control sent */
79796 +/* MIB II */
79797 + uint64_t ifInOctets; /**< Total number of byte received. */
79798 + uint64_t ifInPkts; /**< Total number of packets received.*/
79799 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
79800 + NOTE: this counter is not supported on dTSEC MAC */
79801 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
79802 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79803 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
79804 + uint64_t ifInErrors; /**< Number of frames received with error:
79805 + - FIFO Overflow Error
79806 + - CRC Error
79807 + - Frame Too Long Error
79808 + - Alignment Error
79809 + - The dedicated Error Code (0xfe, not a code error) was received */
79810 + uint64_t ifOutOctets; /**< Total number of byte sent. */
79811 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
79812 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
79813 + NOTE: this counter is not supported on dTSEC MAC */
79814 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79815 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79816 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
79817 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79818 + - FIFO Overflow Error
79819 + - FIFO Underflow Error
79820 + - Other */
79821 +} t_FmMacStatistics;
79822 +
79823 +/**************************************************************************//**
79824 + @Description FM MAC Frame Size Counters
79825 +*//***************************************************************************/
79826 +typedef struct t_FmMacFrameSizeCounters {
79827 +
79828 + uint64_t count_pkts_64; /**< 64 byte frame counter */
79829 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
79830 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
79831 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
79832 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
79833 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
79834 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
79835 +} t_FmMacFrameSizeCounters;
79836 +
79837 +/**************************************************************************//**
79838 + @Group FM_mac_init_grp FM MAC Initialization Unit
79839 +
79840 + @Description FM MAC Initialization Unit
79841 +
79842 + @{
79843 +*//***************************************************************************/
79844 +
79845 +/**************************************************************************//**
79846 + @Description FM MAC config input
79847 +*//***************************************************************************/
79848 +typedef struct t_FmMacParams {
79849 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
79850 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
79851 + uint8_t macId; /**< MAC ID;
79852 + numbering of dTSEC and 1G-mEMAC:
79853 + 0 - FM_MAX_NUM_OF_1G_MACS;
79854 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
79855 + 0 - FM_MAX_NUM_OF_10G_MACS */
79856 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
79857 + Note that the speed should indicate the maximum rate that
79858 + this MAC should support rather than the actual speed;
79859 + i.e. user should use the FM_MAC_AdjustLink() routine to
79860 + provide accurate speed;
79861 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
79862 + automatic mode, where actual speed/duplex mode information
79863 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
79864 + function should be used to switch to manual RGMII speed/duplex mode
79865 + configuration if RGMII PHY doesn't support in-band status signaling;
79866 + In addition, in mEMAC, in case where user is using the higher MACs
79867 + (i.e. the MACs that should support 10G), user should pass here
79868 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
79869 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
79870 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
79871 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
79872 + mdio-irq, or for polling */
79873 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
79874 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
79875 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79876 + be passed by the driver upon calling the above callbacks */
79877 +} t_FmMacParams;
79878 +
79879 +
79880 +/**************************************************************************//**
79881 + @Function FM_MAC_Config
79882 +
79883 + @Description Creates descriptor for the FM MAC module.
79884 +
79885 + The routine returns a handle (descriptor) to the FM MAC object.
79886 + This descriptor must be passed as first parameter to all other
79887 + FM MAC function calls.
79888 +
79889 + No actual initialization or configuration of FM MAC hardware is
79890 + done by this routine.
79891 +
79892 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
79893 +
79894 + @Retval Handle to FM MAC object, or NULL for Failure.
79895 +*//***************************************************************************/
79896 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
79897 +
79898 +/**************************************************************************//**
79899 + @Function FM_MAC_Init
79900 +
79901 + @Description Initializes the FM MAC module
79902 +
79903 + @Param[in] h_FmMac - FM module descriptor
79904 +
79905 + @Return E_OK on success; Error code otherwise.
79906 +*//***************************************************************************/
79907 +t_Error FM_MAC_Init(t_Handle h_FmMac);
79908 +
79909 +/**************************************************************************//**
79910 + @Function FM_Free
79911 +
79912 + @Description Frees all resources that were assigned to FM MAC module.
79913 +
79914 + Calling this routine invalidates the descriptor.
79915 +
79916 + @Param[in] h_FmMac - FM module descriptor
79917 +
79918 + @Return E_OK on success; Error code otherwise.
79919 +*//***************************************************************************/
79920 +t_Error FM_MAC_Free(t_Handle h_FmMac);
79921 +
79922 +
79923 +/**************************************************************************//**
79924 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
79925 +
79926 + @Description Configuration functions used to change default values.
79927 +
79928 + @{
79929 +*//***************************************************************************/
79930 +
79931 +/**************************************************************************//**
79932 + @Function FM_MAC_ConfigResetOnInit
79933 +
79934 + @Description Tell the driver whether to reset the FM MAC before initialization or
79935 + not. It changes the default configuration [DEFAULT_resetOnInit].
79936 +
79937 + @Param[in] h_FmMac A handle to a FM MAC Module.
79938 + @Param[in] enable When TRUE, FM will be reset before any initialization.
79939 +
79940 + @Return E_OK on success; Error code otherwise.
79941 +
79942 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
79943 +*//***************************************************************************/
79944 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
79945 +
79946 +/**************************************************************************//**
79947 + @Function FM_MAC_ConfigLoopback
79948 +
79949 + @Description Enable/Disable internal loopback mode
79950 +
79951 + @Param[in] h_FmMac A handle to a FM MAC Module.
79952 + @Param[in] enable TRUE to enable or FALSE to disable.
79953 +
79954 + @Return E_OK on success; Error code otherwise.
79955 +
79956 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
79957 +*//***************************************************************************/
79958 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
79959 +
79960 +/**************************************************************************//**
79961 + @Function FM_MAC_ConfigMaxFrameLength
79962 +
79963 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
79964 +
79965 + @Param[in] h_FmMac A handle to a FM MAC Module.
79966 + @Param[in] newVal MAX Frame length
79967 +
79968 + @Return E_OK on success; Error code otherwise.
79969 +
79970 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
79971 +*//***************************************************************************/
79972 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
79973 +
79974 +/**************************************************************************//**
79975 + @Function FM_MAC_ConfigWan
79976 +
79977 + @Description ENABLE WAN mode in 10G-MAC
79978 +
79979 + @Param[in] h_FmMac A handle to a FM MAC Module.
79980 + @Param[in] enable TRUE to enable or FALSE to disable.
79981 +
79982 + @Return E_OK on success; Error code otherwise.
79983 +
79984 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
79985 +*//***************************************************************************/
79986 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
79987 +
79988 +/**************************************************************************//**
79989 + @Function FM_MAC_ConfigPadAndCrc
79990 +
79991 + @Description Config PAD and CRC mode
79992 +
79993 + @Param[in] h_FmMac A handle to a FM MAC Module.
79994 + @Param[in] enable TRUE to enable or FALSE to disable.
79995 +
79996 + @Return E_OK on success; Error code otherwise.
79997 +
79998 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
79999 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
80000 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
80001 + added automatically by HW).
80002 +*//***************************************************************************/
80003 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
80004 +
80005 +/**************************************************************************//**
80006 + @Function FM_MAC_ConfigHalfDuplex
80007 +
80008 + @Description Config Half Duplex Mode
80009 +
80010 + @Param[in] h_FmMac A handle to a FM MAC Module.
80011 + @Param[in] enable TRUE to enable or FALSE to disable.
80012 +
80013 + @Return E_OK on success; Error code otherwise.
80014 +
80015 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80016 +*//***************************************************************************/
80017 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
80018 +
80019 +/**************************************************************************//**
80020 + @Function FM_MAC_ConfigTbiPhyAddr
80021 +
80022 + @Description Configures the address of internal TBI PHY.
80023 +
80024 + @Param[in] h_FmMac A handle to a FM MAC Module.
80025 + @Param[in] newVal TBI PHY address (1-31).
80026 +
80027 + @Return E_OK on success; Error code otherwise.
80028 +
80029 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80030 +*//***************************************************************************/
80031 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
80032 +
80033 +/**************************************************************************//**
80034 + @Function FM_MAC_ConfigLengthCheck
80035 +
80036 + @Description Configure the frame length checking.
80037 +
80038 + @Param[in] h_FmMac A handle to a FM MAC Module.
80039 + @Param[in] enable TRUE to enable or FALSE to disable.
80040 +
80041 + @Return E_OK on success; Error code otherwise.
80042 +
80043 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80044 +*//***************************************************************************/
80045 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
80046 +
80047 +/**************************************************************************//**
80048 + @Function FM_MAC_ConfigException
80049 +
80050 + @Description Change Exception selection from default
80051 +
80052 + @Param[in] h_FmMac A handle to a FM MAC Module.
80053 + @Param[in] ex Type of the desired exceptions
80054 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
80055 +
80056 + @Return E_OK on success; Error code otherwise.
80057 +
80058 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80059 +*//***************************************************************************/
80060 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
80061 +
80062 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
80063 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
80064 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
80065 +/** @} */ /* end of FM_mac_advanced_init_grp group */
80066 +/** @} */ /* end of FM_mac_init_grp group */
80067 +
80068 +
80069 +/**************************************************************************//**
80070 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
80071 +
80072 + @Description FM MAC Runtime control unit API functions, definitions and enums.
80073 +
80074 + @{
80075 +*//***************************************************************************/
80076 +
80077 +/**************************************************************************//**
80078 + @Function FM_MAC_Enable
80079 +
80080 + @Description Enable the MAC
80081 +
80082 + @Param[in] h_FmMac A handle to a FM MAC Module.
80083 + @Param[in] mode Mode of operation (RX, TX, Both)
80084 +
80085 + @Return E_OK on success; Error code otherwise.
80086 +
80087 + @Cautions Allowed only following FM_MAC_Init().
80088 +*//***************************************************************************/
80089 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
80090 +
80091 +/**************************************************************************//**
80092 + @Function FM_MAC_Disable
80093 +
80094 + @Description DISABLE the MAC
80095 +
80096 + @Param[in] h_FmMac A handle to a FM MAC Module.
80097 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
80098 +
80099 + @Return E_OK on success; Error code otherwise.
80100 +
80101 + @Cautions Allowed only following FM_MAC_Init().
80102 +*//***************************************************************************/
80103 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
80104 +
80105 +/**************************************************************************//**
80106 + @Function FM_MAC_Resume
80107 +
80108 + @Description Re-init the MAC after suspend
80109 +
80110 + @Param[in] h_FmMac A handle to a FM MAC Module.
80111 +
80112 + @Return E_OK on success; Error code otherwise.
80113 +
80114 + @Cautions Allowed only following FM_MAC_Init().
80115 +*//***************************************************************************/
80116 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
80117 +
80118 +/**************************************************************************//**
80119 + @Function FM_MAC_Enable1588TimeStamp
80120 +
80121 + @Description Enables the TSU operation.
80122 +
80123 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
80124 +
80125 + @Return E_OK on success; Error code otherwise.
80126 +
80127 + @Cautions Allowed only following FM_MAC_Init().
80128 +*//***************************************************************************/
80129 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
80130 +
80131 +/**************************************************************************//**
80132 + @Function FM_MAC_Disable1588TimeStamp
80133 +
80134 + @Description Disables the TSU operation.
80135 +
80136 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
80137 +
80138 + @Return E_OK on success; Error code otherwise.
80139 +
80140 + @Cautions Allowed only following FM_MAC_Init().
80141 +*//***************************************************************************/
80142 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
80143 +
80144 +/**************************************************************************//**
80145 + @Function FM_MAC_SetTxAutoPauseFrames
80146 +
80147 + @Description Enable/Disable transmission of Pause-Frames.
80148 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
80149 +
80150 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80151 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
80152 + Each quanta represents a 512 bit-times; Note that '0'
80153 + as an input here will be used as disabling the
80154 + transmission of the pause-frames.
80155 +
80156 + @Return E_OK on success; Error code otherwise.
80157 +
80158 + @Cautions Allowed only following FM_MAC_Init().
80159 +*//***************************************************************************/
80160 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
80161 + uint16_t pauseTime);
80162 +
80163 + /**************************************************************************//**
80164 + @Function FM_MAC_SetTxPauseFrames
80165 +
80166 + @Description Enable/Disable transmission of Pause-Frames.
80167 + The routine changes the default configuration:
80168 + pause-time - [DEFAULT_TX_PAUSE_TIME]
80169 + threshold-time - [0]
80170 +
80171 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80172 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
80173 + to indicate legacy pause support (i.e. no PFC).
80174 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
80175 + Each quanta represents a 512 bit-times;
80176 + Note that '0' as an input here will be used as disabling the
80177 + transmission of the pause-frames.
80178 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
80179 + if the situation causing a pause frame to be sent didn't finish when the timer
80180 + reached the threshold quanta, the MAC will retransmit the pause frame.
80181 + Each quanta represents a 512 bit-times.
80182 +
80183 + @Return E_OK on success; Error code otherwise.
80184 +
80185 + @Cautions Allowed only following FM_MAC_Init().
80186 + In order for PFC to work properly the user must configure
80187 + TNUM-aging in the tx-port it is recommended that pre-fetch and
80188 + rate limit in the tx port should be disabled;
80189 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
80190 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
80191 + in the 'priority' field.
80192 +*//***************************************************************************/
80193 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
80194 + uint8_t priority,
80195 + uint16_t pauseTime,
80196 + uint16_t threshTime);
80197 +
80198 +/**************************************************************************//**
80199 + @Function FM_MAC_SetRxIgnorePauseFrames
80200 +
80201 + @Description Enable/Disable ignoring of Pause-Frames.
80202 +
80203 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80204 + @Param[in] en - boolean indicates whether to ignore the incoming pause
80205 + frames or not.
80206 +
80207 + @Return E_OK on success; Error code otherwise.
80208 +
80209 + @Cautions Allowed only following FM_MAC_Init().
80210 +*//***************************************************************************/
80211 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
80212 +
80213 +/**************************************************************************//**
80214 + @Function FM_MAC_SetWakeOnLan
80215 +
80216 + @Description Enable/Disable Wake On Lan support
80217 +
80218 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80219 + @Param[in] en - boolean indicates whether to enable Wake On Lan
80220 + support or not.
80221 +
80222 + @Return E_OK on success; Error code otherwise.
80223 +
80224 + @Cautions Allowed only following FM_MAC_Init().
80225 +*//***************************************************************************/
80226 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
80227 +
80228 +/**************************************************************************//**
80229 + @Function FM_MAC_ResetCounters
80230 +
80231 + @Description reset all statistics counters
80232 +
80233 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80234 +
80235 + @Return E_OK on success; Error code otherwise.
80236 +
80237 + @Cautions Allowed only following FM_MAC_Init().
80238 +*//***************************************************************************/
80239 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
80240 +
80241 +/**************************************************************************//**
80242 + @Function FM_MAC_SetException
80243 +
80244 + @Description Enable/Disable a specific Exception
80245 +
80246 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80247 + @Param[in] ex - Type of the desired exceptions
80248 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
80249 +
80250 +
80251 + @Return E_OK on success; Error code otherwise.
80252 +
80253 + @Cautions Allowed only following FM_MAC_Init().
80254 +*//***************************************************************************/
80255 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
80256 +
80257 +/**************************************************************************//**
80258 + @Function FM_MAC_SetStatistics
80259 +
80260 + @Description Define Statistics level.
80261 + Where applicable, the routine also enables the MIB counters
80262 + overflow interrupt in order to keep counters accurate
80263 + and account for overflows.
80264 + This routine is relevant only for dTSEC.
80265 +
80266 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80267 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
80268 + reduce performance. Partial statistics provides only special
80269 + event counters (errors etc.). If selected, regular counters (such as
80270 + byte/packet) will be invalid and will return -1.
80271 +
80272 + @Return E_OK on success; Error code otherwise.
80273 +
80274 + @Cautions Allowed only following FM_MAC_Init().
80275 +*//***************************************************************************/
80276 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
80277 +
80278 +/**************************************************************************//**
80279 + @Function FM_MAC_GetStatistics
80280 +
80281 + @Description get all statistics counters
80282 +
80283 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80284 + @Param[in] p_Statistics - Structure with statistics
80285 +
80286 + @Return E_OK on success; Error code otherwise.
80287 +
80288 + @Cautions Allowed only following FM_Init().
80289 +*//***************************************************************************/
80290 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
80291 +
80292 +/**************************************************************************//**
80293 + @Function FM_MAC_GetFrameSizeCounters
80294 +
80295 + @Description get MAC statistics counters for different frame size
80296 +
80297 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80298 + @Param[in] p_FrameSizeCounters - Structure with counters
80299 + @Param[in] type - Type of counters to be read
80300 +
80301 + @Return E_OK on success; Error code otherwise.
80302 +
80303 + @Cautions Allowed only following FM_Init().
80304 +*//***************************************************************************/
80305 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
80306 +
80307 +/**************************************************************************//**
80308 + @Function FM_MAC_ModifyMacAddr
80309 +
80310 + @Description Replace the main MAC Address
80311 +
80312 + @Param[in] h_FmMac - A handle to a FM Module.
80313 + @Param[in] p_EnetAddr - Ethernet Mac address
80314 +
80315 + @Return E_OK on success; Error code otherwise.
80316 +
80317 + @Cautions Allowed only after FM_MAC_Init().
80318 +*//***************************************************************************/
80319 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80320 +
80321 +/**************************************************************************//**
80322 + @Function FM_MAC_AddHashMacAddr
80323 +
80324 + @Description Add an Address to the hash table. This is for filter purpose only.
80325 +
80326 + @Param[in] h_FmMac - A handle to a FM Module.
80327 + @Param[in] p_EnetAddr - Ethernet Mac address
80328 +
80329 + @Return E_OK on success; Error code otherwise.
80330 +
80331 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
80332 + @Cautions Some address need to be filterd out in upper FM blocks.
80333 +*//***************************************************************************/
80334 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80335 +
80336 +/**************************************************************************//**
80337 + @Function FM_MAC_RemoveHashMacAddr
80338 +
80339 + @Description Delete an Address to the hash table. This is for filter purpose only.
80340 +
80341 + @Param[in] h_FmMac - A handle to a FM Module.
80342 + @Param[in] p_EnetAddr - Ethernet Mac address
80343 +
80344 + @Return E_OK on success; Error code otherwise.
80345 +
80346 + @Cautions Allowed only following FM_MAC_Init().
80347 +*//***************************************************************************/
80348 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80349 +
80350 +/**************************************************************************//**
80351 + @Function FM_MAC_AddExactMatchMacAddr
80352 +
80353 + @Description Add a unicast or multicast mac address for exact-match filtering
80354 + (8 on dTSEC, 2 for 10G-MAC)
80355 +
80356 + @Param[in] h_FmMac - A handle to a FM Module.
80357 + @Param[in] p_EnetAddr - MAC Address to ADD
80358 +
80359 + @Return E_OK on success; Error code otherwise.
80360 +
80361 + @Cautions Allowed only after FM_MAC_Init().
80362 +*//***************************************************************************/
80363 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80364 +
80365 +/**************************************************************************//**
80366 + @Function FM_MAC_RemovelExactMatchMacAddr
80367 +
80368 + @Description Remove a uni cast or multi cast mac address.
80369 +
80370 + @Param[in] h_FmMac - A handle to a FM Module.
80371 + @Param[in] p_EnetAddr - MAC Address to remove
80372 +
80373 + @Return E_OK on success; Error code otherwise..
80374 +
80375 + @Cautions Allowed only after FM_MAC_Init().
80376 +*//***************************************************************************/
80377 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80378 +
80379 +/**************************************************************************//**
80380 + @Function FM_MAC_SetPromiscuous
80381 +
80382 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
80383 +
80384 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80385 + @Param[in] enable - TRUE to enable or FALSE to disable.
80386 +
80387 + @Return E_OK on success; Error code otherwise.
80388 +
80389 + @Cautions Allowed only after FM_MAC_Init().
80390 +*//***************************************************************************/
80391 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
80392 +
80393 +/**************************************************************************//**
80394 + @Function FM_MAC_AdjustLink
80395 +
80396 + @Description Adjusts the Ethernet link with new speed/duplex setup.
80397 + This routine is relevant for dTSEC and mEMAC.
80398 + In case of mEMAC, this routine is also used for manual
80399 + re-configuration of RGMII speed and duplex mode for
80400 + RGMII PHYs not supporting in-band status information
80401 + to MAC.
80402 +
80403 + @Param[in] h_FmMac - A handle to a FM Module.
80404 + @Param[in] speed - Ethernet speed.
80405 + @Param[in] fullDuplex - TRUE for full-duplex mode;
80406 + FALSE for half-duplex mode.
80407 +
80408 + @Return E_OK on success; Error code otherwise.
80409 +*//***************************************************************************/
80410 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
80411 +
80412 +/**************************************************************************//**
80413 + @Function FM_MAC_RestartAutoneg
80414 +
80415 + @Description Restarts the auto-negotiation process.
80416 + When auto-negotiation process is invoked under traffic the
80417 + auto-negotiation process between the internal SGMII PHY and the
80418 + external PHY does not always complete successfully. Calling this
80419 + function will restart the auto-negotiation process that will end
80420 + successfully. It is recommended to call this function after issuing
80421 + auto-negotiation restart command to the Eth Phy.
80422 + This routine is relevant only for dTSEC.
80423 +
80424 + @Param[in] h_FmMac - A handle to a FM Module.
80425 +
80426 + @Return E_OK on success; Error code otherwise.
80427 +*//***************************************************************************/
80428 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
80429 +
80430 +/**************************************************************************//**
80431 + @Function FM_MAC_GetId
80432 +
80433 + @Description Return the MAC ID
80434 +
80435 + @Param[in] h_FmMac - A handle to a FM Module.
80436 + @Param[out] p_MacId - MAC ID of device
80437 +
80438 + @Return E_OK on success; Error code otherwise.
80439 +
80440 + @Cautions Allowed only after FM_MAC_Init().
80441 +*//***************************************************************************/
80442 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
80443 +
80444 +/**************************************************************************//**
80445 + @Function FM_MAC_GetVesrion
80446 +
80447 + @Description Return Mac HW chip version
80448 +
80449 + @Param[in] h_FmMac - A handle to a FM Module.
80450 + @Param[out] p_MacVresion - Mac version as defined by the chip
80451 +
80452 + @Return E_OK on success; Error code otherwise.
80453 +
80454 + @Cautions Allowed only after FM_MAC_Init().
80455 +*//***************************************************************************/
80456 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
80457 +
80458 +/**************************************************************************//**
80459 + @Function FM_MAC_MII_WritePhyReg
80460 +
80461 + @Description Write data into Phy Register
80462 +
80463 + @Param[in] h_FmMac - A handle to a FM Module.
80464 + @Param[in] phyAddr - Phy Address on the MII bus
80465 + @Param[in] reg - Register Number.
80466 + @Param[in] data - Data to write.
80467 +
80468 + @Return E_OK on success; Error code otherwise.
80469 +
80470 + @Cautions Allowed only after FM_MAC_Init().
80471 +*//***************************************************************************/
80472 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
80473 +
80474 +/**************************************************************************//**
80475 + @Function FM_MAC_MII_ReadPhyReg
80476 +
80477 + @Description Read data from Phy Register
80478 +
80479 + @Param[in] h_FmMac - A handle to a FM Module.
80480 + @Param[in] phyAddr - Phy Address on the MII bus
80481 + @Param[in] reg - Register Number.
80482 + @Param[out] p_Data - Data from PHY.
80483 +
80484 + @Return E_OK on success; Error code otherwise.
80485 +
80486 + @Cautions Allowed only after FM_MAC_Init().
80487 +*//***************************************************************************/
80488 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
80489 +
80490 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
80491 +/**************************************************************************//**
80492 + @Function FM_MAC_DumpRegs
80493 +
80494 + @Description Dump internal registers
80495 +
80496 + @Param[in] h_FmMac - A handle to a FM Module.
80497 +
80498 + @Return E_OK on success; Error code otherwise.
80499 +
80500 + @Cautions Allowed only after FM_MAC_Init().
80501 +*//***************************************************************************/
80502 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
80503 +#endif /* (defined(DEBUG_ERRORS) && ... */
80504 +
80505 +/** @} */ /* end of FM_mac_runtime_control_grp group */
80506 +/** @} */ /* end of FM_mac_grp group */
80507 +/** @} */ /* end of FM_grp group */
80508 +
80509 +
80510 +#endif /* __FM_MAC_EXT_H */
80511 --- /dev/null
80512 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
80513 @@ -0,0 +1,1271 @@
80514 +/*
80515 + * Copyright 2008-2015 Freescale Semiconductor Inc.
80516 + *
80517 + * Redistribution and use in source and binary forms, with or without
80518 + * modification, are permitted provided that the following conditions are met:
80519 + * * Redistributions of source code must retain the above copyright
80520 + * notice, this list of conditions and the following disclaimer.
80521 + * * Redistributions in binary form must reproduce the above copyright
80522 + * notice, this list of conditions and the following disclaimer in the
80523 + * documentation and/or other materials provided with the distribution.
80524 + * * Neither the name of Freescale Semiconductor nor the
80525 + * names of its contributors may be used to endorse or promote products
80526 + * derived from this software without specific prior written permission.
80527 + *
80528 + *
80529 + * ALTERNATIVELY, this software may be distributed under the terms of the
80530 + * GNU General Public License ("GPL") as published by the Free Software
80531 + * Foundation, either version 2 of that License or (at your option) any
80532 + * later version.
80533 + *
80534 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80535 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80536 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80537 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80538 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80539 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80540 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80541 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80542 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80543 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80544 + */
80545 +
80546 +/**************************************************************************//**
80547 + @File fm_macsec_ext.h
80548 +
80549 + @Description FM MACSEC ...
80550 +*//***************************************************************************/
80551 +#ifndef __FM_MACSEC_EXT_H
80552 +#define __FM_MACSEC_EXT_H
80553 +
80554 +#include "std_ext.h"
80555 +
80556 +
80557 +/**************************************************************************//**
80558 + @Group FM_grp Frame Manager API
80559 +
80560 + @Description FM API functions, definitions and enums
80561 +
80562 + @{
80563 +*//***************************************************************************/
80564 +
80565 +/**************************************************************************//**
80566 + @Group FM_MACSEC_grp FM MACSEC
80567 +
80568 + @Description FM MACSEC API functions, definitions and enums
80569 +
80570 + @{
80571 +*//***************************************************************************/
80572 +
80573 +/**************************************************************************//**
80574 + @Description MACSEC Exceptions
80575 +*//***************************************************************************/
80576 +typedef enum e_FmMacsecExceptions {
80577 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
80578 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
80579 +} e_FmMacsecExceptions;
80580 +
80581 +
80582 +/**************************************************************************//**
80583 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
80584 +
80585 + @Description FM MACSEC Initialization Unit
80586 +
80587 + @{
80588 +*//***************************************************************************/
80589 +
80590 +/**************************************************************************//**
80591 + @Function t_FmMacsecExceptionsCallback
80592 +
80593 + @Description Exceptions user callback routine, will be called upon an
80594 + exception passing the exception identification.
80595 +
80596 + @Param[in] h_App A handle to an application layer object; This handle
80597 + will be passed by the driver upon calling this callback.
80598 + @Param[in] exception The exception.
80599 +*//***************************************************************************/
80600 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
80601 + e_FmMacsecExceptions exception);
80602 +
80603 +
80604 +/**************************************************************************//**
80605 + @Description FM MACSEC config input
80606 +*//***************************************************************************/
80607 +typedef struct t_FmMacsecParams {
80608 + t_Handle h_Fm; /**< A handle to the FM object related to */
80609 + bool guestMode; /**< Partition-id */
80610 + union {
80611 + struct {
80612 + uint8_t fmMacId; /**< FM MAC id */
80613 + } guestParams;
80614 +
80615 + struct {
80616 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
80617 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
80618 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
80619 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80620 + be passed by the driver upon calling the above callbacks */
80621 + } nonGuestParams;
80622 + };
80623 +} t_FmMacsecParams;
80624 +
80625 +/**************************************************************************//**
80626 + @Function FM_MACSEC_Config
80627 +
80628 + @Description Creates descriptor for the FM MACSEC module;
80629 +
80630 + The routine returns a handle (descriptor) to the FM MACSEC object;
80631 + This descriptor must be passed as first parameter to all other
80632 + FM MACSEC function calls;
80633 +
80634 + No actual initialization or configuration of FM MACSEC hardware is
80635 + done by this routine.
80636 +
80637 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
80638 +
80639 + @Retval Handle to FM MACSEC object, or NULL for Failure.
80640 +*//***************************************************************************/
80641 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
80642 +
80643 +/**************************************************************************//**
80644 + @Function FM_MACSEC_Init
80645 +
80646 + @Description Initializes the FM MACSEC module.
80647 +
80648 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80649 +
80650 + @Return E_OK on success; Error code otherwise.
80651 +*//***************************************************************************/
80652 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
80653 +
80654 +/**************************************************************************//**
80655 + @Function FM_MACSEC_Free
80656 +
80657 + @Description Frees all resources that were assigned to FM MACSEC module;
80658 +
80659 + Calling this routine invalidates the descriptor.
80660 +
80661 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80662 +
80663 + @Return E_OK on success; Error code otherwise.
80664 +*//***************************************************************************/
80665 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
80666 +
80667 +
80668 +/**************************************************************************//**
80669 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
80670 +
80671 + @Description Configuration functions used to change default values.
80672 +
80673 + @{
80674 +*//***************************************************************************/
80675 +
80676 +/**************************************************************************//**
80677 + @Description enum for unknown sci frame treatment
80678 +*//***************************************************************************/
80679 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
80680 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
80681 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
80682 + Controlled port - Check or Disable mode */
80683 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
80684 + 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,
80685 + else discard on uncontrolled port and deliver on controlled port
80686 + Controlled port - Check or Disable mode */
80687 +} e_FmMacsecUnknownSciFrameTreatment;
80688 +
80689 +/**************************************************************************//**
80690 + @Description enum for untag frame treatment
80691 +*//***************************************************************************/
80692 +typedef enum e_FmMacsecUntagFrameTreatment {
80693 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
80694 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
80695 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
80696 +} e_FmMacsecUntagFrameTreatment;
80697 +
80698 +/**************************************************************************//**
80699 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
80700 +
80701 + @Description Change the treatment for received frames with unknown sci from its default
80702 + configuration [DEFAULT_unknownSciFrameTreatment].
80703 +
80704 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80705 + @Param[in] treatMode The selected mode.
80706 +
80707 + @Return E_OK on success; Error code otherwise.
80708 +
80709 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80710 +*//***************************************************************************/
80711 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
80712 +
80713 +/**************************************************************************//**
80714 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
80715 +
80716 + @Description Change the treatment for received frames with invalid tags or
80717 + a zero value PN or an invalid ICV from its default configuration
80718 + [DEFAULT_invalidTagsFrameTreatment].
80719 +
80720 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80721 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
80722 + In both cases discard on the controlled port;
80723 + this provide Strict, Check or Disable mode.
80724 +
80725 + @Return E_OK on success; Error code otherwise.
80726 +
80727 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80728 +*//***************************************************************************/
80729 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
80730 +
80731 +/**************************************************************************//**
80732 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
80733 +
80734 + @Description Change the treatment for received frames with the Encryption bit
80735 + set and the Changed Text bit clear from its default configuration
80736 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
80737 +
80738 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80739 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
80740 + In both cases discard on the controlled port;
80741 + this provide Strict, Check or Disable mode.
80742 +
80743 + @Return E_OK on success; Error code otherwise.
80744 +
80745 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80746 +*//***************************************************************************/
80747 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
80748 +
80749 +/**************************************************************************//**
80750 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
80751 +
80752 + @Description Change the treatment for received frames with the Encryption bit
80753 + clear and the Changed Text bit set from its default configuration
80754 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
80755 +
80756 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80757 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
80758 + In both cases discard on the controlled port;
80759 + this provide Strict, Check or Disable mode.
80760 +
80761 + @Return E_OK on success; Error code otherwise.
80762 +
80763 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80764 +*//***************************************************************************/
80765 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
80766 +
80767 +/**************************************************************************//**
80768 + @Function FM_MACSEC_ConfigUntagFrameTreatment
80769 +
80770 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
80771 + from its default configuration [DEFAULT_untagFrameTreatment].
80772 +
80773 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80774 + @Param[in] treatMode The selected mode.
80775 +
80776 + @Return E_OK on success; Error code otherwise.
80777 +
80778 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80779 +*//***************************************************************************/
80780 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
80781 +
80782 +/**************************************************************************//**
80783 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
80784 +
80785 + @Description Change the treatment for received frames with only SCB bit set
80786 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
80787 +
80788 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80789 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
80790 + In both cases discard on the controlled port;
80791 + this provide Strict, Check or Disable mode.
80792 +
80793 + @Return E_OK on success; Error code otherwise.
80794 +
80795 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80796 +*//***************************************************************************/
80797 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
80798 +
80799 +/**************************************************************************//**
80800 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
80801 +
80802 + @Description It's provide the ability to configure a PN exhaustion threshold;
80803 + When the NextPn crosses this value an interrupt event
80804 + is asserted to warn that the active SA should re-key.
80805 +
80806 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80807 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
80808 + is asserted to re-key.
80809 +
80810 + @Return E_OK on success; Error code otherwise.
80811 +
80812 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80813 +*//***************************************************************************/
80814 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
80815 +
80816 +/**************************************************************************//**
80817 + @Function FM_MACSEC_ConfigKeysUnreadable
80818 +
80819 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
80820 + Can not be cleared unless hard reset.
80821 +
80822 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80823 +
80824 + @Return E_OK on success; Error code otherwise.
80825 +
80826 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80827 +*//***************************************************************************/
80828 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
80829 +
80830 +/**************************************************************************//**
80831 + @Function FM_MACSEC_ConfigSectagWithoutSCI
80832 +
80833 + @Description Promise that all generated Sectag will be without SCI included.
80834 +
80835 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80836 +
80837 + @Return E_OK on success; Error code otherwise.
80838 +
80839 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80840 +*//***************************************************************************/
80841 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
80842 +
80843 +/**************************************************************************//**
80844 + @Function FM_MACSEC_ConfigException
80845 +
80846 + @Description Calling this routine changes the internal driver data base
80847 + from its default selection of exceptions enablement;
80848 + By default all exceptions are enabled.
80849 +
80850 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80851 + @Param[in] exception The exception to be selected.
80852 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80853 +
80854 + @Return E_OK on success; Error code otherwise.
80855 +
80856 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
80857 +*//***************************************************************************/
80858 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
80859 +
80860 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
80861 +/** @} */ /* end of FM_MACSEC_init_grp group */
80862 +
80863 +
80864 +/**************************************************************************//**
80865 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
80866 +
80867 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
80868 +
80869 + @{
80870 +*//***************************************************************************/
80871 +
80872 +/**************************************************************************//**
80873 + @Function FM_MACSEC_GetRevision
80874 +
80875 + @Description Return MACSEC HW chip revision
80876 +
80877 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80878 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
80879 +
80880 + @Return E_OK on success; Error code otherwise.
80881 +
80882 + @Cautions Allowed only after FM_MACSEC_Init().
80883 +*//***************************************************************************/
80884 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
80885 +
80886 +/**************************************************************************//**
80887 + @Function FM_MACSEC_Enable
80888 +
80889 + @Description This routine should be called after MACSEC is initialized for enabling all
80890 + MACSEC engines according to their existing configuration.
80891 +
80892 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80893 +
80894 + @Return E_OK on success; Error code otherwise.
80895 +
80896 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
80897 +*//***************************************************************************/
80898 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
80899 +
80900 +/**************************************************************************//**
80901 + @Function FM_MACSEC_Disable
80902 +
80903 + @Description This routine may be called when MACSEC is enabled in order to
80904 + disable all MACSEC engines; The MACSEC is working in bypass mode.
80905 +
80906 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80907 +
80908 + @Return E_OK on success; Error code otherwise.
80909 +
80910 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
80911 +*//***************************************************************************/
80912 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
80913 +
80914 +/**************************************************************************//**
80915 + @Function FM_MACSEC_SetException
80916 +
80917 + @Description Calling this routine enables/disables the specified exception.
80918 +
80919 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80920 + @Param[in] exception The exception to be selected.
80921 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80922 +
80923 + @Return E_OK on success; Error code otherwise.
80924 +
80925 + @Cautions Allowed only following FM_MACSEC_Init().
80926 +*//***************************************************************************/
80927 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
80928 +
80929 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
80930 +/**************************************************************************//**
80931 + @Function FM_MACSEC_DumpRegs
80932 +
80933 + @Description Dump internal registers.
80934 +
80935 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
80936 +
80937 + @Return E_OK on success; Error code otherwise.
80938 +
80939 + @Cautions Allowed only after FM_MACSEC_Init().
80940 +*//***************************************************************************/
80941 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
80942 +#endif /* (defined(DEBUG_ERRORS) && ... */
80943 +
80944 +#ifdef VERIFICATION_SUPPORT
80945 +/********************* VERIFICATION ONLY ********************************/
80946 +/**************************************************************************//**
80947 + @Function FM_MACSEC_BackdoorSet
80948 +
80949 + @Description Set register of the MACSEC memory map
80950 +
80951 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80952 + @Param[out] offset Register offset.
80953 + @Param[out] value Value to write.
80954 +
80955 +
80956 + @Return None
80957 +
80958 + @Cautions Allowed only following FM_MACSEC_Init().
80959 +*//***************************************************************************/
80960 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
80961 +
80962 +/**************************************************************************//**
80963 + @Function FM_MACSEC_BackdoorGet
80964 +
80965 + @Description Read from register of the MACSEC memory map.
80966 +
80967 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
80968 + @Param[out] offset Register offset.
80969 +
80970 + @Return Value read
80971 +
80972 + @Cautions Allowed only following FM_MACSEC_Init().
80973 +*//***************************************************************************/
80974 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
80975 +#endif /* VERIFICATION_SUPPORT */
80976 +
80977 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
80978 +
80979 +
80980 +/**************************************************************************//**
80981 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
80982 +
80983 + @Description FM-MACSEC SecY API functions, definitions and enums
80984 +
80985 + @{
80986 +*//***************************************************************************/
80987 +
80988 +typedef uint8_t macsecSAKey_t[32];
80989 +typedef uint64_t macsecSCI_t;
80990 +typedef uint8_t macsecAN_t;
80991 +
80992 +/**************************************************************************//**
80993 +@Description MACSEC SECY Cipher Suite
80994 +*//***************************************************************************/
80995 +typedef enum e_FmMacsecSecYCipherSuite {
80996 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
80997 +#if (DPAA_VERSION >= 11)
80998 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
80999 +#endif /* (DPAA_VERSION >= 11) */
81000 +} e_FmMacsecSecYCipherSuite;
81001 +
81002 +/**************************************************************************//**
81003 + @Description MACSEC SECY Exceptions
81004 +*//***************************************************************************/
81005 +typedef enum e_FmMacsecSecYExceptions {
81006 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
81007 +} e_FmMacsecSecYExceptions;
81008 +
81009 +/**************************************************************************//**
81010 + @Description MACSEC SECY Events
81011 +*//***************************************************************************/
81012 +typedef enum e_FmMacsecSecYEvents {
81013 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
81014 +} e_FmMacsecSecYEvents;
81015 +
81016 +/**************************************************************************//**
81017 + @Collection MACSEC SECY Frame Discarded Descriptor error
81018 +*//***************************************************************************/
81019 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
81020 +
81021 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
81022 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
81023 +/* @} */
81024 +
81025 +/**************************************************************************//**
81026 + @Function t_FmMacsecSecYExceptionsCallback
81027 +
81028 + @Description Exceptions user callback routine, will be called upon an
81029 + exception passing the exception identification.
81030 +
81031 + @Param[in] h_App A handle to an application layer object; This handle
81032 + will be passed by the driver upon calling this callback.
81033 + @Param[in] exception The exception.
81034 +*//***************************************************************************/
81035 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
81036 + e_FmMacsecSecYExceptions exception);
81037 +
81038 +/**************************************************************************//**
81039 + @Function t_FmMacsecSecYEventsCallback
81040 +
81041 + @Description Events user callback routine, will be called upon an
81042 + event passing the event identification.
81043 +
81044 + @Param[in] h_App A handle to an application layer object; This handle
81045 + will be passed by the driver upon calling this callback.
81046 + @Param[in] event The event.
81047 +*//***************************************************************************/
81048 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
81049 + e_FmMacsecSecYEvents event);
81050 +
81051 +/**************************************************************************//**
81052 + @Description RFC2863 MIB
81053 +*//***************************************************************************/
81054 +typedef struct t_MIBStatistics {
81055 + uint64_t ifInOctets; /**< Total number of byte received */
81056 + uint64_t ifInPkts; /**< Total number of packets received */
81057 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
81058 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
81059 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
81060 + - InPktsNoTag,
81061 + - InPktsLate,
81062 + - InPktsOverrun */
81063 + uint64_t ifInErrors; /**< Number of frames received with error:
81064 + - InPktsBadTag,
81065 + - InPktsNoSCI,
81066 + - InPktsNotUsingSA
81067 + - InPktsNotValid */
81068 + uint64_t ifOutOctets; /**< Total number of byte sent */
81069 + uint64_t ifOutPkts; /**< Total number of packets sent */
81070 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
81071 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
81072 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
81073 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
81074 + - FIFO Overflow Error
81075 + - FIFO Underflow Error
81076 + - Other */
81077 +} t_MIBStatistics;
81078 +
81079 +/**************************************************************************//**
81080 + @Description MACSEC SecY Rx SA Statistics
81081 +*//***************************************************************************/
81082 +typedef struct t_FmMacsecSecYRxSaStatistics {
81083 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
81084 + frame validation frame validation with the validateFrame not set to disable */
81085 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
81086 + validation with the validateFrame set to check */
81087 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
81088 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
81089 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
81090 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
81091 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
81092 + with validateFrame not in the strict mode and the C bit is cleared */
81093 +} t_FmMacsecSecYRxSaStatistics;
81094 +
81095 +/**************************************************************************//**
81096 + @Description MACSEC SecY Tx SA Statistics
81097 +*//***************************************************************************/
81098 +typedef struct t_FmMacsecSecYTxSaStatistics {
81099 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
81100 + be transmitted, which were integrity protected */
81101 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
81102 + be transmitted, which were confidentiality protected */
81103 +} t_FmMacsecSecYTxSaStatistics;
81104 +
81105 +/**************************************************************************//**
81106 + @Description MACSEC SecY Rx SC Statistics
81107 +*//***************************************************************************/
81108 +typedef struct t_FmMacsecSecYRxScStatistics {
81109 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
81110 + that are not validated with the validateFrame set to disable */
81111 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
81112 + that have their PN smaller than the lowest_PN with the validateFrame set to
81113 + disable or replayProtect disabled */
81114 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
81115 + that have their PN smaller than the lowest_PN with the validateFrame set to
81116 + Check or Strict and replayProtect enabled */
81117 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
81118 + frame validation frame validation with the validateFrame not set to disable */
81119 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
81120 + validation with the validateFrame set to check */
81121 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
81122 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
81123 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
81124 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
81125 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
81126 + with validateFrame not in the strict mode and the C bit is cleared */
81127 +} t_FmMacsecSecYRxScStatistics;
81128 +
81129 +/**************************************************************************//**
81130 + @Description MACSEC SecY Tx SC Statistics
81131 +*//***************************************************************************/
81132 +typedef struct t_FmMacsecSecYTxScStatistics {
81133 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
81134 + be transmitted, which were integrity protected */
81135 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
81136 + be transmitted, which were confidentiality protected */
81137 +} t_FmMacsecSecYTxScStatistics;
81138 +
81139 +/**************************************************************************//**
81140 + @Description MACSEC SecY Statistics
81141 +*//***************************************************************************/
81142 +typedef struct t_FmMacsecSecYStatistics {
81143 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
81144 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
81145 +/* Frame verification statistics */
81146 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
81147 + (SecTAG) with validateFrames which is not in the strict mode */
81148 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
81149 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
81150 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
81151 + SecTAG or a zero value PN or an invalid ICV */
81152 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
81153 + condition : validateFrames is not in the strict mode and the
81154 + C bit in the SecTAG is not set */
81155 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
81156 + information with the condition : validateFrames is in the strict mode
81157 + or the C bit in the SecTAG is set */
81158 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
81159 + received packets exceeded the cryptographic performance capabilities */
81160 +/* Frame validation statistics */
81161 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
81162 + resolved SCI that were integrity protected but not encrypted */
81163 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
81164 + resolved SCI that were integrity protected and encrypted */
81165 +/* Frame generation statistics */
81166 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
81167 + be transmitted, with protectFrame false */
81168 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
81169 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
81170 +/* Frame protection statistics */
81171 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
81172 + integrity protected but not encrypted */
81173 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
81174 + both integrity protected and encrypted */
81175 +} t_FmMacsecSecYStatistics;
81176 +
81177 +
81178 +/**************************************************************************//**
81179 + @Description MACSEC SecY SC Params
81180 +*//***************************************************************************/
81181 +typedef struct t_FmMacsecSecYSCParams {
81182 + macsecSCI_t sci; /**< The secure channel identification of the SC */
81183 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
81184 +} t_FmMacsecSecYSCParams;
81185 +
81186 +/**************************************************************************//**
81187 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
81188 +
81189 + @Description FM-MACSEC SecY Initialization Unit
81190 +
81191 + @{
81192 +*//***************************************************************************/
81193 +
81194 +/**************************************************************************//**
81195 + @Description enum for validate frames
81196 +*//***************************************************************************/
81197 +typedef enum e_FmMacsecValidFrameBehavior {
81198 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
81199 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
81200 + without filtering out invalid frames */
81201 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
81202 + out those invalid frames */
81203 +} e_FmMacsecValidFrameBehavior;
81204 +
81205 +/**************************************************************************//**
81206 + @Description enum for sci insertion
81207 +*//***************************************************************************/
81208 +typedef enum e_FmMacsecSciInsertionMode {
81209 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
81210 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
81211 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
81212 +} e_FmMacsecSciInsertionMode;
81213 +
81214 +/**************************************************************************//**
81215 + @Description FM MACSEC SecY config input
81216 +*//***************************************************************************/
81217 +typedef struct t_FmMacsecSecYParams {
81218 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
81219 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
81220 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
81221 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
81222 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
81223 + t_Handle h_App; /**< A handle to an application layer object; This handle will
81224 + be passed by the driver upon calling the above callbacks */
81225 +} t_FmMacsecSecYParams;
81226 +
81227 +/**************************************************************************//**
81228 + @Function FM_MACSEC_SECY_Config
81229 +
81230 + @Description Creates descriptor for the FM MACSEC SECY module;
81231 +
81232 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
81233 + This descriptor must be passed as first parameter to all other
81234 + FM MACSEC SECY function calls;
81235 + No actual initialization or configuration of FM MACSEC SecY hardware is
81236 + done by this routine.
81237 +
81238 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
81239 +
81240 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
81241 +*//***************************************************************************/
81242 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
81243 +
81244 +/**************************************************************************//**
81245 + @Function FM_MACSEC_SECY_Init
81246 +
81247 + @Description Initializes the FM MACSEC SECY module.
81248 +
81249 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81250 +
81251 + @Return E_OK on success; Error code otherwise.
81252 +*//***************************************************************************/
81253 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
81254 +
81255 +/**************************************************************************//**
81256 + @Function FM_MACSEC_SECY_Free
81257 +
81258 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
81259 +
81260 + Calling this routine invalidates the descriptor.
81261 +
81262 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81263 +
81264 + @Return E_OK on success; Error code otherwise.
81265 +*//***************************************************************************/
81266 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
81267 +
81268 +/**************************************************************************//**
81269 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
81270 +
81271 + @Description Configuration functions used to change default values.
81272 +
81273 + @{
81274 +*//***************************************************************************/
81275 +
81276 +/**************************************************************************//**
81277 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
81278 +
81279 + @Description Calling this routine changes the SCI-insertion-mode in the
81280 + internal driver data base from its default configuration
81281 + [DEFAULT_sciInsertionMode]
81282 +
81283 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81284 + @Param[in] sciInsertionMode Sci insertion mode
81285 +
81286 + @Return E_OK on success; Error code otherwise.
81287 +
81288 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81289 +
81290 +*//***************************************************************************/
81291 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
81292 +
81293 +/**************************************************************************//**
81294 + @Function FM_MACSEC_SECY_ConfigProtectFrames
81295 +
81296 + @Description Calling this routine changes the protect-frame mode in the
81297 + internal driver data base from its default configuration
81298 + [DEFAULT_protectFrames]
81299 +
81300 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81301 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
81302 +
81303 + @Return E_OK on success; Error code otherwise.
81304 +
81305 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81306 +
81307 +*//***************************************************************************/
81308 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
81309 +
81310 +/**************************************************************************//**
81311 + @Function FM_MACSEC_SECY_ConfigReplayWindow
81312 +
81313 + @Description Calling this routine changes the replay-window settings in the
81314 + internal driver data base from its default configuration
81315 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
81316 +
81317 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81318 + @Param[in] replayProtect; Replay protection function mode
81319 + @Param[in] replayWindow; The size of the replay window
81320 +
81321 + @Return E_OK on success; Error code otherwise.
81322 +
81323 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81324 +
81325 +*//***************************************************************************/
81326 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
81327 +
81328 +/**************************************************************************//**
81329 + @Function FM_MACSEC_SECY_ConfigValidationMode
81330 +
81331 + @Description Calling this routine changes the frame-validation-behavior mode
81332 + in the internal driver data base from its default configuration
81333 + [DEFAULT_validateFrames]
81334 +
81335 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81336 + @Param[in] validateFrames Validation function mode
81337 +
81338 + @Return E_OK on success; Error code otherwise.
81339 +
81340 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81341 +
81342 +*//***************************************************************************/
81343 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
81344 +
81345 +/**************************************************************************//**
81346 + @Function FM_MACSEC_SECY_ConfigConfidentiality
81347 +
81348 + @Description Calling this routine changes the confidentiality settings in the
81349 + internal driver data base from its default configuration
81350 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
81351 +
81352 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81353 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
81354 + FALSE - no confidentiality protection, only integrity protection
81355 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
81356 + common values are 0, 30, and 50
81357 +
81358 + @Return E_OK on success; Error code otherwise.
81359 +
81360 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81361 +
81362 +*//***************************************************************************/
81363 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
81364 +
81365 +/**************************************************************************//**
81366 + @Function FM_MACSEC_SECY_ConfigPointToPoint
81367 +
81368 + @Description configure this SecY to work in point-to-point mode, means that
81369 + it will have only one rx sc;
81370 +
81371 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81372 +
81373 + @Return E_OK on success; Error code otherwise.
81374 +
81375 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81376 + Can be called only once in a system; only the first secY that will call this
81377 + routine will be able to operate in Point-To-Point mode.
81378 +*//***************************************************************************/
81379 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
81380 +
81381 +/**************************************************************************//**
81382 + @Function FM_MACSEC_SECY_ConfigException
81383 +
81384 + @Description Calling this routine changes the internal driver data base
81385 + from its default selection of exceptions enablement;
81386 + By default all exceptions are enabled.
81387 +
81388 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81389 + @Param[in] exception The exception to be selected.
81390 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81391 +
81392 + @Return E_OK on success; Error code otherwise.
81393 +
81394 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
81395 +*//***************************************************************************/
81396 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
81397 +
81398 +/**************************************************************************//**
81399 + @Function FM_MACSEC_SECY_ConfigEvent
81400 +
81401 + @Description Calling this routine changes the internal driver data base
81402 + from its default selection of events enablement;
81403 + By default all events are enabled.
81404 +
81405 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81406 + @Param[in] event The event to be selected.
81407 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81408 +
81409 + @Return E_OK on success; Error code otherwise.
81410 +
81411 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
81412 +*//***************************************************************************/
81413 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
81414 +
81415 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
81416 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
81417 +
81418 +
81419 +/**************************************************************************//**
81420 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
81421 +
81422 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
81423 +
81424 + @{
81425 +*//***************************************************************************/
81426 +
81427 +/**************************************************************************//**
81428 + @Function FM_MACSEC_SECY_CreateRxSc
81429 +
81430 + @Description Create a receive secure channel.
81431 +
81432 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81433 + @Param[in] scParams secure channel params.
81434 +
81435 + @Return E_OK on success; Error code otherwise.
81436 +
81437 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81438 +*//***************************************************************************/
81439 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
81440 +
81441 +/**************************************************************************//**
81442 + @Function FM_MACSEC_SECY_DeleteRxSc
81443 +
81444 + @Description Deleting an initialized secure channel.
81445 +
81446 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81447 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81448 +
81449 + @Return E_OK on success; Error code otherwise.
81450 +
81451 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
81452 +*//***************************************************************************/
81453 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
81454 +
81455 +/**************************************************************************//**
81456 + @Function FM_MACSEC_SECY_CreateRxSa
81457 +
81458 + @Description Create a receive secure association for the secure channel;
81459 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
81460 +
81461 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81462 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81463 + @Param[in] an association number represent the SA.
81464 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
81465 + @Param[in] key the desired key for this SA.
81466 +
81467 + @Return E_OK on success; Error code otherwise.
81468 +
81469 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
81470 +*//***************************************************************************/
81471 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
81472 +
81473 +/**************************************************************************//**
81474 + @Function FM_MACSEC_SECY_DeleteRxSa
81475 +
81476 + @Description Deleting an initialized secure association.
81477 +
81478 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81479 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81480 + @Param[in] an association number represent the SA.
81481 +
81482 + @Return E_OK on success; Error code otherwise.
81483 +
81484 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81485 +*//***************************************************************************/
81486 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
81487 +
81488 +/**************************************************************************//**
81489 + @Function FM_MACSEC_SECY_RxSaEnableReceive
81490 +
81491 + @Description Enabling the SA to receive frames.
81492 +
81493 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81494 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81495 + @Param[in] an association number represent the SA.
81496 +
81497 + @Return E_OK on success; Error code otherwise.
81498 +
81499 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81500 +*//***************************************************************************/
81501 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
81502 +
81503 +/**************************************************************************//**
81504 + @Function FM_MACSEC_SECY_RxSaDisableReceive
81505 +
81506 + @Description Disabling the SA from receive frames.
81507 +
81508 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81509 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81510 + @Param[in] an association number represent the SA.
81511 +
81512 + @Return E_OK on success; Error code otherwise.
81513 +
81514 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81515 +*//***************************************************************************/
81516 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
81517 +
81518 +/**************************************************************************//**
81519 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
81520 +
81521 + @Description Update the next packet number expected on RX;
81522 + The value of nextPN shall be set to the greater of its existing value and the
81523 + supplied of updtNextPN (802.1AE-2006 10.7.15).
81524 +
81525 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81526 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81527 + @Param[in] an association number represent the SA.
81528 + @Param[in] updtNextPN the next PN value for a received frame.
81529 +
81530 + @Return E_OK on success; Error code otherwise.
81531 +
81532 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81533 +*//***************************************************************************/
81534 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
81535 +
81536 +/**************************************************************************//**
81537 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
81538 +
81539 + @Description Update the lowest packet number expected on RX;
81540 + The value of lowestPN shall be set to the greater of its existing value and the
81541 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
81542 +
81543 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81544 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81545 + @Param[in] an association number represent the SA.
81546 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
81547 +
81548 + @Return E_OK on success; Error code otherwise.
81549 +
81550 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81551 +*//***************************************************************************/
81552 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
81553 +
81554 +/**************************************************************************//**
81555 + @Function FM_MACSEC_SECY_RxSaModifyKey
81556 +
81557 + @Description Modify the current key of the SA with a new one.
81558 +
81559 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81560 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81561 + @Param[in] an association number represent the SA.
81562 + @Param[in] key new key to replace the current key.
81563 +
81564 + @Return E_OK on success; Error code otherwise.
81565 +
81566 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81567 +*//***************************************************************************/
81568 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
81569 +
81570 +/**************************************************************************//**
81571 + @Function FM_MACSEC_SECY_CreateTxSa
81572 +
81573 + @Description Create a transmit secure association for the secure channel;
81574 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
81575 + Only one SA can be active at a time.
81576 +
81577 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81578 + @Param[in] an association number represent the SA.
81579 + @Param[in] key the desired key for this SA.
81580 +
81581 + @Return E_OK on success; Error code otherwise.
81582 +
81583 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81584 +*//***************************************************************************/
81585 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
81586 +
81587 +/**************************************************************************//**
81588 + @Function FM_MACSEC_SECY_DeleteTxSa
81589 +
81590 + @Description Deleting an initialized secure association.
81591 +
81592 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81593 + @Param[in] an association number represent the SA.
81594 +
81595 + @Return E_OK on success; Error code otherwise.
81596 +
81597 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81598 +*//***************************************************************************/
81599 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
81600 +
81601 +/**************************************************************************//**
81602 + @Function FM_MACSEC_SECY_TxSaModifyKey
81603 +
81604 + @Description Modify the key of the inactive SA with a new one.
81605 +
81606 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81607 + @Param[in] nextActiveAn association number represent the next SA to be activated.
81608 + @Param[in] key new key to replace the current key.
81609 +
81610 + @Return E_OK on success; Error code otherwise.
81611 +
81612 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81613 +*//***************************************************************************/
81614 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
81615 +
81616 +/**************************************************************************//**
81617 + @Function FM_MACSEC_SECY_TxSaSetActive
81618 +
81619 + @Description Set this SA to the active SA to be used on TX for SC;
81620 + only one SA can be active at a time.
81621 +
81622 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81623 + @Param[in] an association number represent the SA.
81624 +
81625 + @Return E_OK on success; Error code otherwise.
81626 +
81627 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81628 +*//***************************************************************************/
81629 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
81630 +
81631 +/**************************************************************************//**
81632 + @Function FM_MACSEC_SECY_TxSaGetActive
81633 +
81634 + @Description Get the active SA that being used for TX.
81635 +
81636 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81637 + @Param[out] p_An the active an.
81638 +
81639 + @Return E_OK on success; Error code otherwise.
81640 +
81641 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81642 +*//***************************************************************************/
81643 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
81644 +
81645 +/**************************************************************************//**
81646 + @Function FM_MACSEC_SECY_GetStatistics
81647 +
81648 + @Description get all statistics counters.
81649 +
81650 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81651 + @Param[in] p_Statistics Structure with statistics.
81652 +
81653 + @Return E_OK on success; Error code otherwise.
81654 +
81655 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81656 +*//***************************************************************************/
81657 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
81658 +
81659 +/**************************************************************************//**
81660 + @Function FM_MACSEC_SECY_RxScGetStatistics
81661 +
81662 + @Description get all statistics counters.
81663 +
81664 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81665 + @Param[in] h_Sc Rx Sc handle.
81666 + @Param[in] p_Statistics Structure with statistics.
81667 +
81668 + @Return E_OK on success; Error code otherwise.
81669 +
81670 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81671 +*//***************************************************************************/
81672 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
81673 +
81674 +/**************************************************************************//**
81675 + @Function FM_MACSEC_SECY_RxSaGetStatistics
81676 +
81677 + @Description get all statistics counters
81678 +
81679 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81680 + @Param[in] h_Sc Rx Sc handle.
81681 + @Param[in] an association number represent the SA.
81682 + @Param[in] p_Statistics Structure with statistics.
81683 +
81684 + @Return E_OK on success; Error code otherwise.
81685 +
81686 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81687 +*//***************************************************************************/
81688 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
81689 +
81690 +/**************************************************************************//**
81691 + @Function FM_MACSEC_SECY_TxScGetStatistics
81692 +
81693 + @Description get all statistics counters.
81694 +
81695 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81696 + @Param[in] p_Statistics Structure with statistics.
81697 +
81698 + @Return E_OK on success; Error code otherwise.
81699 +
81700 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81701 +*//***************************************************************************/
81702 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
81703 +
81704 +/**************************************************************************//**
81705 + @Function FM_MACSEC_SECY_TxSaGetStatistics
81706 +
81707 + @Description get all statistics counters.
81708 +
81709 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81710 + @Param[in] an association number represent the SA.
81711 + @Param[in] p_Statistics Structure with statistics.
81712 +
81713 + @Return E_OK on success; Error code otherwise.
81714 +
81715 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81716 +*//***************************************************************************/
81717 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
81718 +
81719 +/**************************************************************************//**
81720 + @Function FM_MACSEC_SECY_SetException
81721 +
81722 + @Description Calling this routine enables/disables the specified exception.
81723 +
81724 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81725 + @Param[in] exception The exception to be selected.
81726 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81727 +
81728 + @Return E_OK on success; Error code otherwise.
81729 +
81730 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81731 +*//***************************************************************************/
81732 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
81733 +
81734 +/**************************************************************************//**
81735 + @Function FM_MACSEC_SECY_SetEvent
81736 +
81737 + @Description Calling this routine enables/disables the specified event.
81738 +
81739 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81740 + @Param[in] event The event to be selected.
81741 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81742 +
81743 + @Return E_OK on success; Error code otherwise.
81744 +
81745 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
81746 +*//***************************************************************************/
81747 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
81748 +
81749 +/**************************************************************************//**
81750 + @Function FM_MACSEC_SECY_GetRxScPhysId
81751 +
81752 + @Description return the physical id of the Secure Channel.
81753 +
81754 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81755 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81756 + @Param[out] p_ScPhysId the SC physical id.
81757 +
81758 + @Return E_OK on success; Error code otherwise.
81759 +
81760 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
81761 +*//***************************************************************************/
81762 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
81763 +
81764 +/**************************************************************************//**
81765 + @Function FM_MACSEC_SECY_GetTxScPhysId
81766 +
81767 + @Description return the physical id of the Secure Channel.
81768 +
81769 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81770 + @Param[out] p_ScPhysId the SC physical id.
81771 +
81772 + @Return E_OK on success; Error code otherwise.
81773 +
81774 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81775 +*//***************************************************************************/
81776 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
81777 +
81778 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
81779 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
81780 +/** @} */ /* end of FM_MACSEC_grp group */
81781 +/** @} */ /* end of FM_grp group */
81782 +
81783 +
81784 +#endif /* __FM_MACSEC_EXT_H */
81785 --- /dev/null
81786 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
81787 @@ -0,0 +1,170 @@
81788 +/*
81789 + * Copyright 2008-2012 Freescale Semiconductor Inc.
81790 + *
81791 + * Redistribution and use in source and binary forms, with or without
81792 + * modification, are permitted provided that the following conditions are met:
81793 + * * Redistributions of source code must retain the above copyright
81794 + * notice, this list of conditions and the following disclaimer.
81795 + * * Redistributions in binary form must reproduce the above copyright
81796 + * notice, this list of conditions and the following disclaimer in the
81797 + * documentation and/or other materials provided with the distribution.
81798 + * * Neither the name of Freescale Semiconductor nor the
81799 + * names of its contributors may be used to endorse or promote products
81800 + * derived from this software without specific prior written permission.
81801 + *
81802 + *
81803 + * ALTERNATIVELY, this software may be distributed under the terms of the
81804 + * GNU General Public License ("GPL") as published by the Free Software
81805 + * Foundation, either version 2 of that License or (at your option) any
81806 + * later version.
81807 + *
81808 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
81809 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
81810 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
81811 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
81812 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
81813 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
81814 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
81815 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
81816 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
81817 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
81818 + */
81819 +
81820 +
81821 +/**************************************************************************//**
81822 + @File fm_muram_ext.h
81823 +
81824 + @Description FM MURAM Application Programming Interface.
81825 +*//***************************************************************************/
81826 +#ifndef __FM_MURAM_EXT
81827 +#define __FM_MURAM_EXT
81828 +
81829 +#include "error_ext.h"
81830 +#include "std_ext.h"
81831 +
81832 +
81833 +/**************************************************************************//**
81834 +
81835 + @Group FM_grp Frame Manager API
81836 +
81837 + @Description FM API functions, definitions and enums
81838 +
81839 + @{
81840 +*//***************************************************************************/
81841 +
81842 +/**************************************************************************//**
81843 + @Group FM_muram_grp FM MURAM
81844 +
81845 + @Description FM MURAM API functions, definitions and enums
81846 +
81847 + @{
81848 +*//***************************************************************************/
81849 +
81850 +/**************************************************************************//**
81851 + @Group FM_muram_init_grp FM MURAM Initialization Unit
81852 +
81853 + @Description FM MURAM initialization API functions, definitions and enums
81854 +
81855 + @{
81856 +*//***************************************************************************/
81857 +
81858 +/**************************************************************************//**
81859 + @Function FM_MURAM_ConfigAndInit
81860 +
81861 + @Description Creates partition in the MURAM.
81862 +
81863 + The routine returns a handle (descriptor) to the MURAM partition.
81864 + This descriptor must be passed as first parameter to all other
81865 + FM-MURAM function calls.
81866 +
81867 + No actual initialization or configuration of FM_MURAM hardware is
81868 + done by this routine.
81869 +
81870 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
81871 + @Param[in] size - Size of the FM-MURAM partition.
81872 +
81873 + @Return Handle to FM-MURAM object, or NULL for Failure.
81874 +*//***************************************************************************/
81875 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
81876 +
81877 +/**************************************************************************//**
81878 + @Function FM_MURAM_Free
81879 +
81880 + @Description Frees all resources that were assigned to FM-MURAM module.
81881 +
81882 + Calling this routine invalidates the descriptor.
81883 +
81884 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
81885 +
81886 + @Return E_OK on success; Error code otherwise.
81887 +*//***************************************************************************/
81888 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
81889 +
81890 +/** @} */ /* end of FM_muram_init_grp group */
81891 +
81892 +
81893 +/**************************************************************************//**
81894 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
81895 +
81896 + @Description FM MURAM control API functions, definitions and enums
81897 +
81898 + @{
81899 +*//***************************************************************************/
81900 +
81901 +/**************************************************************************//**
81902 + @Function FM_MURAM_AllocMem
81903 +
81904 + @Description Allocate some memory from FM-MURAM partition.
81905 +
81906 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
81907 + @Param[in] size - size of the memory to be allocated.
81908 + @Param[in] align - Alignment of the memory.
81909 +
81910 + @Return address of the allocated memory; NULL otherwise.
81911 +*//***************************************************************************/
81912 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
81913 +
81914 +/**************************************************************************//**
81915 + @Function FM_MURAM_AllocMemForce
81916 +
81917 + @Description Allocate some specific memory from FM-MURAM partition (according
81918 + to base).
81919 +
81920 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
81921 + @Param[in] base - the desired base-address to be allocated.
81922 + @Param[in] size - size of the memory to be allocated.
81923 +
81924 + @Return address of the allocated memory; NULL otherwise.
81925 +*//***************************************************************************/
81926 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
81927 +
81928 +/**************************************************************************//**
81929 + @Function FM_MURAM_FreeMem
81930 +
81931 + @Description Free an allocated memory from FM-MURAM partition.
81932 +
81933 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
81934 + @Param[in] ptr - A pointer to an allocated memory.
81935 +
81936 + @Return E_OK on success; Error code otherwise.
81937 +*//***************************************************************************/
81938 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
81939 +
81940 +/**************************************************************************//**
81941 + @Function FM_MURAM_GetFreeMemSize
81942 +
81943 + @Description Returns the size (in bytes) of free MURAM memory.
81944 +
81945 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
81946 +
81947 + @Return Free MURAM memory size in bytes.
81948 +*//***************************************************************************/
81949 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
81950 +
81951 +/** @} */ /* end of FM_muram_ctrl_grp group */
81952 +/** @} */ /* end of FM_muram_grp group */
81953 +/** @} */ /* end of FM_grp group */
81954 +
81955 +
81956 +
81957 +#endif /* __FM_MURAM_EXT */
81958 --- /dev/null
81959 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
81960 @@ -0,0 +1,3974 @@
81961 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
81962 + * All rights reserved.
81963 + *
81964 + * Redistribution and use in source and binary forms, with or without
81965 + * modification, are permitted provided that the following conditions are met:
81966 + * * Redistributions of source code must retain the above copyright
81967 + * notice, this list of conditions and the following disclaimer.
81968 + * * Redistributions in binary form must reproduce the above copyright
81969 + * notice, this list of conditions and the following disclaimer in the
81970 + * documentation and/or other materials provided with the distribution.
81971 + * * Neither the name of Freescale Semiconductor nor the
81972 + * names of its contributors may be used to endorse or promote products
81973 + * derived from this software without specific prior written permission.
81974 + *
81975 + *
81976 + * ALTERNATIVELY, this software may be distributed under the terms of the
81977 + * GNU General Public License ("GPL") as published by the Free Software
81978 + * Foundation, either version 2 of that License or (at your option) any
81979 + * later version.
81980 + *
81981 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
81982 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
81983 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
81984 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
81985 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
81986 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
81987 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
81988 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
81989 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
81990 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
81991 + */
81992 +
81993 +
81994 +/**************************************************************************//**
81995 + @File fm_pcd_ext.h
81996 +
81997 + @Description FM PCD API definitions
81998 +*//***************************************************************************/
81999 +#ifndef __FM_PCD_EXT
82000 +#define __FM_PCD_EXT
82001 +
82002 +#include "std_ext.h"
82003 +#include "net_ext.h"
82004 +#include "list_ext.h"
82005 +#include "fm_ext.h"
82006 +#include "fsl_fman_kg.h"
82007 +
82008 +
82009 +/**************************************************************************//**
82010 + @Group FM_grp Frame Manager API
82011 +
82012 + @Description Frame Manager Application Programming Interface
82013 +
82014 + @{
82015 +*//***************************************************************************/
82016 +
82017 +/**************************************************************************//**
82018 + @Group FM_PCD_grp FM PCD
82019 +
82020 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
82021 +
82022 + The FM PCD module is responsible for the initialization of all
82023 + global classifying FM modules. This includes the parser general and
82024 + common registers, the key generator global and common registers,
82025 + and the policer global and common registers.
82026 + In addition, the FM PCD SW module will initialize all required
82027 + key generator schemes, coarse classification flows, and policer
82028 + profiles. When FM module is configured to work with one of these
82029 + entities, it will register to it using the FM PORT API. The PCD
82030 + module will manage the PCD resources - i.e. resource management of
82031 + KeyGen schemes, etc.
82032 +
82033 + @{
82034 +*//***************************************************************************/
82035 +
82036 +/**************************************************************************//**
82037 + @Collection General PCD defines
82038 +*//***************************************************************************/
82039 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
82040 +
82041 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
82042 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
82043 + /**< Number of distinction units is limited by
82044 + register size (32 bits) minus reserved bits
82045 + for private headers. */
82046 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
82047 + in a distinction unit */
82048 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
82049 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
82050 + For HW implementation reasons, in most
82051 + cases less than this will be allowed; The
82052 + driver will return an initialization error
82053 + if resource is unavailable. */
82054 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
82055 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
82056 +
82057 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
82058 +#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)
82059 + /**< Maximum size of SW parser code */
82060 +
82061 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
82062 + insert manipulation */
82063 +
82064 +#if (DPAA_VERSION >= 11)
82065 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
82066 +#endif /* (DPAA_VERSION >= 11) */
82067 +/* @} */
82068 +
82069 +
82070 +/**************************************************************************//**
82071 + @Group FM_PCD_init_grp FM PCD Initialization Unit
82072 +
82073 + @Description Frame Manager PCD Initialization Unit API
82074 +
82075 + @{
82076 +*//***************************************************************************/
82077 +
82078 +/**************************************************************************//**
82079 + @Description PCD counters
82080 +*//***************************************************************************/
82081 +typedef enum e_FmPcdCounters {
82082 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
82083 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
82084 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
82085 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
82086 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
82087 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
82088 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
82089 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
82090 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
82091 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
82092 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
82093 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
82094 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
82095 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
82096 + 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. */
82097 + 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. */
82098 + 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. */
82099 + 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. */
82100 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
82101 + 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. */
82102 + 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). */
82103 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
82104 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
82105 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
82106 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
82107 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
82108 +} e_FmPcdCounters;
82109 +
82110 +/**************************************************************************//**
82111 + @Description PCD interrupts
82112 +*//***************************************************************************/
82113 +typedef enum e_FmPcdExceptions {
82114 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
82115 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
82116 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
82117 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
82118 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
82119 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
82120 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
82121 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
82122 +} e_FmPcdExceptions;
82123 +
82124 +
82125 +/**************************************************************************//**
82126 + @Description Exceptions user callback routine, will be called upon an
82127 + exception passing the exception identification.
82128 +
82129 + @Param[in] h_App - User's application descriptor.
82130 + @Param[in] exception - The exception.
82131 + *//***************************************************************************/
82132 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
82133 +
82134 +/**************************************************************************//**
82135 + @Description Exceptions user callback routine, will be called upon an exception
82136 + passing the exception identification.
82137 +
82138 + @Param[in] h_App - User's application descriptor.
82139 + @Param[in] exception - The exception.
82140 + @Param[in] index - id of the relevant source (may be scheme or profile id).
82141 + *//***************************************************************************/
82142 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
82143 + e_FmPcdExceptions exception,
82144 + uint16_t index);
82145 +
82146 +/**************************************************************************//**
82147 + @Description A callback for enqueuing frame onto a QM queue.
82148 +
82149 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
82150 + @Param[in] p_Fd - Frame descriptor for the frame.
82151 +
82152 + @Return E_OK on success; Error code otherwise.
82153 + *//***************************************************************************/
82154 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
82155 +
82156 +/**************************************************************************//**
82157 + @Description Host-Command parameters structure.
82158 +
82159 + When using Host command for PCD functionalities, a dedicated port
82160 + must be used. If this routine is called for a PCD in a single partition
82161 + environment, or it is the Master partition in a Multi-partition
82162 + environment, The port will be initialized by the PCD driver
82163 + initialization routine.
82164 + *//***************************************************************************/
82165 +typedef struct t_FmPcdHcParams {
82166 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
82167 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
82168 + NOTE: When configuring Host Command port for
82169 + FMANv3 devices (DPAA_VERSION 11 and higher),
82170 + portId=0 MUST be used. */
82171 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
82172 + (irrelevant for P4080 revision 1.0) */
82173 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
82174 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
82175 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
82176 + will be used by the FM for dequeue. */
82177 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
82178 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
82179 +} t_FmPcdHcParams;
82180 +
82181 +/**************************************************************************//**
82182 + @Description The main structure for PCD initialization
82183 + *//***************************************************************************/
82184 +typedef struct t_FmPcdParams {
82185 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
82186 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
82187 + of the FM ports. */
82188 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
82189 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
82190 + t_Handle h_Fm; /**< A handle to the FM module. */
82191 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
82192 + this parameter is relevant if 'kgSupport'=TRUE. */
82193 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
82194 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
82195 + Relevant when FM not runs in "guest-mode". */
82196 +
82197 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
82198 + Relevant when FM not runs in "guest-mode". */
82199 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
82200 + Policer profile exceptions;
82201 + Relevant when FM not runs in "guest-mode". */
82202 + t_Handle h_App; /**< A handle to an application layer object; This handle will
82203 + be passed by the driver upon calling the above callbacks;
82204 + Relevant when FM not runs in "guest-mode". */
82205 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
82206 + this parameter is relevant if 'plcrSupport'=TRUE.
82207 + NOTE: this parameter relevant only when working with multiple partitions. */
82208 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
82209 + this parameter is relevant if 'plcrSupport'=TRUE.
82210 + NOTE: this parameter relevant only when working with multiple partitions. */
82211 +} t_FmPcdParams;
82212 +
82213 +
82214 +/**************************************************************************//**
82215 + @Function FM_PCD_Config
82216 +
82217 + @Description Basic configuration of the PCD module.
82218 + Creates descriptor for the FM PCD module.
82219 +
82220 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
82221 +
82222 + @Return A handle to the initialized module.
82223 +*//***************************************************************************/
82224 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
82225 +
82226 +/**************************************************************************//**
82227 + @Function FM_PCD_Init
82228 +
82229 + @Description Initialization of the PCD module.
82230 +
82231 + @Param[in] h_FmPcd - FM PCD module descriptor.
82232 +
82233 + @Return E_OK on success; Error code otherwise.
82234 +*//***************************************************************************/
82235 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
82236 +
82237 +/**************************************************************************//**
82238 + @Function FM_PCD_Free
82239 +
82240 + @Description Frees all resources that were assigned to FM module.
82241 +
82242 + Calling this routine invalidates the descriptor.
82243 +
82244 + @Param[in] h_FmPcd - FM PCD module descriptor.
82245 +
82246 + @Return E_OK on success; Error code otherwise.
82247 +*//***************************************************************************/
82248 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
82249 +
82250 +/**************************************************************************//**
82251 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
82252 +
82253 + @Description Frame Manager PCD Advanced Configuration API.
82254 +
82255 + @{
82256 +*//***************************************************************************/
82257 +
82258 +/**************************************************************************//**
82259 + @Function FM_PCD_ConfigException
82260 +
82261 + @Description Calling this routine changes the internal driver data base
82262 + from its default selection of exceptions enabling.
82263 + [DEFAULT_numOfSharedPlcrProfiles].
82264 +
82265 + @Param[in] h_FmPcd FM PCD module descriptor.
82266 + @Param[in] exception The exception to be selected.
82267 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
82268 +
82269 + @Return E_OK on success; Error code otherwise.
82270 +
82271 + @Cautions This routine should NOT be called from guest-partition
82272 + (i.e. guestId != NCSW_MASTER_ID)
82273 +*//***************************************************************************/
82274 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
82275 +
82276 +/**************************************************************************//**
82277 + @Function FM_PCD_ConfigHcFramesDataMemory
82278 +
82279 + @Description Configures memory-partition-id for FMan-Controller Host-Command
82280 + frames. Calling this routine changes the internal driver data
82281 + base from its default configuration [0].
82282 +
82283 + @Param[in] h_FmPcd FM PCD module descriptor.
82284 + @Param[in] memId Memory partition ID.
82285 +
82286 + @Return E_OK on success; Error code otherwise.
82287 +
82288 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
82289 + when FM_PCD_Config() routine was called.
82290 +*//***************************************************************************/
82291 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
82292 +
82293 +/**************************************************************************//**
82294 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
82295 +
82296 + @Description Calling this routine changes the internal driver data base
82297 + from its default selection of exceptions enablement.
82298 + [DEFAULT_numOfSharedPlcrProfiles].
82299 +
82300 + @Param[in] h_FmPcd FM PCD module descriptor.
82301 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
82302 + be shared between ports on this partition
82303 +
82304 + @Return E_OK on success; Error code otherwise.
82305 +*//***************************************************************************/
82306 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
82307 +
82308 +/**************************************************************************//**
82309 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
82310 +
82311 + @Description Calling this routine changes the internal driver data base
82312 + from its default selection of exceptions enablement.
82313 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
82314 +
82315 + @Param[in] h_FmPcd FM PCD module descriptor.
82316 + @Param[in] enable TRUE to enable, FALSE to disable
82317 +
82318 + @Return E_OK on success; Error code otherwise.
82319 +
82320 + @Cautions This routine should NOT be called from guest-partition
82321 + (i.e. guestId != NCSW_MASTER_ID)
82322 +*//***************************************************************************/
82323 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
82324 +
82325 +/**************************************************************************//**
82326 + @Function FM_PCD_ConfigPrsMaxCycleLimit
82327 +
82328 + @Description Calling this routine changes the internal data structure for
82329 + the maximum parsing time from its default value
82330 + [DEFAULT_MAX_PRS_CYC_LIM].
82331 +
82332 + @Param[in] h_FmPcd FM PCD module descriptor.
82333 + @Param[in] value 0 to disable the mechanism, or new
82334 + maximum parsing time.
82335 +
82336 + @Return E_OK on success; Error code otherwise.
82337 +
82338 + @Cautions This routine should NOT be called from guest-partition
82339 + (i.e. guestId != NCSW_MASTER_ID)
82340 +*//***************************************************************************/
82341 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
82342 +
82343 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
82344 +/** @} */ /* end of FM_PCD_init_grp group */
82345 +
82346 +
82347 +/**************************************************************************//**
82348 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
82349 +
82350 + @Description Frame Manager PCD Runtime Unit API
82351 +
82352 + The runtime control allows creation of PCD infrastructure modules
82353 + such as Network Environment Characteristics, Classification Plan
82354 + Groups and Coarse Classification Trees.
82355 + It also allows on-the-fly initialization, modification and removal
82356 + of PCD modules such as KeyGen schemes, coarse classification nodes
82357 + and Policer profiles.
82358 +
82359 + In order to explain the programming model of the PCD driver interface
82360 + a few terms should be explained, and will be used below.
82361 + - Distinction Header - One of the 16 protocols supported by the FM parser,
82362 + or one of the SHIM headers (1 or 2). May be a header with a special
82363 + option (see below).
82364 + - Interchangeable Headers Group - This is a group of Headers recognized
82365 + by either one of them. For example, if in a specific context the user
82366 + chooses to treat IPv4 and IPV6 in the same way, they may create an
82367 + interchangeable Headers Unit consisting of these 2 headers.
82368 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
82369 + Group.
82370 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
82371 + IPv6, includes multicast, broadcast and other protocol specific options.
82372 + In terms of hardware it relates to the options available in the classification
82373 + plan.
82374 + - Network Environment Characteristics - a set of Distinction Units that define
82375 + the total recognizable header selection for a certain environment. This is
82376 + NOT the list of all headers that will ever appear in a flow, but rather
82377 + everything that needs distinction in a flow, where distinction is made by KeyGen
82378 + schemes and coarse classification action descriptors.
82379 +
82380 + The PCD runtime modules initialization is done in stages. The first stage after
82381 + initializing the PCD module itself is to establish a Network Flows Environment
82382 + Definition. The application may choose to establish one or more such environments.
82383 + Later, when needed, the application will have to state, for some of its modules,
82384 + to which single environment it belongs.
82385 +
82386 + @{
82387 +*//***************************************************************************/
82388 +
82389 +/**************************************************************************//**
82390 + @Description A structure for SW parser labels
82391 + *//***************************************************************************/
82392 +typedef struct t_FmPcdPrsLabelParams {
82393 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
82394 + resolution), relative to Parser RAM. */
82395 + e_NetHeaderType hdr; /**< The existence of this header will invoke
82396 + the SW parser code; Use HEADER_TYPE_NONE
82397 + to indicate that sw parser is to run
82398 + independent of the existence of any protocol
82399 + (run before HW parser). */
82400 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
82401 + attachments for the same header, use this
82402 + index to distinguish between them. */
82403 +} t_FmPcdPrsLabelParams;
82404 +
82405 +/**************************************************************************//**
82406 + @Description A structure for SW parser
82407 + *//***************************************************************************/
82408 +typedef struct t_FmPcdPrsSwParams {
82409 + bool override; /**< FALSE to invoke a check that nothing else
82410 + was loaded to this address, including
82411 + internal patches.
82412 + TRUE to override any existing code.*/
82413 + uint32_t size; /**< SW parser code size */
82414 + uint16_t base; /**< SW parser base (in instruction counts!
82415 + must be larger than 0x20)*/
82416 + uint8_t *p_Code; /**< SW parser code */
82417 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
82418 + /**< SW parser data (parameters) */
82419 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
82420 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
82421 + /**< SW parser labels table, containing
82422 + numOfLabels entries */
82423 +} t_FmPcdPrsSwParams;
82424 +
82425 +
82426 +/**************************************************************************//**
82427 + @Function FM_PCD_Enable
82428 +
82429 + @Description This routine should be called after PCD is initialized for enabling all
82430 + PCD engines according to their existing configuration.
82431 +
82432 + @Param[in] h_FmPcd FM PCD module descriptor.
82433 +
82434 + @Return E_OK on success; Error code otherwise.
82435 +
82436 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82437 +*//***************************************************************************/
82438 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
82439 +
82440 +/**************************************************************************//**
82441 + @Function FM_PCD_Disable
82442 +
82443 + @Description This routine may be called when PCD is enabled in order to
82444 + disable all PCD engines. It may be called
82445 + only when none of the ports in the system are using the PCD.
82446 +
82447 + @Param[in] h_FmPcd FM PCD module descriptor.
82448 +
82449 + @Return E_OK on success; Error code otherwise.
82450 +
82451 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
82452 +*//***************************************************************************/
82453 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
82454 +
82455 +/**************************************************************************//**
82456 + @Function FM_PCD_GetCounter
82457 +
82458 + @Description Reads one of the FM PCD counters.
82459 +
82460 + @Param[in] h_FmPcd FM PCD module descriptor.
82461 + @Param[in] counter The requested counter.
82462 +
82463 + @Return Counter's current value.
82464 +
82465 + @Cautions Allowed only following FM_PCD_Init().
82466 + Note that it is user's responsibility to call this routine only
82467 + for enabled counters, and there will be no indication if a
82468 + disabled counter is accessed.
82469 +*//***************************************************************************/
82470 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
82471 +
82472 +/**************************************************************************//**
82473 +@Function FM_PCD_PrsLoadSw
82474 +
82475 +@Description This routine may be called in order to load software parsing code.
82476 +
82477 +
82478 +@Param[in] h_FmPcd FM PCD module descriptor.
82479 +@Param[in] p_SwPrs A pointer to a structure of software
82480 + parser parameters, including the software
82481 + parser image.
82482 +
82483 +@Return E_OK on success; Error code otherwise.
82484 +
82485 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82486 + This routine should NOT be called from guest-partition
82487 + (i.e. guestId != NCSW_MASTER_ID)
82488 +*//***************************************************************************/
82489 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
82490 +
82491 +/**************************************************************************//**
82492 +@Function FM_PCD_SetAdvancedOffloadSupport
82493 +
82494 +@Description This routine must be called in order to support the following features:
82495 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
82496 +
82497 +@Param[in] h_FmPcd FM PCD module descriptor.
82498 +
82499 +@Return E_OK on success; Error code otherwise.
82500 +
82501 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82502 + This routine should NOT be called from guest-partition
82503 + (i.e. guestId != NCSW_MASTER_ID)
82504 +*//***************************************************************************/
82505 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
82506 +
82507 +/**************************************************************************//**
82508 + @Function FM_PCD_KgSetDfltValue
82509 +
82510 + @Description Calling this routine sets a global default value to be used
82511 + by the KeyGen when parser does not recognize a required
82512 + field/header.
82513 + By default default values are 0.
82514 +
82515 + @Param[in] h_FmPcd FM PCD module descriptor.
82516 + @Param[in] valueId 0,1 - one of 2 global default values.
82517 + @Param[in] value The requested default value.
82518 +
82519 + @Return E_OK on success; Error code otherwise.
82520 +
82521 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82522 + This routine should NOT be called from guest-partition
82523 + (i.e. guestId != NCSW_MASTER_ID)
82524 +*//***************************************************************************/
82525 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
82526 +
82527 +/**************************************************************************//**
82528 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
82529 +
82530 + @Description Calling this routine allows the KeyGen to access data past
82531 + the parser finishing point.
82532 +
82533 + @Param[in] h_FmPcd FM PCD module descriptor.
82534 + @Param[in] payloadOffset the number of bytes beyond the parser location.
82535 +
82536 + @Return E_OK on success; Error code otherwise.
82537 +
82538 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82539 + This routine should NOT be called from guest-partition
82540 + (i.e. guestId != NCSW_MASTER_ID)
82541 +*//***************************************************************************/
82542 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
82543 +
82544 +/**************************************************************************//**
82545 + @Function FM_PCD_SetException
82546 +
82547 + @Description Calling this routine enables/disables PCD interrupts.
82548 +
82549 + @Param[in] h_FmPcd FM PCD module descriptor.
82550 + @Param[in] exception The exception to be selected.
82551 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
82552 +
82553 + @Return E_OK on success; Error code otherwise.
82554 +
82555 + @Cautions Allowed only following FM_PCD_Init().
82556 + This routine should NOT be called from guest-partition
82557 + (i.e. guestId != NCSW_MASTER_ID)
82558 +*//***************************************************************************/
82559 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
82560 +
82561 +/**************************************************************************//**
82562 + @Function FM_PCD_ModifyCounter
82563 +
82564 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
82565 +
82566 + @Param[in] h_FmPcd FM PCD module descriptor.
82567 + @Param[in] counter The requested counter.
82568 + @Param[in] value The requested value to be written into the counter.
82569 +
82570 + @Return E_OK on success; Error code otherwise.
82571 +
82572 + @Cautions Allowed only following FM_PCD_Init().
82573 + This routine should NOT be called from guest-partition
82574 + (i.e. guestId != NCSW_MASTER_ID)
82575 +*//***************************************************************************/
82576 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
82577 +
82578 +/**************************************************************************//**
82579 + @Function FM_PCD_SetPlcrStatistics
82580 +
82581 + @Description This routine may be used to enable/disable policer statistics
82582 + counter. By default the statistics is enabled.
82583 +
82584 + @Param[in] h_FmPcd FM PCD module descriptor
82585 + @Param[in] enable TRUE to enable, FALSE to disable.
82586 +
82587 + @Return E_OK on success; Error code otherwise.
82588 +
82589 + @Cautions Allowed only following FM_PCD_Init().
82590 + This routine should NOT be called from guest-partition
82591 + (i.e. guestId != NCSW_MASTER_ID)
82592 +*//***************************************************************************/
82593 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
82594 +
82595 +/**************************************************************************//**
82596 + @Function FM_PCD_SetPrsStatistics
82597 +
82598 + @Description Defines whether to gather parser statistics including all ports.
82599 +
82600 + @Param[in] h_FmPcd FM PCD module descriptor.
82601 + @Param[in] enable TRUE to enable, FALSE to disable.
82602 +
82603 + @Return None
82604 +
82605 + @Cautions Allowed only following FM_PCD_Init().
82606 + This routine should NOT be called from guest-partition
82607 + (i.e. guestId != NCSW_MASTER_ID)
82608 +*//***************************************************************************/
82609 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
82610 +
82611 +/**************************************************************************//**
82612 + @Function FM_PCD_HcTxConf
82613 +
82614 + @Description This routine should be called to confirm frames that were
82615 + received on the HC confirmation queue.
82616 +
82617 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82618 + @Param[in] p_Fd Frame descriptor of the received frame.
82619 +
82620 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
82621 + option was selected in the initialization.
82622 +*//***************************************************************************/
82623 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
82624 +
82625 +/**************************************************************************//*
82626 + @Function FM_PCD_ForceIntr
82627 +
82628 + @Description Causes an interrupt event on the requested source.
82629 +
82630 + @Param[in] h_FmPcd FM PCD module descriptor.
82631 + @Param[in] exception An exception to be forced.
82632 +
82633 + @Return E_OK on success; Error code if the exception is not enabled,
82634 + or is not able to create interrupt.
82635 +
82636 + @Cautions Allowed only following FM_PCD_Init().
82637 + This routine should NOT be called from guest-partition
82638 + (i.e. guestId != NCSW_MASTER_ID)
82639 +*//***************************************************************************/
82640 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
82641 +
82642 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
82643 +/**************************************************************************//**
82644 + @Function FM_PCD_DumpRegs
82645 +
82646 + @Description Dumps all PCD registers
82647 +
82648 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82649 +
82650 + @Return E_OK on success; Error code otherwise.
82651 +
82652 + @Cautions Allowed only following FM_PCD_Init().
82653 + NOTE: this routine may be called only for FM in master mode
82654 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
82655 + are mapped.
82656 +*//***************************************************************************/
82657 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
82658 +
82659 +/**************************************************************************//**
82660 + @Function FM_PCD_KgDumpRegs
82661 +
82662 + @Description Dumps all PCD KG registers
82663 +
82664 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82665 +
82666 + @Return E_OK on success; Error code otherwise.
82667 +
82668 + @Cautions Allowed only following FM_PCD_Init().
82669 + NOTE: this routine may be called only for FM in master mode
82670 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
82671 + are mapped.
82672 +*//***************************************************************************/
82673 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
82674 +
82675 +/**************************************************************************//**
82676 + @Function FM_PCD_PlcrDumpRegs
82677 +
82678 + @Description Dumps all PCD Policer registers
82679 +
82680 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82681 +
82682 + @Return E_OK on success; Error code otherwise.
82683 +
82684 + @Cautions Allowed only following FM_PCD_Init().
82685 + NOTE: this routine may be called only for FM in master mode
82686 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
82687 + are mapped.
82688 +*//***************************************************************************/
82689 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
82690 +
82691 +/**************************************************************************//**
82692 + @Function FM_PCD_PlcrProfileDumpRegs
82693 +
82694 + @Description Dumps all PCD Policer profile registers
82695 +
82696 + @Param[in] h_Profile A handle to a Policer profile.
82697 +
82698 + @Return E_OK on success; Error code otherwise.
82699 +
82700 + @Cautions Allowed only following FM_PCD_Init().
82701 + NOTE: this routine may be called only for FM in master mode
82702 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
82703 + are mapped.
82704 +*//***************************************************************************/
82705 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
82706 +
82707 +/**************************************************************************//**
82708 + @Function FM_PCD_PrsDumpRegs
82709 +
82710 + @Description Dumps all PCD Parser registers
82711 +
82712 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82713 +
82714 + @Return E_OK on success; Error code otherwise.
82715 +
82716 + @Cautions Allowed only following FM_PCD_Init().
82717 + NOTE: this routine may be called only for FM in master mode
82718 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
82719 + are mapped.
82720 +*//***************************************************************************/
82721 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
82722 +
82723 +/**************************************************************************//**
82724 + @Function FM_PCD_HcDumpRegs
82725 +
82726 + @Description Dumps HC Port registers
82727 +
82728 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82729 +
82730 + @Return E_OK on success; Error code otherwise.
82731 +
82732 + @Cautions Allowed only following FM_PCD_Init().
82733 + NOTE: this routine may be called only for FM in master mode
82734 + (i.e. 'guestId'=NCSW_MASTER_ID).
82735 +*//***************************************************************************/
82736 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
82737 +#endif /* (defined(DEBUG_ERRORS) && ... */
82738 +
82739 +
82740 +
82741 +/**************************************************************************//**
82742 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
82743 +
82744 + @Description Frame Manager PCD Runtime Building API
82745 +
82746 + This group contains routines for setting, deleting and modifying
82747 + PCD resources, for defining the total PCD tree.
82748 + @{
82749 +*//***************************************************************************/
82750 +
82751 +/**************************************************************************//**
82752 + @Collection Definitions of coarse classification
82753 + parameters as required by KeyGen (when coarse classification
82754 + is the next engine after this scheme).
82755 +*//***************************************************************************/
82756 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
82757 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
82758 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
82759 +#define FM_PCD_MAX_NUM_OF_KEYS 256
82760 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
82761 +#define FM_PCD_MAX_SIZE_OF_KEY 56
82762 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
82763 +#define FM_PCD_LAST_KEY_INDEX 0xffff
82764 +
82765 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
82766 +/* @} */
82767 +
82768 +/**************************************************************************//**
82769 + @Collection A set of definitions to allow protocol
82770 + special option description.
82771 +*//***************************************************************************/
82772 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
82773 +
82774 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
82775 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
82776 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
82777 +
82778 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
82779 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
82780 +
82781 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
82782 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
82783 +
82784 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
82785 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
82786 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
82787 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
82788 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
82789 +
82790 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
82791 + IPV4 Reassembly manipulation requires network
82792 + environment with IPV4 header and IPV4_FRAG_1 option */
82793 +
82794 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
82795 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
82796 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
82797 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
82798 +
82799 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
82800 + IPV6 Reassembly manipulation requires network
82801 + environment with IPV6 header and IPV6_FRAG_1 option;
82802 + in case where fragment found, the fragment-extension offset
82803 + may be found at 'shim2' (in parser-result). */
82804 +#if (DPAA_VERSION >= 11)
82805 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
82806 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
82807 + CAPWAP Reassembly manipulation requires network
82808 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
82809 + in case where fragment found, the fragment-extension offset
82810 + may be found at 'shim2' (in parser-result). */
82811 +#endif /* (DPAA_VERSION >= 11) */
82812 +
82813 +
82814 +/* @} */
82815 +
82816 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
82817 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
82818 +
82819 +/**************************************************************************//**
82820 + @Collection A set of definitions to support Header Manipulation selection.
82821 +*//***************************************************************************/
82822 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
82823 +
82824 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
82825 +
82826 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
82827 + of t_FmPcdManipHdrFieldUpdateIpv4) */
82828 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
82829 + of t_FmPcdManipHdrFieldUpdateIpv4) */
82830 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
82831 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
82832 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
82833 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
82834 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
82835 +
82836 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
82837 +
82838 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
82839 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
82840 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
82841 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
82842 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
82843 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
82844 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
82845 +
82846 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
82847 +
82848 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
82849 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
82850 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
82851 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
82852 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
82853 +
82854 +/* @} */
82855 +
82856 +/**************************************************************************//**
82857 + @Description A type used for returning the order of the key extraction.
82858 + each value in this array represents the index of the extraction
82859 + command as defined by the user in the initialization extraction array.
82860 + The valid size of this array is the user define number of extractions
82861 + required (also marked by the second '0' in this array).
82862 +*//***************************************************************************/
82863 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
82864 +
82865 +/**************************************************************************//**
82866 + @Description All PCD engines
82867 +*//***************************************************************************/
82868 +typedef enum e_FmPcdEngine {
82869 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
82870 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
82871 + e_FM_PCD_KG, /**< KeyGen */
82872 + e_FM_PCD_CC, /**< Coarse classifier */
82873 + e_FM_PCD_PLCR, /**< Policer */
82874 + e_FM_PCD_PRS, /**< Parser */
82875 +#if (DPAA_VERSION >= 11)
82876 + e_FM_PCD_FR, /**< Frame-Replicator */
82877 +#endif /* (DPAA_VERSION >= 11) */
82878 + e_FM_PCD_HASH /**< Hash table */
82879 +} e_FmPcdEngine;
82880 +
82881 +/**************************************************************************//**
82882 + @Description Enumeration type for selecting extraction by header types
82883 +*//***************************************************************************/
82884 +typedef enum e_FmPcdExtractByHdrType {
82885 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
82886 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
82887 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
82888 +} e_FmPcdExtractByHdrType;
82889 +
82890 +/**************************************************************************//**
82891 + @Description Enumeration type for selecting extraction source
82892 + (when it is not the header)
82893 +*//***************************************************************************/
82894 +typedef enum e_FmPcdExtractFrom {
82895 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
82896 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
82897 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
82898 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
82899 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
82900 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
82901 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
82902 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
82903 +} e_FmPcdExtractFrom;
82904 +
82905 +/**************************************************************************//**
82906 + @Description Enumeration type for selecting extraction type
82907 +*//***************************************************************************/
82908 +typedef enum e_FmPcdExtractType {
82909 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
82910 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
82911 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
82912 +} e_FmPcdExtractType;
82913 +
82914 +/**************************************************************************//**
82915 + @Description Enumeration type for selecting default extraction value
82916 +*//***************************************************************************/
82917 +typedef enum e_FmPcdKgExtractDfltSelect {
82918 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
82919 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
82920 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
82921 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
82922 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
82923 +} e_FmPcdKgExtractDfltSelect;
82924 +
82925 +/**************************************************************************//**
82926 + @Description Enumeration type defining all default groups - each group shares
82927 + a default value, one of four user-initialized values.
82928 +*//***************************************************************************/
82929 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
82930 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
82931 + e_FM_PCD_KG_TCI, /**< TCI field */
82932 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
82933 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
82934 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
82935 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
82936 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
82937 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
82938 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
82939 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
82940 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
82941 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
82942 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
82943 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
82944 + any data extraction that is not the full
82945 + field described above */
82946 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
82947 + any data extraction without validation */
82948 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
82949 + extraction from parser result or
82950 + direct use of default value */
82951 +} e_FmPcdKgKnownFieldsDfltTypes;
82952 +
82953 +/**************************************************************************//**
82954 + @Description Enumeration type for defining header index for scenarios with
82955 + multiple (tunneled) headers
82956 +*//***************************************************************************/
82957 +typedef enum e_FmPcdHdrIndex {
82958 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
82959 + to specify regular IP (not tunneled). */
82960 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
82961 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
82962 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
82963 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
82964 +} e_FmPcdHdrIndex;
82965 +
82966 +/**************************************************************************//**
82967 + @Description Enumeration type for selecting the policer profile functional type
82968 +*//***************************************************************************/
82969 +typedef enum e_FmPcdProfileTypeSelection {
82970 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
82971 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
82972 +} e_FmPcdProfileTypeSelection;
82973 +
82974 +/**************************************************************************//**
82975 + @Description Enumeration type for selecting the policer profile algorithm
82976 +*//***************************************************************************/
82977 +typedef enum e_FmPcdPlcrAlgorithmSelection {
82978 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
82979 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
82980 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
82981 +} e_FmPcdPlcrAlgorithmSelection;
82982 +
82983 +/**************************************************************************//**
82984 + @Description Enumeration type for selecting a policer profile color mode
82985 +*//***************************************************************************/
82986 +typedef enum e_FmPcdPlcrColorMode {
82987 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
82988 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
82989 +} e_FmPcdPlcrColorMode;
82990 +
82991 +/**************************************************************************//**
82992 + @Description Enumeration type for selecting a policer profile color
82993 +*//***************************************************************************/
82994 +typedef enum e_FmPcdPlcrColor {
82995 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
82996 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
82997 + e_FM_PCD_PLCR_RED, /**< Red color code */
82998 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
82999 +} e_FmPcdPlcrColor;
83000 +
83001 +/**************************************************************************//**
83002 + @Description Enumeration type for selecting the policer profile packet frame length selector
83003 +*//***************************************************************************/
83004 +typedef enum e_FmPcdPlcrFrameLengthSelect {
83005 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
83006 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
83007 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
83008 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
83009 +} e_FmPcdPlcrFrameLengthSelect;
83010 +
83011 +/**************************************************************************//**
83012 + @Description Enumeration type for selecting roll-back frame
83013 +*//***************************************************************************/
83014 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
83015 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
83016 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
83017 +} e_FmPcdPlcrRollBackFrameSelect;
83018 +
83019 +/**************************************************************************//**
83020 + @Description Enumeration type for selecting the policer profile packet or byte mode
83021 +*//***************************************************************************/
83022 +typedef enum e_FmPcdPlcrRateMode {
83023 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
83024 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
83025 +} e_FmPcdPlcrRateMode;
83026 +
83027 +/**************************************************************************//**
83028 + @Description Enumeration type for defining action of frame
83029 +*//***************************************************************************/
83030 +typedef enum e_FmPcdDoneAction {
83031 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
83032 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
83033 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
83034 + flag will be set for this frame. */
83035 +} e_FmPcdDoneAction;
83036 +
83037 +/**************************************************************************//**
83038 + @Description Enumeration type for selecting the policer counter
83039 +*//***************************************************************************/
83040 +typedef enum e_FmPcdPlcrProfileCounters {
83041 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
83042 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
83043 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
83044 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
83045 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
83046 +} e_FmPcdPlcrProfileCounters;
83047 +
83048 +/**************************************************************************//**
83049 + @Description Enumeration type for selecting the PCD action after extraction
83050 +*//***************************************************************************/
83051 +typedef enum e_FmPcdAction {
83052 + e_FM_PCD_ACTION_NONE, /**< NONE */
83053 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
83054 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
83055 +} e_FmPcdAction;
83056 +
83057 +/**************************************************************************//**
83058 + @Description Enumeration type for selecting type of insert manipulation
83059 +*//***************************************************************************/
83060 +typedef enum e_FmPcdManipHdrInsrtType {
83061 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
83062 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
83063 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83064 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
83065 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83066 +} e_FmPcdManipHdrInsrtType;
83067 +
83068 +/**************************************************************************//**
83069 + @Description Enumeration type for selecting type of remove manipulation
83070 +*//***************************************************************************/
83071 +typedef enum e_FmPcdManipHdrRmvType {
83072 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
83073 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
83074 +} e_FmPcdManipHdrRmvType;
83075 +
83076 +/**************************************************************************//**
83077 + @Description Enumeration type for selecting specific L2 fields removal
83078 +*//***************************************************************************/
83079 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
83080 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
83081 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
83082 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
83083 + the header which follows the MPLS header */
83084 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
83085 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
83086 +} e_FmPcdManipHdrRmvSpecificL2;
83087 +
83088 +/**************************************************************************//**
83089 + @Description Enumeration type for selecting specific fields updates
83090 +*//***************************************************************************/
83091 +typedef enum e_FmPcdManipHdrFieldUpdateType {
83092 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
83093 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
83094 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
83095 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
83096 +} e_FmPcdManipHdrFieldUpdateType;
83097 +
83098 +/**************************************************************************//**
83099 + @Description Enumeration type for selecting VLAN updates
83100 +*//***************************************************************************/
83101 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
83102 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
83103 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
83104 +} e_FmPcdManipHdrFieldUpdateVlan;
83105 +
83106 +/**************************************************************************//**
83107 + @Description Enumeration type for selecting specific L2 header insertion
83108 +*//***************************************************************************/
83109 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
83110 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
83111 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
83112 +} e_FmPcdManipHdrInsrtSpecificL2;
83113 +
83114 +#if (DPAA_VERSION >= 11)
83115 +/**************************************************************************//**
83116 + @Description Enumeration type for selecting QoS mapping mode
83117 +
83118 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
83119 + User should instruct the port to read the hash-result
83120 +*//***************************************************************************/
83121 +typedef enum e_FmPcdManipHdrQosMappingMode {
83122 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
83123 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
83124 +} e_FmPcdManipHdrQosMappingMode;
83125 +
83126 +/**************************************************************************//**
83127 + @Description Enumeration type for selecting QoS source
83128 +
83129 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
83130 + User should left room for the hash-result on input/output buffer
83131 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
83132 +*//***************************************************************************/
83133 +typedef enum e_FmPcdManipHdrQosSrc {
83134 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
83135 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
83136 +} e_FmPcdManipHdrQosSrc;
83137 +#endif /* (DPAA_VERSION >= 11) */
83138 +
83139 +/**************************************************************************//**
83140 + @Description Enumeration type for selecting type of header insertion
83141 +*//***************************************************************************/
83142 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
83143 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
83144 +#if (DPAA_VERSION >= 11)
83145 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
83146 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
83147 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
83148 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
83149 +#endif /* (DPAA_VERSION >= 11) */
83150 +} e_FmPcdManipHdrInsrtByHdrType;
83151 +
83152 +/**************************************************************************//**
83153 + @Description Enumeration type for selecting specific customCommand
83154 +*//***************************************************************************/
83155 +typedef enum e_FmPcdManipHdrCustomType {
83156 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
83157 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
83158 +} e_FmPcdManipHdrCustomType;
83159 +
83160 +/**************************************************************************//**
83161 + @Description Enumeration type for selecting specific customCommand
83162 +*//***************************************************************************/
83163 +typedef enum e_FmPcdManipHdrCustomIpReplace {
83164 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
83165 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
83166 +} e_FmPcdManipHdrCustomIpReplace;
83167 +
83168 +/**************************************************************************//**
83169 + @Description Enumeration type for selecting type of header removal
83170 +*//***************************************************************************/
83171 +typedef enum e_FmPcdManipHdrRmvByHdrType {
83172 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
83173 +#if (DPAA_VERSION >= 11)
83174 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
83175 +#endif /* (DPAA_VERSION >= 11) */
83176 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83177 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
83178 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83179 +} e_FmPcdManipHdrRmvByHdrType;
83180 +
83181 +/**************************************************************************//**
83182 + @Description Enumeration type for selecting type of timeout mode
83183 +*//***************************************************************************/
83184 +typedef enum e_FmPcdManipReassemTimeOutMode {
83185 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
83186 + from the first fragment to the last */
83187 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
83188 +} e_FmPcdManipReassemTimeOutMode;
83189 +
83190 +/**************************************************************************//**
83191 + @Description Enumeration type for selecting type of WaysNumber mode
83192 +*//***************************************************************************/
83193 +typedef enum e_FmPcdManipReassemWaysNumber {
83194 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
83195 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
83196 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
83197 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
83198 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
83199 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
83200 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
83201 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
83202 +} e_FmPcdManipReassemWaysNumber;
83203 +
83204 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83205 +/**************************************************************************//**
83206 + @Description Enumeration type for selecting type of statistics mode
83207 +*//***************************************************************************/
83208 +typedef enum e_FmPcdStatsType {
83209 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
83210 +} e_FmPcdStatsType;
83211 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83212 +
83213 +/**************************************************************************//**
83214 + @Description Enumeration type for selecting manipulation type
83215 +*//***************************************************************************/
83216 +typedef enum e_FmPcdManipType {
83217 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
83218 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
83219 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
83220 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
83221 +} e_FmPcdManipType;
83222 +
83223 +/**************************************************************************//**
83224 + @Description Enumeration type for selecting type of statistics mode
83225 +*//***************************************************************************/
83226 +typedef enum e_FmPcdCcStatsMode {
83227 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
83228 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
83229 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
83230 +#if (DPAA_VERSION >= 11)
83231 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
83232 + This mode is supported only on B4860 device */
83233 +#endif /* (DPAA_VERSION >= 11) */
83234 +} e_FmPcdCcStatsMode;
83235 +
83236 +/**************************************************************************//**
83237 + @Description Enumeration type for determining the action in case an IP packet
83238 + is larger than MTU but its DF (Don't Fragment) bit is set.
83239 +*//***************************************************************************/
83240 +typedef enum e_FmPcdManipDontFragAction {
83241 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
83242 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
83243 + /**< Obsolete, cannot enqueue to error queue;
83244 + In practice, selects to discard packets;
83245 + Will be removed in the future */
83246 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
83247 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
83248 +} e_FmPcdManipDontFragAction;
83249 +
83250 +/**************************************************************************//**
83251 + @Description Enumeration type for selecting type of special offload manipulation
83252 +*//***************************************************************************/
83253 +typedef enum e_FmPcdManipSpecialOffloadType {
83254 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
83255 +#if (DPAA_VERSION >= 11)
83256 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
83257 +#endif /* (DPAA_VERSION >= 11) */
83258 +} e_FmPcdManipSpecialOffloadType;
83259 +
83260 +
83261 +/**************************************************************************//**
83262 + @Description A Union of protocol dependent special options
83263 +*//***************************************************************************/
83264 +typedef union u_FmPcdHdrProtocolOpt {
83265 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
83266 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
83267 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
83268 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
83269 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
83270 +#if (DPAA_VERSION >= 11)
83271 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
83272 +#endif /* (DPAA_VERSION >= 11) */
83273 +} u_FmPcdHdrProtocolOpt;
83274 +
83275 +/**************************************************************************//**
83276 + @Description A union holding protocol fields
83277 +
83278 +
83279 + Fields supported as "full fields":
83280 + HEADER_TYPE_ETH:
83281 + NET_HEADER_FIELD_ETH_DA
83282 + NET_HEADER_FIELD_ETH_SA
83283 + NET_HEADER_FIELD_ETH_TYPE
83284 +
83285 + HEADER_TYPE_LLC_SNAP:
83286 + NET_HEADER_FIELD_LLC_SNAP_TYPE
83287 +
83288 + HEADER_TYPE_VLAN:
83289 + NET_HEADER_FIELD_VLAN_TCI
83290 + (index may apply:
83291 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83292 + e_FM_PCD_HDR_INDEX_LAST)
83293 +
83294 + HEADER_TYPE_MPLS:
83295 + NET_HEADER_FIELD_MPLS_LABEL_STACK
83296 + (index may apply:
83297 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83298 + e_FM_PCD_HDR_INDEX_2,
83299 + e_FM_PCD_HDR_INDEX_LAST)
83300 +
83301 + HEADER_TYPE_IPv4:
83302 + NET_HEADER_FIELD_IPv4_SRC_IP
83303 + NET_HEADER_FIELD_IPv4_DST_IP
83304 + NET_HEADER_FIELD_IPv4_PROTO
83305 + NET_HEADER_FIELD_IPv4_TOS
83306 + (index may apply:
83307 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83308 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83309 +
83310 + HEADER_TYPE_IPv6:
83311 + NET_HEADER_FIELD_IPv6_SRC_IP
83312 + NET_HEADER_FIELD_IPv6_DST_IP
83313 + NET_HEADER_FIELD_IPv6_NEXT_HDR
83314 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
83315 + (index may apply:
83316 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83317 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83318 +
83319 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
83320 + the last next header indication, meaning the next L4, which may be
83321 + present at the Ipv6 last extension. On earlier revisions this field
83322 + applies to the Next-Header field of the main IPv6 header)
83323 +
83324 + HEADER_TYPE_IP:
83325 + NET_HEADER_FIELD_IP_PROTO
83326 + (index may apply:
83327 + e_FM_PCD_HDR_INDEX_LAST)
83328 + NET_HEADER_FIELD_IP_DSCP
83329 + (index may apply:
83330 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
83331 + HEADER_TYPE_GRE:
83332 + NET_HEADER_FIELD_GRE_TYPE
83333 +
83334 + HEADER_TYPE_MINENCAP
83335 + NET_HEADER_FIELD_MINENCAP_SRC_IP
83336 + NET_HEADER_FIELD_MINENCAP_DST_IP
83337 + NET_HEADER_FIELD_MINENCAP_TYPE
83338 +
83339 + HEADER_TYPE_TCP:
83340 + NET_HEADER_FIELD_TCP_PORT_SRC
83341 + NET_HEADER_FIELD_TCP_PORT_DST
83342 + NET_HEADER_FIELD_TCP_FLAGS
83343 +
83344 + HEADER_TYPE_UDP:
83345 + NET_HEADER_FIELD_UDP_PORT_SRC
83346 + NET_HEADER_FIELD_UDP_PORT_DST
83347 +
83348 + HEADER_TYPE_UDP_LITE:
83349 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
83350 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
83351 +
83352 + HEADER_TYPE_IPSEC_AH:
83353 + NET_HEADER_FIELD_IPSEC_AH_SPI
83354 + NET_HEADER_FIELD_IPSEC_AH_NH
83355 +
83356 + HEADER_TYPE_IPSEC_ESP:
83357 + NET_HEADER_FIELD_IPSEC_ESP_SPI
83358 +
83359 + HEADER_TYPE_SCTP:
83360 + NET_HEADER_FIELD_SCTP_PORT_SRC
83361 + NET_HEADER_FIELD_SCTP_PORT_DST
83362 +
83363 + HEADER_TYPE_DCCP:
83364 + NET_HEADER_FIELD_DCCP_PORT_SRC
83365 + NET_HEADER_FIELD_DCCP_PORT_DST
83366 +
83367 + HEADER_TYPE_PPPoE:
83368 + NET_HEADER_FIELD_PPPoE_PID
83369 + NET_HEADER_FIELD_PPPoE_SID
83370 +
83371 + *****************************************************************
83372 + Fields supported as "from fields":
83373 + HEADER_TYPE_ETH (with or without validation):
83374 + NET_HEADER_FIELD_ETH_TYPE
83375 +
83376 + HEADER_TYPE_VLAN (with or without validation):
83377 + NET_HEADER_FIELD_VLAN_TCI
83378 + (index may apply:
83379 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83380 + e_FM_PCD_HDR_INDEX_LAST)
83381 +
83382 + HEADER_TYPE_IPv4 (without validation):
83383 + NET_HEADER_FIELD_IPv4_PROTO
83384 + (index may apply:
83385 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83386 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83387 +
83388 + HEADER_TYPE_IPv6 (without validation):
83389 + NET_HEADER_FIELD_IPv6_NEXT_HDR
83390 + (index may apply:
83391 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83392 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83393 +
83394 +*//***************************************************************************/
83395 +typedef union t_FmPcdFields {
83396 + headerFieldEth_t eth; /**< Ethernet */
83397 + headerFieldVlan_t vlan; /**< VLAN */
83398 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
83399 + headerFieldPppoe_t pppoe; /**< PPPoE */
83400 + headerFieldMpls_t mpls; /**< MPLS */
83401 + headerFieldIp_t ip; /**< IP */
83402 + headerFieldIpv4_t ipv4; /**< IPv4 */
83403 + headerFieldIpv6_t ipv6; /**< IPv6 */
83404 + headerFieldUdp_t udp; /**< UDP */
83405 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
83406 + headerFieldTcp_t tcp; /**< TCP */
83407 + headerFieldSctp_t sctp; /**< SCTP */
83408 + headerFieldDccp_t dccp; /**< DCCP */
83409 + headerFieldGre_t gre; /**< GRE */
83410 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
83411 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
83412 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
83413 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
83414 +} t_FmPcdFields;
83415 +
83416 +/**************************************************************************//**
83417 + @Description Parameters for defining header extraction for key generation
83418 +*//***************************************************************************/
83419 +typedef struct t_FmPcdFromHdr {
83420 + uint8_t size; /**< Size in byte */
83421 + uint8_t offset; /**< Byte offset */
83422 +} t_FmPcdFromHdr;
83423 +
83424 +/**************************************************************************//**
83425 + @Description Parameters for defining field extraction for key generation
83426 +*//***************************************************************************/
83427 +typedef struct t_FmPcdFromField {
83428 + t_FmPcdFields field; /**< Field selection */
83429 + uint8_t size; /**< Size in byte */
83430 + uint8_t offset; /**< Byte offset */
83431 +} t_FmPcdFromField;
83432 +
83433 +/**************************************************************************//**
83434 + @Description Parameters for defining a single network environment unit
83435 +
83436 + A distinction unit should be defined if it will later be used
83437 + by one or more PCD engines to distinguish between flows.
83438 +*//***************************************************************************/
83439 +typedef struct t_FmPcdDistinctionUnit {
83440 + struct {
83441 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
83442 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
83443 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
83444 +} t_FmPcdDistinctionUnit;
83445 +
83446 +/**************************************************************************//**
83447 + @Description Parameters for defining all different distinction units supported
83448 + by a specific PCD Network Environment Characteristics module.
83449 +
83450 + Each unit represent a protocol or a group of protocols that may
83451 + be used later by the different PCD engines to distinguish
83452 + between flows.
83453 +*//***************************************************************************/
83454 +typedef struct t_FmPcdNetEnvParams {
83455 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
83456 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
83457 + different units to be identified */
83458 +} t_FmPcdNetEnvParams;
83459 +
83460 +/**************************************************************************//**
83461 + @Description Parameters for defining a single extraction action when
83462 + creating a key
83463 +*//***************************************************************************/
83464 +typedef struct t_FmPcdExtractEntry {
83465 + e_FmPcdExtractType type; /**< Extraction type select */
83466 + union {
83467 + struct {
83468 + e_NetHeaderType hdr; /**< Header selection */
83469 + bool ignoreProtocolValidation;
83470 + /**< Ignore protocol validation */
83471 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
83472 + IP. Otherwise should be cleared. */
83473 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
83474 + union {
83475 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
83476 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
83477 + t_FmPcdFields fullField; /**< Extract full filed parameters */
83478 + } extractByHdrType;
83479 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
83480 + struct {
83481 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
83482 + e_FmPcdAction action; /**< Relevant for CC Only */
83483 + uint16_t icIndxMask; /**< Relevant only for CC when
83484 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
83485 + Note that the number of bits that are set within
83486 + this mask must be log2 of the CC-node 'numOfKeys'.
83487 + Note that the mask cannot be set on the lower bits. */
83488 + uint8_t offset; /**< Byte offset */
83489 + uint8_t size; /**< Size in byte */
83490 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
83491 + };
83492 +} t_FmPcdExtractEntry;
83493 +
83494 +/**************************************************************************//**
83495 + @Description Parameters for defining masks for each extracted field in the key.
83496 +*//***************************************************************************/
83497 +typedef struct t_FmPcdKgExtractMask {
83498 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
83499 + uint8_t offset; /**< Byte offset */
83500 + uint8_t mask; /**< A byte mask (selected bits will be used) */
83501 +} t_FmPcdKgExtractMask;
83502 +
83503 +/**************************************************************************//**
83504 + @Description Parameters for defining default selection per groups of fields
83505 +*//***************************************************************************/
83506 +typedef struct t_FmPcdKgExtractDflt {
83507 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
83508 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
83509 +} t_FmPcdKgExtractDflt;
83510 +
83511 +/**************************************************************************//**
83512 + @Description Parameters for defining key extraction and hashing
83513 +*//***************************************************************************/
83514 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
83515 + uint32_t privateDflt0; /**< Scheme default register 0 */
83516 + uint32_t privateDflt1; /**< Scheme default register 1 */
83517 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
83518 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
83519 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
83520 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
83521 + /**< For each extraction used in this scheme, specify the required
83522 + default register to be used when header is not found.
83523 + types not specified in this array will get undefined value. */
83524 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
83525 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
83526 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
83527 + result. 0 means using the 24 LSB's, otherwise use the
83528 + 24 LSB's after shifting right.*/
83529 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
83530 + of queues for the key and hash functionality */
83531 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
83532 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
83533 + destination fields on all layers; If TRUE, driver will check that for
83534 + all layers, if SRC extraction is selected, DST extraction must also be
83535 + selected, and vice versa. */
83536 +} t_FmPcdKgKeyExtractAndHashParams;
83537 +
83538 +/**************************************************************************//**
83539 + @Description Parameters for defining a single FQID mask (extracted OR).
83540 +*//***************************************************************************/
83541 +typedef struct t_FmPcdKgExtractedOrParams {
83542 + e_FmPcdExtractType type; /**< Extraction type select */
83543 + union {
83544 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
83545 + e_NetHeaderType hdr;
83546 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
83547 + IP. Otherwise should be cleared.*/
83548 + bool ignoreProtocolValidation;
83549 + /**< continue extraction even if protocol is not recognized */
83550 + } extractByHdr; /**< Header to extract by */
83551 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
83552 + };
83553 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
83554 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
83555 + field not found */
83556 + uint8_t mask; /**< Extraction mask (specified bits are used) */
83557 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
83558 + the extracted byte; Assume byte is placed as the 8 MSB's in
83559 + a 32 bit word where the lower bits
83560 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
83561 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
83562 + extracted byte will effect the 8 LSB's of the FQID,
83563 + if bitOffsetInFqid=31 than the byte's MSB will effect
83564 + the FQID's LSB; 0 means - no effect on FQID;
83565 + Note that one, and only one of
83566 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
83567 + extracted byte must effect either FQID or Policer profile).*/
83568 + uint8_t bitOffsetInPlcrProfile;
83569 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
83570 + effect using the extracted byte; Assume byte is placed
83571 + as the 8 MSB's in a 16 bit word where the lower bits
83572 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
83573 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
83574 + than the extracted byte will effect the whole policer profile id,
83575 + if bitOffsetInFqid=15 than the byte's MSB will effect
83576 + the Policer Profile id's LSB;
83577 + 0 means - no effect on policer profile; Note that one, and only one of
83578 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
83579 + extracted byte must effect either FQID or Policer profile).*/
83580 +} t_FmPcdKgExtractedOrParams;
83581 +
83582 +/**************************************************************************//**
83583 + @Description Parameters for configuring a scheme counter
83584 +*//***************************************************************************/
83585 +typedef struct t_FmPcdKgSchemeCounter {
83586 + bool update; /**< FALSE to keep the current counter state
83587 + and continue from that point, TRUE to update/reset
83588 + the counter when the scheme is written. */
83589 + uint32_t value; /**< If update=TRUE, this value will be written into the
83590 + counter. clear this field to reset the counter. */
83591 +} t_FmPcdKgSchemeCounter;
83592 +
83593 +/**************************************************************************//**
83594 + @Description Parameters for configuring a policer profile for a KeyGen scheme
83595 + (when policer is the next engine after this scheme).
83596 +*//***************************************************************************/
83597 +typedef struct t_FmPcdKgPlcrProfile {
83598 + bool sharedProfile; /**< TRUE if this profile is shared between ports
83599 + (managed by master partition); Must not be TRUE
83600 + if profile is after Coarse Classification*/
83601 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
83602 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
83603 + together with fqidOffsetShift and numOfProfiles
83604 + parameters, to define a range of profiles from
83605 + which the KeyGen result will determine the
83606 + destination policer profile. */
83607 + union {
83608 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
83609 + should indicate the policer profile offset within the
83610 + port's policer profiles or shared window. */
83611 + struct {
83612 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
83613 + final FQID - without the FQID base). */
83614 + uint8_t fqidOffsetRelativeProfileIdBase;
83615 + /**< The base of the FMan Port's relative Storage-Profile ID;
83616 + this value will be "OR'ed" with the KeyGen create FQID
83617 + offset (i.e. not the final FQID - without the FQID base);
83618 + the final result should indicate the Storage-Profile offset
83619 + within the FMan Port's relative Storage-Profiles window/
83620 + (or the SHARED window depends on 'sharedProfile'). */
83621 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
83622 + } indirectProfile; /**< Indirect profile parameters */
83623 + } profileSelect; /**< Direct/indirect profile selection and parameters */
83624 +} t_FmPcdKgPlcrProfile;
83625 +
83626 +#if (DPAA_VERSION >= 11)
83627 +/**************************************************************************//**
83628 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
83629 +*//***************************************************************************/
83630 +typedef struct t_FmPcdKgStorageProfile {
83631 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
83632 + profile id;
83633 + If FALSE, fqidOffsetRelativeProfileIdBase is used
83634 + together with fqidOffsetShift and numOfProfiles
83635 + parameters to define a range of profiles from which
83636 + the KeyGen result will determine the destination
83637 + storage profile. */
83638 + union {
83639 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
83640 + should indicate the storage profile offset within the
83641 + port's storage profiles window. */
83642 + struct {
83643 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
83644 + final FQID - without the FQID base). */
83645 + uint8_t fqidOffsetRelativeProfileIdBase;
83646 + /**< The base of the FMan Port's relative Storage-Profile ID;
83647 + this value will be "OR'ed" with the KeyGen create FQID
83648 + offset (i.e. not the final FQID - without the FQID base);
83649 + the final result should indicate the Storage-Profile offset
83650 + within the FMan Port's relative Storage-Profiles window. */
83651 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
83652 + } indirectProfile; /**< Indirect profile parameters. */
83653 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
83654 +} t_FmPcdKgStorageProfile;
83655 +#endif /* (DPAA_VERSION >= 11) */
83656 +
83657 +/**************************************************************************//**
83658 + @Description Parameters for defining CC as the next engine after KeyGen
83659 +*//***************************************************************************/
83660 +typedef struct t_FmPcdKgCc {
83661 + t_Handle h_CcTree; /**< A handle to a CC Tree */
83662 + uint8_t grpId; /**< CC group id within the CC tree */
83663 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
83664 + policing is required. */
83665 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
83666 + selected profile is the one set at port initialization. */
83667 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
83668 + bypassPlcrProfileGeneration = FALSE */
83669 +} t_FmPcdKgCc;
83670 +
83671 +/**************************************************************************//**
83672 + @Description Parameters for defining initializing a KeyGen scheme
83673 +*//***************************************************************************/
83674 +typedef struct t_FmPcdKgSchemeParams {
83675 + bool modify; /**< TRUE to change an existing scheme */
83676 + union
83677 + {
83678 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
83679 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
83680 + } id;
83681 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
83682 + for match vector; KeyGen will ignore it when matching */
83683 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
83684 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
83685 + by FM_PCD_NetEnvCharacteristicsSet() */
83686 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
83687 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
83688 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
83689 + } netEnvParams;
83690 + bool useHash; /**< use the KeyGen Hash functionality */
83691 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
83692 + /**< used only if useHash = TRUE */
83693 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
83694 + In such a case FQID after KeyGen will be the default FQID
83695 + defined for the relevant port, or the FQID defined by CC
83696 + in cases where CC was the previous engine. */
83697 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
83698 + If hash is used and an even distribution is expected
83699 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
83700 + hashDistributionNumOfFqids. */
83701 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
83702 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
83703 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
83704 + registers are shared between qidMasks
83705 + functionality and some of the extraction
83706 + actions; Normally only some will be used
83707 + for qidMask. Driver will return error if
83708 + resource is full at initialization time. */
83709 +
83710 +#if (DPAA_VERSION >= 11)
83711 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
83712 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
83713 +#endif /* (DPAA_VERSION >= 11) */
83714 +
83715 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
83716 + union { /**< depends on nextEngine */
83717 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
83718 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
83719 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
83720 + } kgNextEngineParams;
83721 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
83722 + the scheme counter */
83723 +} t_FmPcdKgSchemeParams;
83724 +
83725 +/**************************************************************************//**
83726 + @Collection Definitions for CC statistics
83727 +*//***************************************************************************/
83728 +#if (DPAA_VERSION >= 11)
83729 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
83730 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
83731 +#endif /* (DPAA_VERSION >= 11) */
83732 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
83733 +/* @} */
83734 +
83735 +/**************************************************************************//**
83736 + @Description Parameters for defining CC as the next engine after a CC node.
83737 +*//***************************************************************************/
83738 +typedef struct t_FmPcdCcNextCcParams {
83739 + t_Handle h_CcNode; /**< A handle of the next CC node */
83740 +} t_FmPcdCcNextCcParams;
83741 +
83742 +#if (DPAA_VERSION >= 11)
83743 +/**************************************************************************//**
83744 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
83745 +*//***************************************************************************/
83746 +typedef struct t_FmPcdCcNextFrParams {
83747 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
83748 +} t_FmPcdCcNextFrParams;
83749 +#endif /* (DPAA_VERSION >= 11) */
83750 +
83751 +/**************************************************************************//**
83752 + @Description Parameters for defining Policer as the next engine after a CC node.
83753 +*//***************************************************************************/
83754 +typedef struct t_FmPcdCcNextPlcrParams {
83755 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
83756 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
83757 + TRUE if this profile is shared between ports */
83758 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
83759 + (otherwise profile id is taken from KeyGen);
83760 + This parameter should indicate the policer
83761 + profile offset within the port's
83762 + policer profiles or from SHARED window.*/
83763 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
83764 + FQID for enqueuing the frame;
83765 + In earlier chips if policer next engine is KEYGEN,
83766 + this parameter can be 0, because the KEYGEN
83767 + always decides the enqueue FQID.*/
83768 +#if (DPAA_VERSION >= 11)
83769 + uint8_t newRelativeStorageProfileId;
83770 + /**< Indicates the relative storage profile offset within
83771 + the port's storage profiles window;
83772 + Relevant only if the port was configured with VSP. */
83773 +#endif /* (DPAA_VERSION >= 11) */
83774 +} t_FmPcdCcNextPlcrParams;
83775 +
83776 +/**************************************************************************//**
83777 + @Description Parameters for defining enqueue as the next action after a CC node.
83778 +*//***************************************************************************/
83779 +typedef struct t_FmPcdCcNextEnqueueParams {
83780 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
83781 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
83782 + relevant if action = e_FM_PCD_ENQ_FRAME */
83783 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
83784 + (otherwise FQID is taken from KeyGen),
83785 + relevant if action = e_FM_PCD_ENQ_FRAME */
83786 +#if (DPAA_VERSION >= 11)
83787 + uint8_t newRelativeStorageProfileId;
83788 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
83789 + storage profile offset within the port's storage profiles
83790 + window; Relevant only if the port was configured with VSP. */
83791 +#endif /* (DPAA_VERSION >= 11) */
83792 +} t_FmPcdCcNextEnqueueParams;
83793 +
83794 +/**************************************************************************//**
83795 + @Description Parameters for defining KeyGen as the next engine after a CC node.
83796 +*//***************************************************************************/
83797 +typedef struct t_FmPcdCcNextKgParams {
83798 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
83799 + Note - this parameters irrelevant for earlier chips */
83800 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
83801 + (otherwise FQID is taken from KeyGen),
83802 + Note - this parameters irrelevant for earlier chips */
83803 +#if (DPAA_VERSION >= 11)
83804 + uint8_t newRelativeStorageProfileId;
83805 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
83806 + storage profile offset within the port's storage profiles
83807 + window; Relevant only if the port was configured with VSP. */
83808 +#endif /* (DPAA_VERSION >= 11) */
83809 +
83810 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
83811 +} t_FmPcdCcNextKgParams;
83812 +
83813 +/**************************************************************************//**
83814 + @Description Parameters for defining the next engine after a CC node.
83815 +*//***************************************************************************/
83816 +typedef struct t_FmPcdCcNextEngineParams {
83817 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
83818 + according to nextEngine definition */
83819 + union {
83820 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
83821 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
83822 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
83823 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
83824 +#if (DPAA_VERSION >= 11)
83825 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
83826 +#endif /* (DPAA_VERSION >= 11) */
83827 + } params; /**< union used for all the next-engine parameters options */
83828 +
83829 + t_Handle h_Manip; /**< Handle to Manipulation object.
83830 + Relevant if next engine is of type result
83831 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
83832 +
83833 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
83834 + for each frame passing through this
83835 + Coarse Classification entry. */
83836 +} t_FmPcdCcNextEngineParams;
83837 +
83838 +/**************************************************************************//**
83839 + @Description Parameters for defining a single CC key
83840 +*//***************************************************************************/
83841 +typedef struct t_FmPcdCcKeyParams {
83842 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
83843 + pointer to the key of the size defined in keySize */
83844 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
83845 + pointer to the Mask per key of the size defined
83846 + in keySize. p_Key and p_Mask (if defined) has to be
83847 + of the same size defined in the keySize;
83848 + NOTE that if this value is equal for all entries whithin
83849 + this table, the driver will automatically use global-mask
83850 + (i.e. one common mask for all entries) instead of private
83851 + one; that is done in order to spare some memory and for
83852 + better performance. */
83853 + t_FmPcdCcNextEngineParams ccNextEngineParams;
83854 + /**< parameters for the next for the defined Key in
83855 + the p_Key */
83856 +} t_FmPcdCcKeyParams;
83857 +
83858 +/**************************************************************************//**
83859 + @Description Parameters for defining CC keys parameters
83860 + The driver supports two methods for CC node allocation: dynamic and static.
83861 + Static mode was created in order to prevent runtime alloc/free
83862 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
83863 + the driver automatically allocates the memory according to
83864 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
83865 + size that may be used for this CC-Node taking into consideration
83866 + 'maskSupport' and 'statisticsMode' parameters.
83867 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
83868 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
83869 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
83870 + all required structures are allocated according to 'numOfKeys'
83871 + parameter. During runtime modification, these structures are
83872 + re-allocated according to the updated number of keys.
83873 +
83874 + Please note that 'action' and 'icIndxMask' mentioned in the
83875 + specific parameter explanations are passed in the extraction
83876 + parameters of the node (fields of extractCcParams.extractNonHdr).
83877 +*//***************************************************************************/
83878 +typedef struct t_KeysParams {
83879 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
83880 + A value of zero may be used for dynamic memory allocation. */
83881 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
83882 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
83883 + Should be TRUE to reserve table memory for key masks, even if
83884 + initial keys do not contain masks, or if the node was initialized
83885 + as 'empty' (without keys); this will allow user to add keys with
83886 + masks at runtime.
83887 + NOTE that if user want to use only global-masks (i.e. one common mask
83888 + for all the entries within this table, this parameter should set to 'FALSE'. */
83889 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
83890 + To enable statistics gathering, statistics should be enabled per
83891 + every key, using 'statisticsEn' in next engine parameters structure
83892 + of that key;
83893 + If 'maxNumOfKeys' is set, all required structures will be
83894 + preallocated for all keys. */
83895 +#if (DPAA_VERSION >= 11)
83896 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
83897 + /**< Relevant only for 'RMON' statistics mode
83898 + (this feature is supported only on B4860 device);
83899 + Holds a list of programmable thresholds - for each received frame,
83900 + its length in bytes is examined against these range thresholds and
83901 + the appropriate counter is incremented by 1 - for example, to belong
83902 + to range i, the following should hold:
83903 + range i-1 threshold < frame length <= range i threshold
83904 + Each range threshold must be larger then its preceding range
83905 + threshold, and last range threshold must be 0xFFFF. */
83906 +#endif /* (DPAA_VERSION >= 11) */
83907 + uint16_t numOfKeys; /**< Number of initial keys;
83908 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
83909 + this field should be power-of-2 of the number of bits that are
83910 + set in 'icIndxMask'. */
83911 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
83912 + to be the standard size of the selected key; For other extraction
83913 + types, 'keySize' has to be as size of extraction; When 'action' =
83914 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
83915 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
83916 + /**< An array with 'numOfKeys' entries, each entry specifies the
83917 + corresponding key parameters;
83918 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
83919 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
83920 + for the 'miss' entry. */
83921 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
83922 + /**< Parameters for defining the next engine when a key is not matched;
83923 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
83924 +} t_KeysParams;
83925 +
83926 +
83927 +/**************************************************************************//**
83928 + @Description Parameters for defining a CC node
83929 +*//***************************************************************************/
83930 +typedef struct t_FmPcdCcNodeParams {
83931 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
83932 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
83933 +} t_FmPcdCcNodeParams;
83934 +
83935 +/**************************************************************************//**
83936 + @Description Parameters for defining a hash table
83937 +*//***************************************************************************/
83938 +typedef struct t_FmPcdHashTableParams {
83939 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
83940 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
83941 + requested statistics mode will be allocated according to maxNumOfKeys. */
83942 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
83943 + that leads to this hash-table. */
83944 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
83945 + The number-of-sets for this hash will be calculated
83946 + as (2^(number of bits set in 'hashResMask'));
83947 + The 4 lower bits must be cleared. */
83948 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
83949 + 2-bytes to be used as hash index. */
83950 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
83951 +
83952 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
83953 +
83954 +} t_FmPcdHashTableParams;
83955 +
83956 +/**************************************************************************//**
83957 + @Description Parameters for defining a CC tree group.
83958 +
83959 + This structure defines a CC group in terms of NetEnv units
83960 + and the action to be taken in each case. The unitIds list must
83961 + be given in order from low to high indices.
83962 +
83963 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
83964 + structures where each defines the next action to be taken for
83965 + each units combination. for example:
83966 + numOfDistinctionUnits = 2
83967 + unitIds = {1,3}
83968 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
83969 + unit 1 - not found; unit 3 - not found;
83970 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
83971 + unit 1 - not found; unit 3 - found;
83972 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
83973 + unit 1 - found; unit 3 - not found;
83974 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
83975 + unit 1 - found; unit 3 - found;
83976 +*//***************************************************************************/
83977 +typedef struct t_FmPcdCcGrpParams {
83978 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
83979 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
83980 + /**< Indices of the units as defined in
83981 + FM_PCD_NetEnvCharacteristicsSet() */
83982 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
83983 + /**< Maximum entries per group is 16 */
83984 +} t_FmPcdCcGrpParams;
83985 +
83986 +/**************************************************************************//**
83987 + @Description Parameters for defining CC tree groups
83988 +*//***************************************************************************/
83989 +typedef struct t_FmPcdCcTreeParams {
83990 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
83991 + by FM_PCD_NetEnvCharacteristicsSet() */
83992 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
83993 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
83994 + /**< Parameters for each group. */
83995 +} t_FmPcdCcTreeParams;
83996 +
83997 +
83998 +/**************************************************************************//**
83999 + @Description CC key statistics structure
84000 +*//***************************************************************************/
84001 +typedef struct t_FmPcdCcKeyStatistics {
84002 + uint32_t byteCount; /**< This counter reflects byte count of frames that
84003 + were matched by this key. */
84004 + uint32_t frameCount; /**< This counter reflects count of frames that
84005 + were matched by this key. */
84006 +#if (DPAA_VERSION >= 11)
84007 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
84008 + /**< These counters reflect how many frames matched
84009 + this key in 'RMON' statistics mode:
84010 + Each counter holds the number of frames of a
84011 + specific frames length range, according to the
84012 + ranges provided at initialization. */
84013 +#endif /* (DPAA_VERSION >= 11) */
84014 +} t_FmPcdCcKeyStatistics;
84015 +
84016 +/**************************************************************************//**
84017 + @Description Parameters for defining policer byte rate
84018 +*//***************************************************************************/
84019 +typedef struct t_FmPcdPlcrByteRateModeParams {
84020 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
84021 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
84022 + e_FM_PCD_PLCR_FULL_FRM_LEN */
84023 +} t_FmPcdPlcrByteRateModeParams;
84024 +
84025 +/**************************************************************************//**
84026 + @Description Parameters for defining the policer profile (based on
84027 + RFC-2698 or RFC-4115 attributes).
84028 +*//***************************************************************************/
84029 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
84030 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
84031 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
84032 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
84033 + uint32_t committedBurstSize; /**< Bytes/Packets */
84034 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
84035 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
84036 +} t_FmPcdPlcrNonPassthroughAlgParams;
84037 +
84038 +/**************************************************************************//**
84039 + @Description Parameters for defining the next engine after policer
84040 +*//***************************************************************************/
84041 +typedef union u_FmPcdPlcrNextEngineParams {
84042 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
84043 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
84044 + is Policer, must be a SHARED profile */
84045 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
84046 +} u_FmPcdPlcrNextEngineParams;
84047 +
84048 +/**************************************************************************//**
84049 + @Description Parameters for defining the policer profile entry
84050 +*//***************************************************************************/
84051 +typedef struct t_FmPcdPlcrProfileParams {
84052 + bool modify; /**< TRUE to change an existing profile */
84053 + union {
84054 + struct {
84055 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
84056 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
84057 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
84058 + } newParams; /**< use it when modify = FALSE */
84059 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
84060 + } id;
84061 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
84062 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
84063 +
84064 + union {
84065 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
84066 + any incoming packet with the default value. */
84067 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
84068 + pre-color value of 2'b11. */
84069 + } color;
84070 +
84071 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
84072 +
84073 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
84074 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
84075 +
84076 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
84077 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
84078 +
84079 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
84080 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
84081 +
84082 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
84083 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
84084 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
84085 +} t_FmPcdPlcrProfileParams;
84086 +
84087 +/**************************************************************************//**
84088 + @Description Parameters for selecting a location for requested manipulation
84089 +*//***************************************************************************/
84090 +typedef struct t_FmManipHdrInfo {
84091 + e_NetHeaderType hdr; /**< Header selection */
84092 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
84093 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
84094 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
84095 +} t_FmManipHdrInfo;
84096 +
84097 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84098 +/**************************************************************************//**
84099 + @Description Parameters for defining an insertion manipulation
84100 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
84101 +*//***************************************************************************/
84102 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
84103 + uint8_t size; /**< Size of insert template to the start of the frame. */
84104 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
84105 + /**< Array of the insertion template. */
84106 +
84107 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
84108 + struct {
84109 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
84110 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
84111 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
84112 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
84113 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
84114 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
84115 + 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.*/
84116 + struct {
84117 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
84118 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
84119 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
84120 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
84121 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
84122 +
84123 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
84124 + struct {
84125 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
84126 + VPri only 3 bits, it has to be adjusted to the right*/
84127 + } modifyOuterVlanParams;
84128 +} t_FmPcdManipHdrInsrtByTemplateParams;
84129 +
84130 +/**************************************************************************//**
84131 + @Description Parameters for defining CAPWAP fragmentation
84132 +*//***************************************************************************/
84133 +typedef struct t_CapwapFragmentationParams {
84134 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
84135 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
84136 + and all other fragments exclude the CAPWAP options field,
84137 + FALSE - all fragments include CAPWAP header options field. */
84138 +} t_CapwapFragmentationParams;
84139 +
84140 +/**************************************************************************//**
84141 + @Description Parameters for defining CAPWAP reassembly
84142 +*//***************************************************************************/
84143 +typedef struct t_CapwapReassemblyParams {
84144 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
84145 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
84146 + maxNumFramesInProcess has to be in the range of 4 - 512,
84147 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
84148 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
84149 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
84150 + and all processed fragments will be enqueued with error indication;
84151 + If FALSE, only duplicated fragments will be enqueued with error indication. */
84152 +
84153 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
84154 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
84155 + uint32_t timeoutRoutineRequestTime;
84156 + /**< Represents the time interval in microseconds between consecutive
84157 + timeout routine requests It has to be power of 2. */
84158 + uint32_t timeoutThresholdForReassmProcess;
84159 + /**< Time interval (microseconds) for marking frames in process as too old;
84160 + Frames in process are those for which at least one fragment was received
84161 + but not all fragments. */
84162 +
84163 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
84164 +} t_CapwapReassemblyParams;
84165 +
84166 +/**************************************************************************//**
84167 + @Description Parameters for defining fragmentation/reassembly manipulation
84168 +*//***************************************************************************/
84169 +typedef struct t_FmPcdManipFragOrReasmParams {
84170 + bool frag; /**< TRUE if using the structure for fragmentation,
84171 + otherwise this structure is used for reassembly */
84172 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
84173 + Same LIODN number is used for these buffers as for
84174 + the received frames buffers, so buffers of this pool
84175 + need to be allocated in the same memory area as the
84176 + received buffers. If the received buffers arrive
84177 + from different sources, the Scatter/Gather BP id
84178 + should be mutual to all these sources. */
84179 + e_NetHeaderType hdr; /**< Header selection */
84180 + union {
84181 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
84182 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
84183 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
84184 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
84185 + } u;
84186 +} t_FmPcdManipFragOrReasmParams;
84187 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84188 +
84189 +
84190 +/**************************************************************************//**
84191 + @Description Parameters for defining header removal by header type
84192 +*//***************************************************************************/
84193 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
84194 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
84195 + union {
84196 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84197 + struct {
84198 + bool include; /**< If FALSE, remove until the specified header (not including the header);
84199 + If TRUE, remove also the specified header. */
84200 + t_FmManipHdrInfo hdrInfo;
84201 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
84202 +#endif /* (DPAA_VERSION >= 11) || ... */
84203 +#if (DPAA_VERSION >= 11)
84204 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
84205 +#endif /* (DPAA_VERSION >= 11) */
84206 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
84207 + Defines which L2 headers to remove. */
84208 + } u;
84209 +} t_FmPcdManipHdrRmvByHdrParams;
84210 +
84211 +/**************************************************************************//**
84212 + @Description Parameters for configuring IP fragmentation manipulation
84213 +
84214 + Restrictions:
84215 + - IP Fragmentation output fragments must not be forwarded to application directly.
84216 + - Maximum number of fragments per frame is 16.
84217 + - Fragmentation of IP fragments is not supported.
84218 + - IPv4 packets containing header Option fields are fragmented by copying all option
84219 + fields to each fragment, regardless of the copy bit value.
84220 + - Transmit confirmation is not supported.
84221 + - Fragmentation after SEC can't handle S/G frames.
84222 + - Fragmentation nodes must be set as the last PCD action (i.e. the
84223 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
84224 + - Only BMan buffers shall be used for frames to be fragmented.
84225 + - IPF does not support VSP. Therefore, on the same port where we have IPF
84226 + we cannot support VSP.
84227 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
84228 + does not support VSP. Therefore, on the same port where we have IPF we
84229 + cannot support VSP.
84230 +*//***************************************************************************/
84231 +typedef struct t_FmPcdManipFragIpParams {
84232 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
84233 + IP fragmentation will be executed.*/
84234 +#if (DPAA_VERSION == 10)
84235 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
84236 +#endif /* (DPAA_VERSION == 10) */
84237 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
84238 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
84239 + received frame's buffer. */
84240 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
84241 + This parameters is relevant when 'sgBpidEn=TRUE';
84242 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
84243 + of this pool need to be allocated in the same memory area as the received buffers.
84244 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
84245 + mutual to all these sources. */
84246 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
84247 + than MTU and its DF bit is set, then this field will
84248 + determine the action to be taken.*/
84249 +} t_FmPcdManipFragIpParams;
84250 +
84251 +/**************************************************************************//**
84252 + @Description Parameters for configuring IP reassembly manipulation.
84253 +
84254 + This is a common structure for both IPv4 and IPv6 reassembly
84255 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
84256 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
84257 +
84258 + Restrictions:
84259 + - Application must define at least one scheme to catch the reassembled frames.
84260 + - Maximum number of fragments per frame is 16.
84261 + - Reassembly of IPv4 fragments containing Option fields is supported.
84262 +
84263 +*//***************************************************************************/
84264 +typedef struct t_FmPcdManipReassemIpParams {
84265 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
84266 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
84267 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
84268 + NOTE: The following comment is relevant only for FMAN v2 devices:
84269 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
84270 + the user schemes id to ensure that the reassembly schemes will be first match;
84271 + Rest schemes, if defined, should have higher relative scheme ID. */
84272 +#if (DPAA_VERSION >= 11)
84273 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
84274 + profile than the opening fragment (Non-Consistent-SP state)
84275 + then one of two possible scenarios occurs:
84276 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
84277 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
84278 +#else
84279 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
84280 +#endif /* (DPAA_VERSION >= 11) */
84281 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
84282 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
84283 + uint16_t minFragSize[2]; /**< Minimum fragment size:
84284 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
84285 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
84286 + /**< Number of frames per hash entry needed for reassembly process:
84287 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
84288 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
84289 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
84290 + Must be power of 2;
84291 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
84292 + maxNumFramesInProcess has to be in the range of 4 - 512;
84293 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
84294 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
84295 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
84296 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
84297 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
84298 + uint32_t timeoutThresholdForReassmProcess;
84299 + /**< Represents the time interval in microseconds which defines
84300 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
84301 +} t_FmPcdManipReassemIpParams;
84302 +
84303 +/**************************************************************************//**
84304 + @Description structure for defining IPSEC manipulation
84305 +*//***************************************************************************/
84306 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
84307 + bool decryption; /**< TRUE if being used in decryption direction;
84308 + FALSE if being used in encryption direction. */
84309 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
84310 + (direction depends on the 'decryption' field). */
84311 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
84312 + (direction depends on the 'decryption' field). */
84313 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
84314 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
84315 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
84316 + It is specifies the length of the outer IP header that was configured in the
84317 + corresponding SA. */
84318 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
84319 + The value must be a multiplication of 16 */
84320 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
84321 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
84322 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
84323 +} t_FmPcdManipSpecialOffloadIPSecParams;
84324 +
84325 +#if (DPAA_VERSION >= 11)
84326 +/**************************************************************************//**
84327 + @Description Parameters for configuring CAPWAP fragmentation manipulation
84328 +
84329 + Restrictions:
84330 + - Maximum number of fragments per frame is 16.
84331 + - Transmit confirmation is not supported.
84332 + - Fragmentation nodes must be set as the last PCD action (i.e. the
84333 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
84334 + - Only BMan buffers shall be used for frames to be fragmented.
84335 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
84336 + does not support VSP. Therefore, on the same port where we have IPF we
84337 + cannot support VSP.
84338 +*//***************************************************************************/
84339 +typedef struct t_FmPcdManipFragCapwapParams {
84340 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
84341 + CAPWAP fragmentation will be executed.*/
84342 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
84343 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
84344 + received frame's buffer. */
84345 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
84346 + This parameters is relevant when 'sgBpidEn=TRUE';
84347 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
84348 + of this pool need to be allocated in the same memory area as the received buffers.
84349 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
84350 + mutual to all these sources. */
84351 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
84352 + When this mode is enabled then only the first fragment include the CAPWAP header options
84353 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
84354 + options field (CAPWAP header is updated accordingly).*/
84355 +} t_FmPcdManipFragCapwapParams;
84356 +
84357 +/**************************************************************************//**
84358 + @Description Parameters for configuring CAPWAP reassembly manipulation.
84359 +
84360 + Restrictions:
84361 + - Application must define one scheme to catch the reassembled frames.
84362 + - Maximum number of fragments per frame is 16.
84363 +
84364 +*//***************************************************************************/
84365 +typedef struct t_FmPcdManipReassemCapwapParams {
84366 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
84367 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
84368 + Rest schemes, if defined, should have higher relative scheme ID. */
84369 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
84370 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
84371 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
84372 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
84373 + considered as a valid length;
84374 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
84375 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
84376 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
84377 + /**< Number of frames per hash entry needed for reassembly process */
84378 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
84379 + Must be power of 2;
84380 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
84381 + maxNumFramesInProcess has to be in the range of 4 - 512;
84382 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
84383 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
84384 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
84385 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
84386 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
84387 + uint32_t timeoutThresholdForReassmProcess;
84388 + /**< Represents the time interval in microseconds which defines
84389 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
84390 +} t_FmPcdManipReassemCapwapParams;
84391 +
84392 +/**************************************************************************//**
84393 + @Description structure for defining CAPWAP manipulation
84394 +*//***************************************************************************/
84395 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
84396 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
84397 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
84398 +} t_FmPcdManipSpecialOffloadCapwapParams;
84399 +
84400 +#endif /* (DPAA_VERSION >= 11) */
84401 +
84402 +
84403 +/**************************************************************************//**
84404 + @Description Parameters for defining special offload manipulation
84405 +*//***************************************************************************/
84406 +typedef struct t_FmPcdManipSpecialOffloadParams {
84407 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
84408 + union
84409 + {
84410 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
84411 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
84412 +#if (DPAA_VERSION >= 11)
84413 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
84414 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
84415 +#endif /* (DPAA_VERSION >= 11) */
84416 + } u;
84417 +} t_FmPcdManipSpecialOffloadParams;
84418 +
84419 +/**************************************************************************//**
84420 + @Description Parameters for defining insertion manipulation
84421 +*//***************************************************************************/
84422 +typedef struct t_FmPcdManipHdrInsrt {
84423 + uint8_t size; /**< size of inserted section */
84424 + uint8_t *p_Data; /**< data to be inserted */
84425 +} t_FmPcdManipHdrInsrt;
84426 +
84427 +
84428 +/**************************************************************************//**
84429 + @Description Parameters for defining generic removal manipulation
84430 +*//***************************************************************************/
84431 +typedef struct t_FmPcdManipHdrRmvGenericParams {
84432 + uint8_t offset; /**< Offset from beginning of header to the start
84433 + location of the removal */
84434 + uint8_t size; /**< Size of removed section */
84435 +} t_FmPcdManipHdrRmvGenericParams;
84436 +
84437 +/**************************************************************************//**
84438 + @Description Parameters for defining generic insertion manipulation
84439 +*//***************************************************************************/
84440 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
84441 + uint8_t offset; /**< Offset from beginning of header to the start
84442 + location of the insertion */
84443 + uint8_t size; /**< Size of inserted section */
84444 + bool replace; /**< TRUE to override (replace) existing data at
84445 + 'offset', FALSE to insert */
84446 + uint8_t *p_Data; /**< Pointer to data to be inserted */
84447 +} t_FmPcdManipHdrInsrtGenericParams;
84448 +
84449 +/**************************************************************************//**
84450 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
84451 +*//***************************************************************************/
84452 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
84453 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
84454 + /**< A table of VPri values for each DSCP value;
84455 + The index is the DSCP value (0-0x3F) and the
84456 + value is the corresponding VPRI (0-15). */
84457 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
84458 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
84459 + this field is the Q Tag default value if the
84460 + IP header is not found. */
84461 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
84462 +
84463 +/**************************************************************************//**
84464 + @Description Parameters for defining header manipulation VLAN fields updates
84465 +*//***************************************************************************/
84466 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
84467 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
84468 + union {
84469 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
84470 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
84471 + is the new VLAN pri. */
84472 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
84473 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
84474 + } u;
84475 +} t_FmPcdManipHdrFieldUpdateVlan;
84476 +
84477 +/**************************************************************************//**
84478 + @Description Parameters for defining header manipulation IPV4 fields updates
84479 +*//***************************************************************************/
84480 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
84481 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
84482 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
84483 + HDR_MANIP_IPV4_TOS */
84484 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
84485 + contains HDR_MANIP_IPV4_ID */
84486 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
84487 + contains HDR_MANIP_IPV4_SRC */
84488 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
84489 + contains HDR_MANIP_IPV4_DST */
84490 +} t_FmPcdManipHdrFieldUpdateIpv4;
84491 +
84492 +/**************************************************************************//**
84493 + @Description Parameters for defining header manipulation IPV6 fields updates
84494 +*//***************************************************************************/
84495 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
84496 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
84497 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
84498 + HDR_MANIP_IPV6_TC */
84499 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
84500 + /**< 16 byte new IP SRC; Relevant only if validUpdates
84501 + contains HDR_MANIP_IPV6_SRC */
84502 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
84503 + /**< 16 byte new IP DST; Relevant only if validUpdates
84504 + contains HDR_MANIP_IPV6_DST */
84505 +} t_FmPcdManipHdrFieldUpdateIpv6;
84506 +
84507 +/**************************************************************************//**
84508 + @Description Parameters for defining header manipulation TCP/UDP fields updates
84509 +*//***************************************************************************/
84510 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
84511 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
84512 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
84513 + contains HDR_MANIP_TCP_UDP_SRC */
84514 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
84515 + contains HDR_MANIP_TCP_UDP_DST */
84516 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
84517 +
84518 +/**************************************************************************//**
84519 + @Description Parameters for defining header manipulation fields updates
84520 +*//***************************************************************************/
84521 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
84522 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
84523 + union {
84524 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
84525 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
84526 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
84527 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
84528 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
84529 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
84530 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
84531 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
84532 + } u;
84533 +} t_FmPcdManipHdrFieldUpdateParams;
84534 +
84535 +
84536 +
84537 +/**************************************************************************//**
84538 + @Description Parameters for defining custom header manipulation for generic field replacement
84539 +*//***************************************************************************/
84540 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
84541 + uint8_t srcOffset; /**< Location of new data - Offset from
84542 + Parse Result (>= 16, srcOffset+size <= 32, ) */
84543 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
84544 + start of frame (dstOffset + size <= 256). */
84545 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
84546 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
84547 + replacement (1 - bit will be replaced);
84548 + Clear to use field as is. */
84549 + uint8_t maskOffset; /**< Relevant if mask != 0;
84550 + Mask offset within the replaces "size" */
84551 +} t_FmPcdManipHdrCustomGenFieldReplace;
84552 +
84553 +/**************************************************************************//**
84554 + @Description Parameters for defining custom header manipulation for IP replacement
84555 +*//***************************************************************************/
84556 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
84557 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
84558 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
84559 + bool updateIpv4Id; /**< Relevant when replaceType =
84560 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
84561 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
84562 + updateIpv4Id = TRUE */
84563 + uint8_t hdrSize; /**< The size of the new IP header */
84564 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
84565 + /**< The new IP header */
84566 +} t_FmPcdManipHdrCustomIpHdrReplace;
84567 +
84568 +/**************************************************************************//**
84569 + @Description Parameters for defining custom header manipulation
84570 +*//***************************************************************************/
84571 +typedef struct t_FmPcdManipHdrCustomParams {
84572 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
84573 + union {
84574 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
84575 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
84576 + } u;
84577 +} t_FmPcdManipHdrCustomParams;
84578 +
84579 +/**************************************************************************//**
84580 + @Description Parameters for defining specific L2 insertion manipulation
84581 +*//***************************************************************************/
84582 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
84583 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
84584 + bool update; /**< TRUE to update MPLS header */
84585 + uint8_t size; /**< size of inserted section */
84586 + uint8_t *p_Data; /**< data to be inserted */
84587 +} t_FmPcdManipHdrInsrtSpecificL2Params;
84588 +
84589 +#if (DPAA_VERSION >= 11)
84590 +/**************************************************************************//**
84591 + @Description Parameters for defining IP insertion manipulation
84592 +*//***************************************************************************/
84593 +typedef struct t_FmPcdManipHdrInsrtIpParams {
84594 + bool calcL4Checksum; /**< Calculate L4 checksum. */
84595 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
84596 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
84597 + the inserted header */
84598 + uint16_t id; /**< 16 bit New IP ID */
84599 + bool dontFragOverwrite;
84600 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
84601 + * This byte is configured to be overwritten when RPD is set. */
84602 + uint8_t lastDstOffset;
84603 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
84604 + * in order to calculate UDP checksum pseudo header;
84605 + * Otherwise set it to '0'. */
84606 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
84607 +} t_FmPcdManipHdrInsrtIpParams;
84608 +#endif /* (DPAA_VERSION >= 11) */
84609 +
84610 +/**************************************************************************//**
84611 + @Description Parameters for defining header insertion manipulation by header type
84612 +*//***************************************************************************/
84613 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
84614 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
84615 + union {
84616 +
84617 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
84618 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
84619 + Selects which L2 headers to insert */
84620 +#if (DPAA_VERSION >= 11)
84621 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
84622 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
84623 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
84624 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
84625 +#endif /* (DPAA_VERSION >= 11) */
84626 + } u;
84627 +} t_FmPcdManipHdrInsrtByHdrParams;
84628 +
84629 +/**************************************************************************//**
84630 + @Description Parameters for defining header insertion manipulation
84631 +*//***************************************************************************/
84632 +typedef struct t_FmPcdManipHdrInsrtParams {
84633 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
84634 + union {
84635 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
84636 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
84637 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
84638 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
84639 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84640 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
84641 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
84642 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84643 + } u;
84644 +} t_FmPcdManipHdrInsrtParams;
84645 +
84646 +/**************************************************************************//**
84647 + @Description Parameters for defining header removal manipulation
84648 +*//***************************************************************************/
84649 +typedef struct t_FmPcdManipHdrRmvParams {
84650 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
84651 + union {
84652 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
84653 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
84654 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
84655 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
84656 + } u;
84657 +} t_FmPcdManipHdrRmvParams;
84658 +
84659 +/**************************************************************************//**
84660 + @Description Parameters for defining header manipulation node
84661 +*//***************************************************************************/
84662 +typedef struct t_FmPcdManipHdrParams {
84663 + bool rmv; /**< TRUE, to define removal manipulation */
84664 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
84665 +
84666 + bool insrt; /**< TRUE, to define insertion manipulation */
84667 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
84668 +
84669 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
84670 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
84671 +
84672 + bool custom; /**< TRUE, to define custom manipulation */
84673 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
84674 +
84675 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
84676 + Restrictions:
84677 + 1. MUST be set if the next engine after the CC is not another CC node
84678 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
84679 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
84680 + also never pointed as h_NextManip of other manipulation nodes)
84681 + 2. MUST be set if the next engine after the CC is another CC node, and
84682 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
84683 +} t_FmPcdManipHdrParams;
84684 +
84685 +/**************************************************************************//**
84686 + @Description Parameters for defining fragmentation manipulation
84687 +*//***************************************************************************/
84688 +typedef struct t_FmPcdManipFragParams {
84689 + e_NetHeaderType hdr; /**< Header selection */
84690 + union {
84691 +#if (DPAA_VERSION >= 11)
84692 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
84693 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
84694 +#endif /* (DPAA_VERSION >= 11) */
84695 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
84696 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
84697 + } u;
84698 +} t_FmPcdManipFragParams;
84699 +
84700 +/**************************************************************************//**
84701 + @Description Parameters for defining reassembly manipulation
84702 +*//***************************************************************************/
84703 +typedef struct t_FmPcdManipReassemParams {
84704 + e_NetHeaderType hdr; /**< Header selection */
84705 + union {
84706 +#if (DPAA_VERSION >= 11)
84707 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
84708 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
84709 +#endif /* (DPAA_VERSION >= 11) */
84710 +
84711 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
84712 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
84713 + } u;
84714 +} t_FmPcdManipReassemParams;
84715 +
84716 +/**************************************************************************//**
84717 + @Description Parameters for defining a manipulation node
84718 +*//***************************************************************************/
84719 +typedef struct t_FmPcdManipParams {
84720 + e_FmPcdManipType type; /**< Selects type of manipulation node */
84721 + union{
84722 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
84723 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
84724 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
84725 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
84726 + } u;
84727 +
84728 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
84729 + Handle to another (previously defined) manipulation node;
84730 + Allows concatenation of manipulation actions;
84731 + This parameter is optional and may be NULL. */
84732 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84733 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
84734 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
84735 + relevant if fragOrReasm = TRUE */
84736 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84737 +} t_FmPcdManipParams;
84738 +
84739 +/**************************************************************************//**
84740 + @Description Structure for retrieving IP reassembly statistics
84741 +*//***************************************************************************/
84742 +typedef struct t_FmPcdManipReassemIpStats {
84743 + /* common counters for both IPv4 and IPv6 */
84744 + uint32_t timeout; /**< Counts the number of timeout occurrences */
84745 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
84746 + a Reassembly Frame Descriptor */
84747 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
84748 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
84749 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
84750 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
84751 +#if (DPAA_VERSION >= 11)
84752 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
84753 + successfully reassembled frames */
84754 +#endif /* (DPAA_VERSION >= 11) */
84755 + struct {
84756 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
84757 + uint32_t validFragments; /**< Counts the total number of valid fragments that
84758 + have been processed for all frames */
84759 + uint32_t processedFragments; /**< Counts the number of processed fragments
84760 + (valid and error fragments) for all frames */
84761 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
84762 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
84763 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
84764 + to access an IP-Reassembly Automatic Learning Hash set */
84765 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
84766 + exceeds 16 */
84767 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
84768 +} t_FmPcdManipReassemIpStats;
84769 +
84770 +/**************************************************************************//**
84771 + @Description Structure for retrieving IP fragmentation statistics
84772 +*//***************************************************************************/
84773 +typedef struct t_FmPcdManipFragIpStats {
84774 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
84775 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
84776 + uint32_t generatedFragments; /**< Number of fragments that were generated */
84777 +} t_FmPcdManipFragIpStats;
84778 +
84779 +#if (DPAA_VERSION >= 11)
84780 +/**************************************************************************//**
84781 + @Description Structure for retrieving CAPWAP reassembly statistics
84782 +*//***************************************************************************/
84783 +typedef struct t_FmPcdManipReassemCapwapStats {
84784 + uint32_t timeout; /**< Counts the number of timeout occurrences */
84785 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
84786 + a Reassembly Frame Descriptor */
84787 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
84788 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
84789 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
84790 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
84791 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
84792 + uint32_t validFragments; /**< Counts the total number of valid fragments that
84793 + have been processed for all frames */
84794 + uint32_t processedFragments; /**< Counts the number of processed fragments
84795 + (valid and error fragments) for all frames */
84796 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
84797 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
84798 + to access an Reassembly Automatic Learning Hash set */
84799 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
84800 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
84801 + exceeds 16 */
84802 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
84803 + length exceeds MaxReassembledFrameLength value */
84804 +} t_FmPcdManipReassemCapwapStats;
84805 +
84806 +/**************************************************************************//**
84807 + @Description Structure for retrieving CAPWAP fragmentation statistics
84808 +*//***************************************************************************/
84809 +typedef struct t_FmPcdManipFragCapwapStats {
84810 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
84811 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
84812 + uint32_t generatedFragments; /**< Number of fragments that were generated */
84813 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
84814 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
84815 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
84816 +} t_FmPcdManipFragCapwapStats;
84817 +#endif /* (DPAA_VERSION >= 11) */
84818 +
84819 +/**************************************************************************//**
84820 + @Description Structure for retrieving reassembly statistics
84821 +*//***************************************************************************/
84822 +typedef struct t_FmPcdManipReassemStats {
84823 + union {
84824 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
84825 +#if (DPAA_VERSION >= 11)
84826 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
84827 +#endif /* (DPAA_VERSION >= 11) */
84828 + } u;
84829 +} t_FmPcdManipReassemStats;
84830 +
84831 +/**************************************************************************//**
84832 + @Description Structure for retrieving fragmentation statistics
84833 +*//***************************************************************************/
84834 +typedef struct t_FmPcdManipFragStats {
84835 + union {
84836 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
84837 +#if (DPAA_VERSION >= 11)
84838 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
84839 +#endif /* (DPAA_VERSION >= 11) */
84840 + } u;
84841 +} t_FmPcdManipFragStats;
84842 +
84843 +/**************************************************************************//**
84844 + @Description Structure for selecting manipulation statistics
84845 +*//***************************************************************************/
84846 +typedef struct t_FmPcdManipStats {
84847 + union {
84848 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
84849 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
84850 + } u;
84851 +} t_FmPcdManipStats;
84852 +
84853 +#if (DPAA_VERSION >= 11)
84854 +/**************************************************************************//**
84855 + @Description Parameters for defining frame replicator group and its members
84856 +*//***************************************************************************/
84857 +typedef struct t_FmPcdFrmReplicGroupParams {
84858 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
84859 + Must be at least 2. */
84860 + uint8_t numOfEntries; /**< Number of members in the group;
84861 + Must be at least 1. */
84862 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
84863 + /**< Array of members' parameters */
84864 +} t_FmPcdFrmReplicGroupParams;
84865 +#endif /* (DPAA_VERSION >= 11) */
84866 +
84867 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84868 +/**************************************************************************//**
84869 + @Description structure for defining statistics node
84870 +*//***************************************************************************/
84871 +typedef struct t_FmPcdStatsParams {
84872 + e_FmPcdStatsType type; /**< type of statistics node */
84873 +} t_FmPcdStatsParams;
84874 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84875 +
84876 +/**************************************************************************//**
84877 + @Function FM_PCD_NetEnvCharacteristicsSet
84878 +
84879 + @Description Define a set of Network Environment Characteristics.
84880 +
84881 + When setting an environment it is important to understand its
84882 + application. It is not meant to describe the flows that will run
84883 + on the ports using this environment, but what the user means TO DO
84884 + with the PCD mechanisms in order to parse-classify-distribute those
84885 + frames.
84886 + By specifying a distinction unit, the user means it would use that option
84887 + for distinction between frames at either a KeyGen scheme or a coarse
84888 + classification action descriptor. Using interchangeable headers to define a
84889 + unit means that the user is indifferent to which of the interchangeable
84890 + headers is present in the frame, and wants the distinction to be based
84891 + on the presence of either one of them.
84892 +
84893 + Depending on context, there are limitations to the use of environments. A
84894 + port using the PCD functionality is bound to an environment. Some or even
84895 + all ports may share an environment but also an environment per port is
84896 + possible. When initializing a scheme, a classification plan group (see below),
84897 + or a coarse classification tree, one of the initialized environments must be
84898 + stated and related to. When a port is bound to a scheme, a classification
84899 + plan group, or a coarse classification tree, it MUST be bound to the same
84900 + environment.
84901 +
84902 + The different PCD modules, may relate (for flows definition) ONLY on
84903 + distinction units as defined by their environment. When initializing a
84904 + scheme for example, it may not choose to select IPV4 as a match for
84905 + recognizing flows unless it was defined in the relating environment. In
84906 + fact, to guide the user through the configuration of the PCD, each module's
84907 + characterization in terms of flows is not done using protocol names, but using
84908 + environment indexes.
84909 +
84910 + In terms of HW implementation, the list of distinction units sets the LCV vectors
84911 + and later used for match vector, classification plan vectors and coarse classification
84912 + indexing.
84913 +
84914 + @Param[in] h_FmPcd FM PCD module descriptor.
84915 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
84916 + the network environment.
84917 +
84918 + @Return A handle to the initialized object on success; NULL code otherwise.
84919 +
84920 + @Cautions Allowed only following FM_PCD_Init().
84921 +*//***************************************************************************/
84922 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
84923 +
84924 +/**************************************************************************//**
84925 + @Function FM_PCD_NetEnvCharacteristicsDelete
84926 +
84927 + @Description Deletes a set of Network Environment Characteristics.
84928 +
84929 + @Param[in] h_NetEnv A handle to the Network environment.
84930 +
84931 + @Return E_OK on success; Error code otherwise.
84932 +*//***************************************************************************/
84933 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
84934 +
84935 +/**************************************************************************//**
84936 + @Function FM_PCD_KgSchemeSet
84937 +
84938 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
84939 + This routine should be called for adding or modifying a scheme.
84940 + When a scheme needs modifying, the API requires that it will be
84941 + rewritten. In such a case 'modify' should be TRUE. If the
84942 + routine is called for a valid scheme and 'modify' is FALSE,
84943 + it will return error.
84944 +
84945 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
84946 + Otherwise NULL (ignored by driver).
84947 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
84948 +
84949 + @Return A handle to the initialized scheme on success; NULL code otherwise.
84950 + When used as "modify" (rather than for setting a new scheme),
84951 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
84952 + BUSY state.
84953 +
84954 + @Cautions Allowed only following FM_PCD_Init().
84955 +*//***************************************************************************/
84956 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
84957 + t_FmPcdKgSchemeParams *p_SchemeParams);
84958 +
84959 +/**************************************************************************//**
84960 + @Function FM_PCD_KgSchemeDelete
84961 +
84962 + @Description Deleting an initialized scheme.
84963 +
84964 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
84965 +
84966 + @Return E_OK on success; Error code otherwise.
84967 +
84968 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
84969 +*//***************************************************************************/
84970 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
84971 +
84972 +/**************************************************************************//**
84973 + @Function FM_PCD_KgSchemeGetCounter
84974 +
84975 + @Description Reads scheme packet counter.
84976 +
84977 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
84978 +
84979 + @Return Counter's current value.
84980 +
84981 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
84982 +*//***************************************************************************/
84983 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
84984 +
84985 +/**************************************************************************//**
84986 + @Function FM_PCD_KgSchemeSetCounter
84987 +
84988 + @Description Writes scheme packet counter.
84989 +
84990 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
84991 + @Param[in] value New scheme counter value - typically '0' for
84992 + resetting the counter.
84993 +
84994 + @Return E_OK on success; Error code otherwise.
84995 +
84996 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
84997 +*//***************************************************************************/
84998 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
84999 +
85000 +/**************************************************************************//**
85001 + @Function FM_PCD_PlcrProfileSet
85002 +
85003 + @Description Sets a profile entry in the policer profile table.
85004 + The routine overrides any existing value.
85005 +
85006 + @Param[in] h_FmPcd A handle to an FM PCD Module.
85007 + @Param[in] p_Profile A structure of parameters for defining a
85008 + policer profile entry.
85009 +
85010 + @Return A handle to the initialized object on success; NULL code otherwise.
85011 + When used as "modify" (rather than for setting a new profile),
85012 + p_Profile->id.h_Profile will return NULL if action fails due to profile
85013 + BUSY state.
85014 + @Cautions Allowed only following FM_PCD_Init().
85015 +*//***************************************************************************/
85016 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
85017 + t_FmPcdPlcrProfileParams *p_Profile);
85018 +
85019 +/**************************************************************************//**
85020 + @Function FM_PCD_PlcrProfileDelete
85021 +
85022 + @Description Delete a profile entry in the policer profile table.
85023 + The routine set entry to invalid.
85024 +
85025 + @Param[in] h_Profile A handle to the profile.
85026 +
85027 + @Return E_OK on success; Error code otherwise.
85028 +
85029 + @Cautions Allowed only following FM_PCD_Init().
85030 +*//***************************************************************************/
85031 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
85032 +
85033 +/**************************************************************************//**
85034 + @Function FM_PCD_PlcrProfileGetCounter
85035 +
85036 + @Description Sets an entry in the classification plan.
85037 + The routine overrides any existing value.
85038 +
85039 + @Param[in] h_Profile A handle to the profile.
85040 + @Param[in] counter Counter selector.
85041 +
85042 + @Return specific counter value.
85043 +
85044 + @Cautions Allowed only following FM_PCD_Init().
85045 +*//***************************************************************************/
85046 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
85047 + e_FmPcdPlcrProfileCounters counter);
85048 +
85049 +/**************************************************************************//**
85050 + @Function FM_PCD_PlcrProfileSetCounter
85051 +
85052 + @Description Sets an entry in the classification plan.
85053 + The routine overrides any existing value.
85054 +
85055 + @Param[in] h_Profile A handle to the profile.
85056 + @Param[in] counter Counter selector.
85057 + @Param[in] value value to set counter with.
85058 +
85059 + @Return E_OK on success; Error code otherwise.
85060 +
85061 + @Cautions Allowed only following FM_PCD_Init().
85062 +*//***************************************************************************/
85063 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
85064 + e_FmPcdPlcrProfileCounters counter,
85065 + uint32_t value);
85066 +
85067 +/**************************************************************************//**
85068 + @Function FM_PCD_CcRootBuild
85069 +
85070 + @Description This routine must be called to define a complete coarse
85071 + classification tree. This is the way to define coarse
85072 + classification to a certain flow - the KeyGen schemes
85073 + may point only to trees defined in this way.
85074 +
85075 + @Param[in] h_FmPcd FM PCD module descriptor.
85076 + @Param[in] p_Params A structure of parameters to define the tree.
85077 +
85078 + @Return A handle to the initialized object on success; NULL code otherwise.
85079 +
85080 + @Cautions Allowed only following FM_PCD_Init().
85081 +*//***************************************************************************/
85082 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
85083 + t_FmPcdCcTreeParams *p_Params);
85084 +
85085 +/**************************************************************************//**
85086 + @Function FM_PCD_CcRootDelete
85087 +
85088 + @Description Deleting an built tree.
85089 +
85090 + @Param[in] h_CcTree A handle to a CC tree.
85091 +
85092 + @Return E_OK on success; Error code otherwise.
85093 +
85094 + @Cautions Allowed only following FM_PCD_Init().
85095 +*//***************************************************************************/
85096 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
85097 +
85098 +/**************************************************************************//**
85099 + @Function FM_PCD_CcRootModifyNextEngine
85100 +
85101 + @Description Modify the Next Engine Parameters in the entry of the tree.
85102 +
85103 + @Param[in] h_CcTree A handle to the tree
85104 + @Param[in] grpId A Group index in the tree
85105 + @Param[in] index Entry index in the group defined by grpId
85106 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
85107 +
85108 + @Return E_OK on success; Error code otherwise.
85109 +
85110 + @Cautions Allowed only following FM_PCD_CcBuildTree().
85111 +*//***************************************************************************/
85112 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
85113 + uint8_t grpId,
85114 + uint8_t index,
85115 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85116 +
85117 +/**************************************************************************//**
85118 + @Function FM_PCD_MatchTableSet
85119 +
85120 + @Description This routine should be called for each CC (coarse classification)
85121 + node. The whole CC tree should be built bottom up so that each
85122 + node points to already defined nodes.
85123 +
85124 + @Param[in] h_FmPcd FM PCD module descriptor.
85125 + @Param[in] p_Param A structure of parameters defining the CC node
85126 +
85127 + @Return A handle to the initialized object on success; NULL code otherwise.
85128 +
85129 + @Cautions Allowed only following FM_PCD_Init().
85130 +*//***************************************************************************/
85131 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
85132 +
85133 +/**************************************************************************//**
85134 + @Function FM_PCD_MatchTableDelete
85135 +
85136 + @Description Deleting an built node.
85137 +
85138 + @Param[in] h_CcNode A handle to a CC node.
85139 +
85140 + @Return E_OK on success; Error code otherwise.
85141 +
85142 + @Cautions Allowed only following FM_PCD_Init().
85143 +*//***************************************************************************/
85144 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
85145 +
85146 +/**************************************************************************//**
85147 + @Function FM_PCD_MatchTableModifyMissNextEngine
85148 +
85149 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
85150 +
85151 + @Param[in] h_CcNode A handle to the node
85152 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
85153 +
85154 + @Return E_OK on success; Error code otherwise.
85155 +
85156 + @Cautions Allowed only following FM_PCD_MatchTableSet();
85157 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
85158 + When configuring nextEngine = e_FM_PCD_CC, note that
85159 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85160 + from the currently changed table.
85161 +
85162 +*//***************************************************************************/
85163 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
85164 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85165 +
85166 +/**************************************************************************//**
85167 + @Function FM_PCD_MatchTableRemoveKey
85168 +
85169 + @Description Remove the key (including next engine parameters of this key)
85170 + defined by the index of the relevant node.
85171 +
85172 + @Param[in] h_CcNode A handle to the node
85173 + @Param[in] keyIndex Key index for removing
85174 +
85175 + @Return E_OK on success; Error code otherwise.
85176 +
85177 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85178 + node and the nodes that lead to it.
85179 +*//***************************************************************************/
85180 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
85181 +
85182 +/**************************************************************************//**
85183 + @Function FM_PCD_MatchTableAddKey
85184 +
85185 + @Description Add the key (including next engine parameters of this key in the
85186 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
85187 + may be used by user that don't care about the position of the
85188 + key in the table - in that case, the key will be automatically
85189 + added by the driver in the last available entry.
85190 +
85191 + @Param[in] h_CcNode A handle to the node
85192 + @Param[in] keyIndex Key index for adding.
85193 + @Param[in] keySize Key size of added key
85194 + @Param[in] p_KeyParams A pointer to the parameters includes
85195 + new key with Next Engine Parameters
85196 +
85197 + @Return E_OK on success; Error code otherwise.
85198 +
85199 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85200 + node and the nodes that lead to it.
85201 +*//***************************************************************************/
85202 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
85203 + uint16_t keyIndex,
85204 + uint8_t keySize,
85205 + t_FmPcdCcKeyParams *p_KeyParams);
85206 +
85207 +/**************************************************************************//**
85208 + @Function FM_PCD_MatchTableModifyNextEngine
85209 +
85210 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
85211 +
85212 + @Param[in] h_CcNode A handle to the node
85213 + @Param[in] keyIndex Key index for Next Engine modifications
85214 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
85215 +
85216 + @Return E_OK on success; Error code otherwise.
85217 +
85218 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85219 + When configuring nextEngine = e_FM_PCD_CC, note that
85220 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85221 + from the currently changed table.
85222 +
85223 +*//***************************************************************************/
85224 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
85225 + uint16_t keyIndex,
85226 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85227 +
85228 +/**************************************************************************//**
85229 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
85230 +
85231 + @Description Modify the key and Next Engine Parameters of this key in the
85232 + index defined by the keyIndex.
85233 +
85234 + @Param[in] h_CcNode A handle to the node
85235 + @Param[in] keyIndex Key index for adding
85236 + @Param[in] keySize Key size of added key
85237 + @Param[in] p_KeyParams A pointer to the parameters includes
85238 + modified key and modified Next Engine Parameters
85239 +
85240 + @Return E_OK on success; Error code otherwise.
85241 +
85242 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85243 + node and the nodes that lead to it.
85244 + When configuring nextEngine = e_FM_PCD_CC, note that
85245 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85246 + from the currently changed table.
85247 +*//***************************************************************************/
85248 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
85249 + uint16_t keyIndex,
85250 + uint8_t keySize,
85251 + t_FmPcdCcKeyParams *p_KeyParams);
85252 +
85253 +/**************************************************************************//**
85254 + @Function FM_PCD_MatchTableModifyKey
85255 +
85256 + @Description Modify the key in the index defined by the keyIndex.
85257 +
85258 + @Param[in] h_CcNode A handle to the node
85259 + @Param[in] keyIndex Key index for adding
85260 + @Param[in] keySize Key size of added key
85261 + @Param[in] p_Key A pointer to the new key
85262 + @Param[in] p_Mask A pointer to the new mask if relevant,
85263 + otherwise pointer to NULL
85264 +
85265 + @Return E_OK on success; Error code otherwise.
85266 +
85267 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85268 + node and the nodes that lead to it.
85269 +*//***************************************************************************/
85270 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
85271 + uint16_t keyIndex,
85272 + uint8_t keySize,
85273 + uint8_t *p_Key,
85274 + uint8_t *p_Mask);
85275 +
85276 +/**************************************************************************//**
85277 + @Function FM_PCD_MatchTableFindNRemoveKey
85278 +
85279 + @Description Remove the key (including next engine parameters of this key)
85280 + defined by the key and mask. Note that this routine will search
85281 + the node to locate the index of the required key (& mask) to remove.
85282 +
85283 + @Param[in] h_CcNode A handle to the node
85284 + @Param[in] keySize Key size of the one to remove.
85285 + @Param[in] p_Key A pointer to the requested key to remove.
85286 + @Param[in] p_Mask A pointer to the mask if relevant,
85287 + otherwise pointer to NULL
85288 +
85289 + @Return E_OK on success; Error code otherwise.
85290 +
85291 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85292 + node and the nodes that lead to it.
85293 +*//***************************************************************************/
85294 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
85295 + uint8_t keySize,
85296 + uint8_t *p_Key,
85297 + uint8_t *p_Mask);
85298 +
85299 +/**************************************************************************//**
85300 + @Function FM_PCD_MatchTableFindNModifyNextEngine
85301 +
85302 + @Description Modify the Next Engine Parameters in the relevant key entry of
85303 + the node. Note that this routine will search the node to locate
85304 + the index of the required key (& mask) to modify.
85305 +
85306 + @Param[in] h_CcNode A handle to the node
85307 + @Param[in] keySize Key size of the one to modify.
85308 + @Param[in] p_Key A pointer to the requested key to modify.
85309 + @Param[in] p_Mask A pointer to the mask if relevant,
85310 + otherwise pointer to NULL
85311 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
85312 +
85313 + @Return E_OK on success; Error code otherwise.
85314 +
85315 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85316 + When configuring nextEngine = e_FM_PCD_CC, note that
85317 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85318 + from the currently changed table.
85319 +*//***************************************************************************/
85320 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
85321 + uint8_t keySize,
85322 + uint8_t *p_Key,
85323 + uint8_t *p_Mask,
85324 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85325 +
85326 +/**************************************************************************//**
85327 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
85328 +
85329 + @Description Modify the key and Next Engine Parameters of this key in the
85330 + index defined by the keyIndex. Note that this routine will search
85331 + the node to locate the index of the required key (& mask) to modify.
85332 +
85333 + @Param[in] h_CcNode A handle to the node
85334 + @Param[in] keySize Key size of the one to modify.
85335 + @Param[in] p_Key A pointer to the requested key to modify.
85336 + @Param[in] p_Mask A pointer to the mask if relevant,
85337 + otherwise pointer to NULL
85338 + @Param[in] p_KeyParams A pointer to the parameters includes
85339 + modified key and modified Next Engine Parameters
85340 +
85341 + @Return E_OK on success; Error code otherwise.
85342 +
85343 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85344 + node and the nodes that lead to it.
85345 + When configuring nextEngine = e_FM_PCD_CC, note that
85346 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85347 + from the currently changed table.
85348 +*//***************************************************************************/
85349 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
85350 + uint8_t keySize,
85351 + uint8_t *p_Key,
85352 + uint8_t *p_Mask,
85353 + t_FmPcdCcKeyParams *p_KeyParams);
85354 +
85355 +/**************************************************************************//**
85356 + @Function FM_PCD_MatchTableFindNModifyKey
85357 +
85358 + @Description Modify the key in the index defined by the keyIndex. Note that
85359 + this routine will search the node to locate the index of the
85360 + required key (& mask) to modify.
85361 +
85362 + @Param[in] h_CcNode A handle to the node
85363 + @Param[in] keySize Key size of the one to modify.
85364 + @Param[in] p_Key A pointer to the requested key to modify.
85365 + @Param[in] p_Mask A pointer to the mask if relevant,
85366 + otherwise pointer to NULL
85367 + @Param[in] p_NewKey A pointer to the new key
85368 + @Param[in] p_NewMask A pointer to the new mask if relevant,
85369 + otherwise pointer to NULL
85370 +
85371 + @Return E_OK on success; Error code otherwise.
85372 +
85373 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85374 + node and the nodes that lead to it.
85375 +*//***************************************************************************/
85376 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
85377 + uint8_t keySize,
85378 + uint8_t *p_Key,
85379 + uint8_t *p_Mask,
85380 + uint8_t *p_NewKey,
85381 + uint8_t *p_NewMask);
85382 +
85383 +/**************************************************************************//**
85384 + @Function FM_PCD_MatchTableGetKeyCounter
85385 +
85386 + @Description This routine may be used to get a counter of specific key in a CC
85387 + Node; This counter reflects how many frames passed that were matched
85388 + this key.
85389 +
85390 + @Param[in] h_CcNode A handle to the node
85391 + @Param[in] keyIndex Key index for adding
85392 +
85393 + @Return The specific key counter.
85394 +
85395 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85396 +*//***************************************************************************/
85397 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
85398 +
85399 +/**************************************************************************//**
85400 + @Function FM_PCD_MatchTableGetKeyStatistics
85401 +
85402 + @Description This routine may be used to get statistics counters of specific key
85403 + in a CC Node.
85404 +
85405 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85406 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85407 + these counters reflect how many frames passed that were matched
85408 + this key; The total frames count will be returned in the counter
85409 + of the first range (as only one frame length range was defined).
85410 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
85411 + frame count will be separated to frame length counters, based on
85412 + provided frame length ranges.
85413 +
85414 + @Param[in] h_CcNode A handle to the node
85415 + @Param[in] keyIndex Key index for adding
85416 + @Param[out] p_KeyStatistics Key statistics counters
85417 +
85418 + @Return The specific key statistics.
85419 +
85420 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85421 +*//***************************************************************************/
85422 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
85423 + uint16_t keyIndex,
85424 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
85425 +
85426 +/**************************************************************************//**
85427 + @Function FM_PCD_MatchTableGetMissStatistics
85428 +
85429 + @Description This routine may be used to get statistics counters of miss entry
85430 + in a CC Node.
85431 +
85432 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85433 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85434 + these counters reflect how many frames were not matched to any
85435 + existing key and therefore passed through the miss entry; The
85436 + total frames count will be returned in the counter of the
85437 + first range (as only one frame length range was defined).
85438 +
85439 + @Param[in] h_CcNode A handle to the node
85440 + @Param[out] p_MissStatistics Statistics counters for 'miss'
85441 +
85442 + @Return The statistics for 'miss'.
85443 +
85444 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85445 +*//***************************************************************************/
85446 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
85447 + t_FmPcdCcKeyStatistics *p_MissStatistics);
85448 +
85449 +/**************************************************************************//**
85450 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
85451 +
85452 + @Description This routine may be used to get statistics counters of specific key
85453 + in a CC Node.
85454 +
85455 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85456 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85457 + these counters reflect how many frames passed that were matched
85458 + this key; The total frames count will be returned in the counter
85459 + of the first range (as only one frame length range was defined).
85460 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
85461 + frame count will be separated to frame length counters, based on
85462 + provided frame length ranges.
85463 + Note that this routine will search the node to locate the index
85464 + of the required key based on received key parameters.
85465 +
85466 + @Param[in] h_CcNode A handle to the node
85467 + @Param[in] keySize Size of the requested key
85468 + @Param[in] p_Key A pointer to the requested key
85469 + @Param[in] p_Mask A pointer to the mask if relevant,
85470 + otherwise pointer to NULL
85471 + @Param[out] p_KeyStatistics Key statistics counters
85472 +
85473 + @Return The specific key statistics.
85474 +
85475 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85476 +*//***************************************************************************/
85477 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
85478 + uint8_t keySize,
85479 + uint8_t *p_Key,
85480 + uint8_t *p_Mask,
85481 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
85482 +
85483 +/**************************************************************************//*
85484 + @Function FM_PCD_MatchTableGetNextEngine
85485 +
85486 + @Description Gets NextEngine of the relevant keyIndex.
85487 +
85488 + @Param[in] h_CcNode A handle to the node.
85489 + @Param[in] keyIndex keyIndex in the relevant node.
85490 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
85491 + the relevant keyIndex of the CC Node
85492 + received as parameter to this function
85493 +
85494 + @Return E_OK on success; Error code otherwise.
85495 +
85496 + @Cautions Allowed only following FM_PCD_Init().
85497 +*//***************************************************************************/
85498 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
85499 + uint16_t keyIndex,
85500 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85501 +
85502 +/**************************************************************************//*
85503 + @Function FM_PCD_MatchTableGetIndexedHashBucket
85504 +
85505 + @Description This routine simulates KeyGen operation on the provided key and
85506 + calculates to which hash bucket it will be mapped.
85507 +
85508 + @Param[in] h_CcNode A handle to the node.
85509 + @Param[in] kgKeySize Key size as it was configured in the KG
85510 + scheme that leads to this hash.
85511 + @Param[in] p_KgKey Pointer to the key; must be like the key
85512 + that the KG is generated, i.e. the same
85513 + extraction and with mask if exist.
85514 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
85515 + scheme that leads to this hash.
85516 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
85517 + @Param[out] p_BucketIndex Index to the bucket of the provided key
85518 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
85519 + provided key.
85520 +
85521 + @Return E_OK on success; Error code otherwise.
85522 +
85523 + @Cautions Allowed only following FM_PCD_HashTableSet()
85524 +*//***************************************************************************/
85525 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
85526 + uint8_t kgKeySize,
85527 + uint8_t *p_KgKey,
85528 + uint8_t kgHashShift,
85529 + t_Handle *p_CcNodeBucketHandle,
85530 + uint8_t *p_BucketIndex,
85531 + uint16_t *p_LastIndex);
85532 +
85533 +/**************************************************************************//**
85534 + @Function FM_PCD_HashTableSet
85535 +
85536 + @Description This routine initializes a hash table structure.
85537 + KeyGen hash result determines the hash bucket.
85538 + Next, KeyGen key is compared against all keys of this
85539 + bucket (exact match).
85540 + Number of sets (number of buckets) of the hash equals to the
85541 + number of 1-s in 'hashResMask' in the provided parameters.
85542 + Number of hash table ways is then calculated by dividing
85543 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
85544 + number of keys that a hash bucket may hold.
85545 + The hash table is initialized empty and keys may be
85546 + added to it following the initialization. Keys masks are not
85547 + supported in current hash table implementation.
85548 + The initialized hash table can be integrated as a node in a
85549 + CC tree.
85550 +
85551 + @Param[in] h_FmPcd FM PCD module descriptor.
85552 + @Param[in] p_Param A structure of parameters defining the hash table
85553 +
85554 + @Return A handle to the initialized object on success; NULL code otherwise.
85555 +
85556 + @Cautions Allowed only following FM_PCD_Init().
85557 +*//***************************************************************************/
85558 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
85559 +
85560 +/**************************************************************************//**
85561 + @Function FM_PCD_HashTableDelete
85562 +
85563 + @Description This routine deletes the provided hash table and released all
85564 + its allocated resources.
85565 +
85566 + @Param[in] h_HashTbl A handle to a hash table
85567 +
85568 + @Return E_OK on success; Error code otherwise.
85569 +
85570 + @Cautions Allowed only following FM_PCD_HashTableSet().
85571 +*//***************************************************************************/
85572 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
85573 +
85574 +/**************************************************************************//**
85575 + @Function FM_PCD_HashTableAddKey
85576 +
85577 + @Description This routine adds the provided key (including next engine
85578 + parameters of this key) to the hash table.
85579 + The key is added as the last key of the bucket that it is
85580 + mapped to.
85581 +
85582 + @Param[in] h_HashTbl A handle to a hash table
85583 + @Param[in] keySize Key size of added key
85584 + @Param[in] p_KeyParams A pointer to the parameters includes
85585 + new key with next engine parameters; The pointer
85586 + to the key mask must be NULL, as masks are not
85587 + supported in hash table implementation.
85588 +
85589 + @Return E_OK on success; Error code otherwise.
85590 +
85591 + @Cautions Allowed only following FM_PCD_HashTableSet().
85592 +*//***************************************************************************/
85593 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
85594 + uint8_t keySize,
85595 + t_FmPcdCcKeyParams *p_KeyParams);
85596 +
85597 +/**************************************************************************//**
85598 + @Function FM_PCD_HashTableRemoveKey
85599 +
85600 + @Description This routine removes the requested key (including next engine
85601 + parameters of this key) from the hash table.
85602 +
85603 + @Param[in] h_HashTbl A handle to a hash table
85604 + @Param[in] keySize Key size of the one to remove.
85605 + @Param[in] p_Key A pointer to the requested key to remove.
85606 +
85607 + @Return E_OK on success; Error code otherwise.
85608 +
85609 + @Cautions Allowed only following FM_PCD_HashTableSet().
85610 +*//***************************************************************************/
85611 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
85612 + uint8_t keySize,
85613 + uint8_t *p_Key);
85614 +
85615 +/**************************************************************************//**
85616 + @Function FM_PCD_HashTableModifyNextEngine
85617 +
85618 + @Description This routine modifies the next engine for the provided key. The
85619 + key should be previously added to the hash table.
85620 +
85621 + @Param[in] h_HashTbl A handle to a hash table
85622 + @Param[in] keySize Key size of the key to modify.
85623 + @Param[in] p_Key A pointer to the requested key to modify.
85624 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
85625 + parameters.
85626 +
85627 + @Return E_OK on success; Error code otherwise.
85628 +
85629 + @Cautions Allowed only following FM_PCD_HashTableSet().
85630 + When configuring nextEngine = e_FM_PCD_CC, note that
85631 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85632 + from the currently changed table.
85633 +*//***************************************************************************/
85634 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
85635 + uint8_t keySize,
85636 + uint8_t *p_Key,
85637 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85638 +
85639 +/**************************************************************************//**
85640 + @Function FM_PCD_HashTableModifyMissNextEngine
85641 +
85642 + @Description This routine modifies the next engine on key match miss.
85643 +
85644 + @Param[in] h_HashTbl A handle to a hash table
85645 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
85646 + parameters.
85647 +
85648 + @Return E_OK on success; Error code otherwise.
85649 +
85650 + @Cautions Allowed only following FM_PCD_HashTableSet().
85651 + When configuring nextEngine = e_FM_PCD_CC, note that
85652 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85653 + from the currently changed table.
85654 +*//***************************************************************************/
85655 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
85656 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85657 +
85658 +/**************************************************************************//*
85659 + @Function FM_PCD_HashTableGetMissNextEngine
85660 +
85661 + @Description Gets NextEngine in case of key match miss.
85662 +
85663 + @Param[in] h_HashTbl A handle to a hash table
85664 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
85665 + hash table.
85666 +
85667 + @Return E_OK on success; Error code otherwise.
85668 +
85669 + @Cautions Allowed only following FM_PCD_HashTableSet().
85670 +*//***************************************************************************/
85671 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
85672 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85673 +
85674 +/**************************************************************************//**
85675 + @Function FM_PCD_HashTableFindNGetKeyStatistics
85676 +
85677 + @Description This routine may be used to get statistics counters of specific key
85678 + in a hash table.
85679 +
85680 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85681 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85682 + these counters reflect how many frames passed that were matched
85683 + this key; The total frames count will be returned in the counter
85684 + of the first range (as only one frame length range was defined).
85685 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
85686 + frame count will be separated to frame length counters, based on
85687 + provided frame length ranges.
85688 + Note that this routine will identify the bucket of this key in
85689 + the hash table and will search the bucket to locate the index
85690 + of the required key based on received key parameters.
85691 +
85692 + @Param[in] h_HashTbl A handle to a hash table
85693 + @Param[in] keySize Size of the requested key
85694 + @Param[in] p_Key A pointer to the requested key
85695 + @Param[out] p_KeyStatistics Key statistics counters
85696 +
85697 + @Return The specific key statistics.
85698 +
85699 + @Cautions Allowed only following FM_PCD_HashTableSet().
85700 +*//***************************************************************************/
85701 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
85702 + uint8_t keySize,
85703 + uint8_t *p_Key,
85704 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
85705 +
85706 +/**************************************************************************//**
85707 + @Function FM_PCD_HashTableGetMissStatistics
85708 +
85709 + @Description This routine may be used to get statistics counters of 'miss'
85710 + entry of the a hash table.
85711 +
85712 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85713 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85714 + these counters reflect how many frames were not matched to any
85715 + existing key and therefore passed through the miss entry;
85716 +
85717 + @Param[in] h_HashTbl A handle to a hash table
85718 + @Param[out] p_MissStatistics Statistics counters for 'miss'
85719 +
85720 + @Return The statistics for 'miss'.
85721 +
85722 + @Cautions Allowed only following FM_PCD_HashTableSet().
85723 +*//***************************************************************************/
85724 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
85725 + t_FmPcdCcKeyStatistics *p_MissStatistics);
85726 +
85727 +/**************************************************************************//**
85728 + @Function FM_PCD_ManipNodeSet
85729 +
85730 + @Description This routine should be called for defining a manipulation
85731 + node. A manipulation node must be defined before the CC node
85732 + that precedes it.
85733 +
85734 + @Param[in] h_FmPcd FM PCD module descriptor.
85735 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
85736 +
85737 + @Return A handle to the initialized object on success; NULL code otherwise.
85738 +
85739 + @Cautions Allowed only following FM_PCD_Init().
85740 +*//***************************************************************************/
85741 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
85742 +
85743 +/**************************************************************************//**
85744 + @Function FM_PCD_ManipNodeDelete
85745 +
85746 + @Description Delete an existing manipulation node.
85747 +
85748 + @Param[in] h_ManipNode A handle to a manipulation node.
85749 +
85750 + @Return E_OK on success; Error code otherwise.
85751 +
85752 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
85753 +*//***************************************************************************/
85754 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
85755 +
85756 +/**************************************************************************//**
85757 + @Function FM_PCD_ManipGetStatistics
85758 +
85759 + @Description Retrieve the manipulation statistics.
85760 +
85761 + @Param[in] h_ManipNode A handle to a manipulation node.
85762 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
85763 +
85764 + @Return E_OK on success; Error code otherwise.
85765 +
85766 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
85767 +*//***************************************************************************/
85768 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
85769 +
85770 +/**************************************************************************//**
85771 + @Function FM_PCD_ManipNodeReplace
85772 +
85773 + @Description Change existing manipulation node to be according to new requirement.
85774 +
85775 + @Param[in] h_ManipNode A handle to a manipulation node.
85776 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
85777 +
85778 + @Return E_OK on success; Error code otherwise.
85779 +
85780 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
85781 +*//***************************************************************************/
85782 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
85783 +
85784 +#if (DPAA_VERSION >= 11)
85785 +/**************************************************************************//**
85786 + @Function FM_PCD_FrmReplicSetGroup
85787 +
85788 + @Description Initialize a Frame Replicator group.
85789 +
85790 + @Param[in] h_FmPcd FM PCD module descriptor.
85791 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
85792 + the frame replicator group.
85793 +
85794 + @Return A handle to the initialized object on success; NULL code otherwise.
85795 +
85796 + @Cautions Allowed only following FM_PCD_Init().
85797 +*//***************************************************************************/
85798 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
85799 +
85800 +/**************************************************************************//**
85801 + @Function FM_PCD_FrmReplicDeleteGroup
85802 +
85803 + @Description Delete a Frame Replicator group.
85804 +
85805 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
85806 +
85807 + @Return E_OK on success; Error code otherwise.
85808 +
85809 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
85810 +*//***************************************************************************/
85811 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
85812 +
85813 +/**************************************************************************//**
85814 + @Function FM_PCD_FrmReplicAddMember
85815 +
85816 + @Description Add the member in the index defined by the memberIndex.
85817 +
85818 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
85819 + @Param[in] memberIndex member index for adding.
85820 + @Param[in] p_MemberParams A pointer to the new member parameters.
85821 +
85822 + @Return E_OK on success; Error code otherwise.
85823 +
85824 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
85825 +*//***************************************************************************/
85826 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
85827 + uint16_t memberIndex,
85828 + t_FmPcdCcNextEngineParams *p_MemberParams);
85829 +
85830 +/**************************************************************************//**
85831 + @Function FM_PCD_FrmReplicRemoveMember
85832 +
85833 + @Description Remove the member defined by the index from the relevant group.
85834 +
85835 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
85836 + @Param[in] memberIndex member index for removing.
85837 +
85838 + @Return E_OK on success; Error code otherwise.
85839 +
85840 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
85841 +*//***************************************************************************/
85842 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
85843 + uint16_t memberIndex);
85844 +#endif /* (DPAA_VERSION >= 11) */
85845 +
85846 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
85847 +/**************************************************************************//**
85848 + @Function FM_PCD_StatisticsSetNode
85849 +
85850 + @Description This routine should be called for defining a statistics node.
85851 +
85852 + @Param[in] h_FmPcd FM PCD module descriptor.
85853 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
85854 +
85855 + @Return A handle to the initialized object on success; NULL code otherwise.
85856 +
85857 + @Cautions Allowed only following FM_PCD_Init().
85858 +*//***************************************************************************/
85859 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
85860 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
85861 +
85862 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
85863 +/** @} */ /* end of FM_PCD_Runtime_grp group */
85864 +/** @} */ /* end of FM_PCD_grp group */
85865 +/** @} */ /* end of FM_grp group */
85866 +
85867 +
85868 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
85869 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
85870 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
85871 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
85872 +
85873 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
85874 +
85875 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
85876 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
85877 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
85878 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
85879 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
85880 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
85881 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
85882 +
85883 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
85884 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
85885 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
85886 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
85887 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
85888 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
85889 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
85890 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
85891 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
85892 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
85893 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
85894 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
85895 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
85896 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
85897 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
85898 + FM_PCD_CcRootDelete(__VA_ARGS__)
85899 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
85900 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
85901 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
85902 + FM_PCD_MatchTableDelete(__VA_ARGS__)
85903 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
85904 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
85905 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
85906 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
85907 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
85908 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
85909 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
85910 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
85911 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
85912 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
85913 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
85914 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
85915 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
85916 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
85917 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
85918 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
85919 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
85920 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
85921 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
85922 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
85923 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
85924 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
85925 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
85926 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
85927 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
85928 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
85929 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
85930 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
85931 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
85932 +
85933 +
85934 +#endif /* __FM_PCD_EXT */
85935 --- /dev/null
85936 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
85937 @@ -0,0 +1,2608 @@
85938 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
85939 + * All rights reserved.
85940 + *
85941 + * Redistribution and use in source and binary forms, with or without
85942 + * modification, are permitted provided that the following conditions are met:
85943 + * * Redistributions of source code must retain the above copyright
85944 + * notice, this list of conditions and the following disclaimer.
85945 + * * Redistributions in binary form must reproduce the above copyright
85946 + * notice, this list of conditions and the following disclaimer in the
85947 + * documentation and/or other materials provided with the distribution.
85948 + * * Neither the name of Freescale Semiconductor nor the
85949 + * names of its contributors may be used to endorse or promote products
85950 + * derived from this software without specific prior written permission.
85951 + *
85952 + *
85953 + * ALTERNATIVELY, this software may be distributed under the terms of the
85954 + * GNU General Public License ("GPL") as published by the Free Software
85955 + * Foundation, either version 2 of that License or (at your option) any
85956 + * later version.
85957 + *
85958 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
85959 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
85960 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
85961 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
85962 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
85963 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
85964 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
85965 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
85966 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
85967 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85968 + */
85969 +
85970 +
85971 +/**************************************************************************//**
85972 + @File fm_port_ext.h
85973 +
85974 + @Description FM-Port Application Programming Interface.
85975 +*//***************************************************************************/
85976 +#ifndef __FM_PORT_EXT
85977 +#define __FM_PORT_EXT
85978 +
85979 +#include "error_ext.h"
85980 +#include "std_ext.h"
85981 +#include "fm_pcd_ext.h"
85982 +#include "fm_ext.h"
85983 +#include "net_ext.h"
85984 +
85985 +
85986 +/**************************************************************************//**
85987 +
85988 + @Group FM_grp Frame Manager API
85989 +
85990 + @Description FM API functions, definitions and enums
85991 +
85992 + @{
85993 +*//***************************************************************************/
85994 +
85995 +/**************************************************************************//**
85996 + @Group FM_PORT_grp FM Port
85997 +
85998 + @Description FM Port API
85999 +
86000 + The FM uses a general module called "port" to represent a Tx port
86001 + (MAC), an Rx port (MAC) or Offline Parsing port.
86002 + The number of ports in an FM varies between SOCs.
86003 + The SW driver manages these ports as sub-modules of the FM, i.e.
86004 + after an FM is initialized, its ports may be initialized and
86005 + operated upon.
86006 +
86007 + The port is initialized aware of its type, but other functions on
86008 + a port may be indifferent to its type. When necessary, the driver
86009 + verifies coherence and returns error if applicable.
86010 +
86011 + On initialization, user specifies the port type and it's index
86012 + (relative to the port's type) - always starting at 0.
86013 +
86014 + @{
86015 +*//***************************************************************************/
86016 +
86017 +/**************************************************************************//**
86018 + @Description An enum for defining port PCD modes.
86019 + This enum defines the superset of PCD engines support - i.e. not
86020 + all engines have to be used, but all have to be enabled. The real
86021 + flow of a specific frame depends on the PCD configuration and the
86022 + frame headers and payload.
86023 + Note: the first engine and the first engine after the parser (if
86024 + exists) should be in order, the order is important as it will
86025 + define the flow of the port. However, as for the rest engines
86026 + (the ones that follows), the order is not important anymore as
86027 + it is defined by the PCD graph itself.
86028 +*//***************************************************************************/
86029 +typedef enum e_FmPortPcdSupport {
86030 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
86031 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
86032 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
86033 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
86034 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
86035 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
86036 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
86037 + /**< Use all PCD engines */
86038 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
86039 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
86040 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
86041 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
86042 +#ifdef FM_CAPWAP_SUPPORT
86043 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
86044 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
86045 +#endif /* FM_CAPWAP_SUPPORT */
86046 +} e_FmPortPcdSupport;
86047 +
86048 +/**************************************************************************//**
86049 + @Description Port interrupts
86050 +*//***************************************************************************/
86051 +typedef enum e_FmPortExceptions {
86052 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
86053 +} e_FmPortExceptions;
86054 +
86055 +
86056 +/**************************************************************************//**
86057 + @Collection General FM Port defines
86058 +*//***************************************************************************/
86059 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
86060 +/* @} */
86061 +
86062 +/**************************************************************************//**
86063 + @Collection FM Frame error
86064 +*//***************************************************************************/
86065 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
86066 +
86067 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
86068 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
86069 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
86070 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
86071 + was chained to FM */
86072 +
86073 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
86074 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
86075 +
86076 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
86077 +
86078 +#ifdef FM_CAPWAP_SUPPORT
86079 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
86080 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
86081 +#endif /* FM_CAPWAP_SUPPORT */
86082 +
86083 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
86084 + error (SGMII and TBI modes), FIFO parity error. PHY
86085 + Sequence error, PHY error control character detected. */
86086 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
86087 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
86088 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
86089 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
86090 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
86091 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
86092 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
86093 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
86094 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
86095 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
86096 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
86097 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
86098 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
86099 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
86100 +/* @} */
86101 +
86102 +
86103 +
86104 +/**************************************************************************//**
86105 + @Group FM_PORT_init_grp FM Port Initialization Unit
86106 +
86107 + @Description FM Port Initialization Unit
86108 +
86109 + @{
86110 +*//***************************************************************************/
86111 +
86112 +/**************************************************************************//**
86113 + @Description Exceptions user callback routine, will be called upon an
86114 + exception passing the exception identification.
86115 +
86116 + @Param[in] h_App - User's application descriptor.
86117 + @Param[in] exception - The exception.
86118 + *//***************************************************************************/
86119 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
86120 +
86121 +/**************************************************************************//**
86122 + @Description User callback function called by driver with received data.
86123 +
86124 + User provides this function. Driver invokes it.
86125 +
86126 + @Param[in] h_App Application's handle originally specified to
86127 + the API Config function
86128 + @Param[in] p_Data A pointer to data received
86129 + @Param[in] length length of received data
86130 + @Param[in] status receive status and errors
86131 + @Param[in] position position of buffer in frame
86132 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86133 +
86134 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
86135 + operation for all ready data.
86136 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
86137 +*//***************************************************************************/
86138 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
86139 + uint8_t *p_Data,
86140 + uint16_t length,
86141 + uint16_t status,
86142 + uint8_t position,
86143 + t_Handle h_BufContext);
86144 +
86145 +/**************************************************************************//**
86146 + @Description User callback function called by driver when transmit completed.
86147 +
86148 + User provides this function. Driver invokes it.
86149 +
86150 + @Param[in] h_App Application's handle originally specified to
86151 + the API Config function
86152 + @Param[in] p_Data A pointer to data received
86153 + @Param[in] status transmit status and errors
86154 + @Param[in] lastBuffer is last buffer in frame
86155 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86156 + *//***************************************************************************/
86157 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
86158 + uint8_t *p_Data,
86159 + uint16_t status,
86160 + t_Handle h_BufContext);
86161 +
86162 +/**************************************************************************//**
86163 + @Description A structure for additional Rx port parameters
86164 +*//***************************************************************************/
86165 +typedef struct t_FmPortRxParams {
86166 + uint32_t errFqid; /**< Error Queue Id. */
86167 + uint32_t dfltFqid; /**< Default Queue Id. */
86168 + uint16_t liodnOffset; /**< Port's LIODN offset. */
86169 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
86170 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
86171 +} t_FmPortRxParams;
86172 +
86173 +/**************************************************************************//**
86174 + @Description A structure for additional non-Rx port parameters
86175 +*//***************************************************************************/
86176 +typedef struct t_FmPortNonRxParams {
86177 + uint32_t errFqid; /**< Error Queue Id. */
86178 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
86179 + 0 means no Tx confirmation for processed
86180 + frames. For OP port - default Rx queue. */
86181 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
86182 + by the FM for dequeue. */
86183 +} t_FmPortNonRxParams;
86184 +
86185 +/**************************************************************************//**
86186 + @Description A structure for additional Rx port parameters
86187 +*//***************************************************************************/
86188 +typedef struct t_FmPortImRxTxParams {
86189 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
86190 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
86191 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
86192 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
86193 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
86194 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
86195 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
86196 +} t_FmPortImRxTxParams;
86197 +
86198 +/**************************************************************************//**
86199 + @Description A union for additional parameters depending on port type
86200 +*//***************************************************************************/
86201 +typedef union u_FmPortSpecificParams {
86202 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
86203 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
86204 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
86205 +} u_FmPortSpecificParams;
86206 +
86207 +/**************************************************************************//**
86208 + @Description A structure representing FM initialization parameters
86209 +*//***************************************************************************/
86210 +typedef struct t_FmPortParams {
86211 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
86212 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
86213 + e_FmPortType portType; /**< Port type */
86214 + uint8_t portId; /**< Port Id - relative to type;
86215 + NOTE: When configuring Offline Parsing port for
86216 + FMANv3 devices (DPAA_VERSION 11 and higher),
86217 + it is highly recommended NOT to use portId=0 due to lack
86218 + of HW resources on portId=0. */
86219 + bool independentModeEnable;
86220 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
86221 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
86222 + used together with LIODN offset. */
86223 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
86224 + type. */
86225 +
86226 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
86227 + t_Handle h_App; /**< A handle to an application layer object; This handle will
86228 + be passed by the driver upon calling the above callbacks */
86229 +} t_FmPortParams;
86230 +
86231 +
86232 +/**************************************************************************//**
86233 + @Function FM_PORT_Config
86234 +
86235 + @Description Creates a descriptor for the FM PORT module.
86236 +
86237 + The routine returns a handle (descriptor) to the FM PORT object.
86238 + This descriptor must be passed as first parameter to all other
86239 + FM PORT function calls.
86240 +
86241 + No actual initialization or configuration of FM hardware is
86242 + done by this routine.
86243 +
86244 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
86245 +
86246 + @Retval Handle to FM object, or NULL for Failure.
86247 +*//***************************************************************************/
86248 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
86249 +
86250 +/**************************************************************************//**
86251 + @Function FM_PORT_Init
86252 +
86253 + @Description Initializes the FM PORT module by defining the software structure
86254 + and configuring the hardware registers.
86255 +
86256 + @Param[in] h_FmPort - FM PORT module descriptor
86257 +
86258 + @Return E_OK on success; Error code otherwise.
86259 +*//***************************************************************************/
86260 +t_Error FM_PORT_Init(t_Handle h_FmPort);
86261 +
86262 +/**************************************************************************//**
86263 + @Function FM_PORT_Free
86264 +
86265 + @Description Frees all resources that were assigned to FM PORT module.
86266 +
86267 + Calling this routine invalidates the descriptor.
86268 +
86269 + @Param[in] h_FmPort - FM PORT module descriptor
86270 +
86271 + @Return E_OK on success; Error code otherwise.
86272 +*//***************************************************************************/
86273 +t_Error FM_PORT_Free(t_Handle h_FmPort);
86274 +
86275 +
86276 +/**************************************************************************//**
86277 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
86278 +
86279 + @Description Configuration functions used to change default values.
86280 +
86281 + @{
86282 +*//***************************************************************************/
86283 +
86284 +/**************************************************************************//**
86285 + @Description enum for defining QM frame dequeue
86286 +*//***************************************************************************/
86287 +typedef enum e_FmPortDeqType {
86288 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
86289 + and Intra-Class Scheduling respected. */
86290 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
86291 + and Intra-Class Scheduling respected. */
86292 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
86293 + and override Intra-Class Scheduling */
86294 +} e_FmPortDeqType;
86295 +
86296 +/**************************************************************************//**
86297 + @Description enum for defining QM frame dequeue
86298 +*//***************************************************************************/
86299 +typedef enum e_FmPortDeqPrefetchOption {
86300 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
86301 + only when a dedicated portID Tnum is waiting. */
86302 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
86303 + one dedicated portId tnum is waiting. */
86304 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
86305 + no dedicated portId tnums are waiting. */
86306 +
86307 +} e_FmPortDeqPrefetchOption;
86308 +
86309 +/**************************************************************************//**
86310 + @Description enum for defining port default color
86311 +*//***************************************************************************/
86312 +typedef enum e_FmPortColor {
86313 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
86314 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
86315 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
86316 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
86317 +} e_FmPortColor;
86318 +
86319 +/**************************************************************************//**
86320 + @Description A structure for defining Dual Tx rate limiting scale
86321 +*//***************************************************************************/
86322 +typedef enum e_FmPortDualRateLimiterScaleDown {
86323 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
86324 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
86325 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
86326 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
86327 +} e_FmPortDualRateLimiterScaleDown;
86328 +
86329 +
86330 +/**************************************************************************//**
86331 + @Description A structure for defining FM port resources
86332 +*//***************************************************************************/
86333 +typedef struct t_FmPortRsrc {
86334 + uint32_t num; /**< Committed required resource */
86335 + uint32_t extra; /**< Extra (not committed) required resource */
86336 +} t_FmPortRsrc;
86337 +
86338 +/**************************************************************************//**
86339 + @Description A structure for defining observed pool depletion
86340 +*//***************************************************************************/
86341 +typedef struct t_FmPortObservedBufPoolDepletion {
86342 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
86343 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
86344 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
86345 + and their sizes. */
86346 +} t_FmPortObservedBufPoolDepletion;
86347 +
86348 +/**************************************************************************//**
86349 + @Description A structure for defining Tx rate limiting
86350 +*//***************************************************************************/
86351 +typedef struct t_FmPortRateLimit {
86352 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
86353 + for OP ports. (note that
86354 + for early chips burst size is
86355 + rounded up to a multiply of 1000 frames).*/
86356 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
86357 + OP ports. Rate limit refers to
86358 + data rate (rather than line rate). */
86359 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
86360 + for some earlier chip revisions */
86361 +} t_FmPortRateLimit;
86362 +
86363 +/**************************************************************************//**
86364 + @Description A structure for defining the parameters of
86365 + the Rx port performance counters
86366 +*//***************************************************************************/
86367 +typedef struct t_FmPortPerformanceCnt {
86368 + uint8_t taskCompVal; /**< Task compare value */
86369 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
86370 + value (unused for H/O) */
86371 + uint8_t dmaCompVal; /**< Dma compare value */
86372 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
86373 +} t_FmPortPerformanceCnt;
86374 +
86375 +
86376 +/**************************************************************************//**
86377 + @Description A structure for defining the sizes of the Deep Sleep
86378 + the Auto Response tables
86379 +*//***************************************************************************/
86380 +typedef struct t_FmPortDsarTablesSizes
86381 +{
86382 + uint16_t maxNumOfArpEntries;
86383 + uint16_t maxNumOfEchoIpv4Entries;
86384 + uint16_t maxNumOfNdpEntries;
86385 + uint16_t maxNumOfEchoIpv6Entries;
86386 + uint16_t maxNumOfSnmpIPV4Entries;
86387 + uint16_t maxNumOfSnmpIPV6Entries;
86388 + uint16_t maxNumOfSnmpOidEntries;
86389 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
86390 +
86391 + uint16_t maxNumOfIpProtFiltering;
86392 + uint16_t maxNumOfTcpPortFiltering;
86393 + uint16_t maxNumOfUdpPortFiltering;
86394 +} t_FmPortDsarTablesSizes;
86395 +
86396 +
86397 +/**************************************************************************//**
86398 + @Function FM_PORT_ConfigDsarSupport
86399 +
86400 + @Description This function will allocate the amount of MURAM needed for
86401 + this max number of entries for Deep Sleep Auto Response.
86402 + it will calculate all needed MURAM for autoresponse including
86403 + necesary common stuff.
86404 +
86405 +
86406 + @Param[in] h_FmPort A handle to a FM Port module.
86407 + @Param[in] params A pointer to a structure containing the maximum
86408 + sizes of the auto response tables
86409 +
86410 + @Return E_OK on success; Error code otherwise.
86411 +
86412 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86413 +*//***************************************************************************/
86414 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
86415 +
86416 +/**************************************************************************//**
86417 + @Function FM_PORT_ConfigNumOfOpenDmas
86418 +
86419 + @Description Calling this routine changes the max number of open DMA's
86420 + available for this port. It changes this parameter in the
86421 + internal driver data base from its default configuration
86422 + [OP: 1]
86423 + [1G-RX, 1G-TX: 1 (+1)]
86424 + [10G-RX, 10G-TX: 8 (+8)]
86425 +
86426 + @Param[in] h_FmPort A handle to a FM Port module.
86427 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
86428 + the open DMA allocation.
86429 +
86430 + @Return E_OK on success; Error code otherwise.
86431 +
86432 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86433 +*//***************************************************************************/
86434 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
86435 +
86436 +/**************************************************************************//**
86437 + @Function FM_PORT_ConfigNumOfTasks
86438 +
86439 + @Description Calling this routine changes the max number of tasks
86440 + available for this port. It changes this parameter in the
86441 + internal driver data base from its default configuration
86442 + [OP: 1]
86443 + [1G-RX, 1G-TX: 3 (+2)]
86444 + [10G-RX, 10G-TX: 16 (+8)]
86445 +
86446 + @Param[in] h_FmPort A handle to a FM Port module.
86447 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
86448 + the tasks allocation.
86449 +
86450 + @Return E_OK on success; Error code otherwise.
86451 +
86452 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86453 +*//***************************************************************************/
86454 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
86455 +
86456 +/**************************************************************************//**
86457 + @Function FM_PORT_ConfigSizeOfFifo
86458 +
86459 + @Description Calling this routine changes the max FIFO size configured for this port.
86460 +
86461 + This function changes the internal driver data base from its
86462 + default configuration. Please refer to the driver's User Guide for
86463 + information on default FIFO sizes in the various devices.
86464 + [OP: 2KB]
86465 + [1G-RX, 1G-TX: 11KB]
86466 + [10G-RX, 10G-TX: 12KB]
86467 +
86468 + @Param[in] h_FmPort A handle to a FM Port module.
86469 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
86470 + the FIFO allocation.
86471 +
86472 + @Return E_OK on success; Error code otherwise.
86473 +
86474 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86475 +*//***************************************************************************/
86476 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
86477 +
86478 +/**************************************************************************//**
86479 + @Function FM_PORT_ConfigDeqHighPriority
86480 +
86481 + @Description Calling this routine changes the dequeue priority in the
86482 + internal driver data base from its default configuration
86483 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
86484 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
86485 +
86486 + May be used for Non-Rx ports only
86487 +
86488 + @Param[in] h_FmPort A handle to a FM Port module.
86489 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
86490 +
86491 + @Return E_OK on success; Error code otherwise.
86492 +
86493 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86494 +*//***************************************************************************/
86495 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
86496 +
86497 +/**************************************************************************//**
86498 + @Function FM_PORT_ConfigDeqType
86499 +
86500 + @Description Calling this routine changes the dequeue type parameter in the
86501 + internal driver data base from its default configuration
86502 + [DEFAULT_PORT_deqType].
86503 +
86504 + May be used for Non-Rx ports only
86505 +
86506 + @Param[in] h_FmPort A handle to a FM Port module.
86507 + @Param[in] deqType According to QM definition.
86508 +
86509 + @Return E_OK on success; Error code otherwise.
86510 +
86511 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86512 +*//***************************************************************************/
86513 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
86514 +
86515 +/**************************************************************************//**
86516 + @Function FM_PORT_ConfigDeqPrefetchOption
86517 +
86518 + @Description Calling this routine changes the dequeue prefetch option parameter in the
86519 + internal driver data base from its default configuration
86520 + [DEFAULT_PORT_deqPrefetchOption]
86521 + Note: Available for some chips only
86522 +
86523 + May be used for Non-Rx ports only
86524 +
86525 + @Param[in] h_FmPort A handle to a FM Port module.
86526 + @Param[in] deqPrefetchOption New option
86527 +
86528 + @Return E_OK on success; Error code otherwise.
86529 +
86530 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86531 +*//***************************************************************************/
86532 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
86533 +
86534 +/**************************************************************************//**
86535 + @Function FM_PORT_ConfigDeqByteCnt
86536 +
86537 + @Description Calling this routine changes the dequeue byte count parameter in
86538 + the internal driver data base from its default configuration
86539 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
86540 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
86541 +
86542 + May be used for Non-Rx ports only
86543 +
86544 + @Param[in] h_FmPort A handle to a FM Port module.
86545 + @Param[in] deqByteCnt New byte count
86546 +
86547 + @Return E_OK on success; Error code otherwise.
86548 +
86549 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86550 +*//***************************************************************************/
86551 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
86552 +
86553 +/**************************************************************************//**
86554 + @Function FM_PORT_ConfigBufferPrefixContent
86555 +
86556 + @Description Defines the structure, size and content of the application buffer.
86557 + The prefix will
86558 + In Tx ports, if 'passPrsResult', the application
86559 + should set a value to their offsets in the prefix of
86560 + the FM will save the first 'privDataSize', than,
86561 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
86562 + and timeStamp, and the packet itself (in this order), to the
86563 + application buffer, and to offset.
86564 + Calling this routine changes the buffer margins definitions
86565 + in the internal driver data base from its default
86566 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
86567 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
86568 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
86569 +
86570 + May be used for all ports
86571 +
86572 + @Param[in] h_FmPort A handle to a FM Port module.
86573 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
86574 + structure of the buffer.
86575 + Out parameter: Start margin - offset
86576 + of data from start of external buffer.
86577 +
86578 + @Return E_OK on success; Error code otherwise.
86579 +
86580 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86581 +*//***************************************************************************/
86582 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
86583 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
86584 +
86585 +/**************************************************************************//**
86586 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
86587 +
86588 + @Description Calling this routine changes the number of checksum bytes to ignore
86589 + parameter in the internal driver data base from its default configuration
86590 + [DEFAULT_PORT_cheksumLastBytesIgnore]
86591 +
86592 + May be used by Tx & Rx ports only
86593 +
86594 + @Param[in] h_FmPort A handle to a FM Port module.
86595 + @Param[in] cheksumLastBytesIgnore New value
86596 +
86597 + @Return E_OK on success; Error code otherwise.
86598 +
86599 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86600 +*//***************************************************************************/
86601 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
86602 +
86603 +/**************************************************************************//**
86604 + @Function FM_PORT_ConfigCutBytesFromEnd
86605 +
86606 + @Description Calling this routine changes the number of bytes to cut from a
86607 + frame's end parameter in the internal driver data base
86608 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
86609 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
86610 + less than 14 bytes, the chop operation is not executed.
86611 +
86612 + May be used for Rx ports only
86613 +
86614 + @Param[in] h_FmPort A handle to a FM Port module.
86615 + @Param[in] cutBytesFromEnd New value
86616 +
86617 + @Return E_OK on success; Error code otherwise.
86618 +
86619 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86620 +*//***************************************************************************/
86621 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
86622 +
86623 +/**************************************************************************//**
86624 + @Function FM_PORT_ConfigPoolDepletion
86625 +
86626 + @Description Calling this routine enables pause frame generation depending on the
86627 + depletion status of BM pools. It also defines the conditions to activate
86628 + this functionality. By default, this functionality is disabled.
86629 +
86630 + May be used for Rx ports only
86631 +
86632 + @Param[in] h_FmPort A handle to a FM Port module.
86633 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
86634 +
86635 + @Return E_OK on success; Error code otherwise.
86636 +
86637 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86638 +*//***************************************************************************/
86639 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
86640 +
86641 +/**************************************************************************//**
86642 + @Function FM_PORT_ConfigObservedPoolDepletion
86643 +
86644 + @Description Calling this routine enables a mechanism to stop port enqueue
86645 + depending on the depletion status of selected BM pools.
86646 + It also defines the conditions to activate
86647 + this functionality. By default, this functionality is disabled.
86648 +
86649 + Note: Available for some chips only
86650 +
86651 + May be used for OP ports only
86652 +
86653 + @Param[in] h_FmPort A handle to a FM Port module.
86654 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
86655 +
86656 + @Return E_OK on success; Error code otherwise.
86657 +
86658 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86659 +*//***************************************************************************/
86660 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
86661 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
86662 +
86663 +/**************************************************************************//**
86664 + @Function FM_PORT_ConfigExtBufPools
86665 +
86666 + @Description This routine should be called for OP ports
86667 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
86668 + re-assembly, the FM needs new BM buffers. By calling this routine the user
86669 + specifies the BM buffer pools that should be used.
86670 +
86671 + Note: Available for some chips only
86672 +
86673 + May be used for OP ports only
86674 +
86675 + @Param[in] h_FmPort A handle to a FM Port module.
86676 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
86677 +
86678 + @Return E_OK on success; Error code otherwise.
86679 +
86680 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86681 +*//***************************************************************************/
86682 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
86683 +
86684 +/**************************************************************************//**
86685 + @Function FM_PORT_ConfigBackupPools
86686 +
86687 + @Description Calling this routine allows the configuration of some of the BM pools
86688 + defined for this port as backup pools.
86689 + A pool configured to be a backup pool will be used only if all other
86690 + enabled non-backup pools are depleted.
86691 +
86692 + May be used for Rx ports only
86693 +
86694 + @Param[in] h_FmPort A handle to a FM Port module.
86695 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
86696 + be defined as backup pools.
86697 +
86698 + @Return E_OK on success; Error code otherwise.
86699 +
86700 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86701 +*//***************************************************************************/
86702 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
86703 +
86704 +/**************************************************************************//**
86705 + @Function FM_PORT_ConfigFrmDiscardOverride
86706 +
86707 + @Description Calling this routine changes the error frames destination parameter
86708 + in the internal driver data base from its default configuration:
86709 + override = [DEFAULT_PORT_frmDiscardOverride]
86710 +
86711 + May be used for Rx and OP ports only
86712 +
86713 + @Param[in] h_FmPort A handle to a FM Port module.
86714 + @Param[in] override TRUE to override discarding of error frames and
86715 + enqueueing them to error queue.
86716 +
86717 + @Return E_OK on success; Error code otherwise.
86718 +
86719 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86720 +*//***************************************************************************/
86721 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
86722 +
86723 +/**************************************************************************//**
86724 + @Function FM_PORT_ConfigErrorsToDiscard
86725 +
86726 + @Description Calling this routine changes the behaviour on error parameter
86727 + in the internal driver data base from its default configuration:
86728 + [DEFAULT_PORT_errorsToDiscard].
86729 + If a requested error was previously defined as "ErrorsToEnqueue" it's
86730 + definition will change and the frame will be discarded.
86731 + Errors that were not defined either as "ErrorsToEnqueue" nor as
86732 + "ErrorsToDiscard", will be forwarded to CPU.
86733 +
86734 + May be used for Rx and OP ports only
86735 +
86736 + @Param[in] h_FmPort A handle to a FM Port module.
86737 + @Param[in] errs A list of errors to discard
86738 +
86739 + @Return E_OK on success; Error code otherwise.
86740 +
86741 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86742 +*//***************************************************************************/
86743 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86744 +
86745 +/**************************************************************************//**
86746 + @Function FM_PORT_ConfigDmaSwapData
86747 +
86748 + @Description Calling this routine changes the DMA swap data aparameter
86749 + in the internal driver data base from its default
86750 + configuration [DEFAULT_PORT_dmaSwapData]
86751 +
86752 + May be used for all port types
86753 +
86754 + @Param[in] h_FmPort A handle to a FM Port module.
86755 + @Param[in] swapData New selection
86756 +
86757 + @Return E_OK on success; Error code otherwise.
86758 +
86759 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86760 +*//***************************************************************************/
86761 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
86762 +
86763 +/**************************************************************************//**
86764 + @Function FM_PORT_ConfigDmaIcCacheAttr
86765 +
86766 + @Description Calling this routine changes the internal context cache
86767 + attribute parameter in the internal driver data base
86768 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
86769 +
86770 + May be used for all port types
86771 +
86772 + @Param[in] h_FmPort A handle to a FM Port module.
86773 + @Param[in] intContextCacheAttr New selection
86774 +
86775 + @Return E_OK on success; Error code otherwise.
86776 +
86777 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86778 +*//***************************************************************************/
86779 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
86780 +
86781 +/**************************************************************************//**
86782 + @Function FM_PORT_ConfigDmaHdrAttr
86783 +
86784 + @Description Calling this routine changes the header cache
86785 + attribute parameter in the internal driver data base
86786 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
86787 +
86788 + May be used for all port types
86789 +
86790 + @Param[in] h_FmPort A handle to a FM Port module.
86791 + @Param[in] headerCacheAttr New selection
86792 +
86793 + @Return E_OK on success; Error code otherwise.
86794 +
86795 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86796 +*//***************************************************************************/
86797 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
86798 +
86799 +/**************************************************************************//**
86800 + @Function FM_PORT_ConfigDmaScatterGatherAttr
86801 +
86802 + @Description Calling this routine changes the scatter gather cache
86803 + attribute parameter in the internal driver data base
86804 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
86805 +
86806 + May be used for all port types
86807 +
86808 + @Param[in] h_FmPort A handle to a FM Port module.
86809 + @Param[in] scatterGatherCacheAttr New selection
86810 +
86811 + @Return E_OK on success; Error code otherwise.
86812 +
86813 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86814 +*//***************************************************************************/
86815 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
86816 +
86817 +/**************************************************************************//**
86818 + @Function FM_PORT_ConfigDmaWriteOptimize
86819 +
86820 + @Description Calling this routine changes the write optimization
86821 + parameter in the internal driver data base
86822 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
86823 + Note:
86824 +
86825 + 1. For head optimization, data alignment must be >= 16 (supported by default).
86826 +
86827 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
86828 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
86829 + is extended to be on 16/64 bytes aligned block (chip dependent).
86830 +
86831 + Relevant for non-Tx port types
86832 +
86833 + @Param[in] h_FmPort A handle to a FM Port module.
86834 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
86835 +
86836 + @Return E_OK on success; Error code otherwise.
86837 +
86838 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86839 +*//***************************************************************************/
86840 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
86841 +
86842 +/**************************************************************************//**
86843 + @Function FM_PORT_ConfigNoScatherGather
86844 +
86845 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
86846 + from its default configuration.
86847 +
86848 + @Param[in] h_FmPort A handle to a FM Port module.
86849 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
86850 + FALSE - frame can be stored in scatter gather (S/G) format).
86851 +
86852 + @Return E_OK on success; Error code otherwise.
86853 +
86854 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86855 +*//***************************************************************************/
86856 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
86857 +
86858 +/**************************************************************************//**
86859 + @Function FM_PORT_ConfigDfltColor
86860 +
86861 + @Description Calling this routine changes the internal default color parameter
86862 + in the internal driver data base
86863 + from its default configuration [DEFAULT_PORT_color]
86864 +
86865 + May be used for all port types
86866 +
86867 + @Param[in] h_FmPort A handle to a FM Port module.
86868 + @Param[in] color New selection
86869 +
86870 + @Return E_OK on success; Error code otherwise.
86871 +
86872 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86873 +*//***************************************************************************/
86874 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
86875 +
86876 +/**************************************************************************//**
86877 + @Function FM_PORT_ConfigSyncReq
86878 +
86879 + @Description Calling this routine changes the synchronization attribute parameter
86880 + in the internal driver data base from its default configuration:
86881 + syncReq = [DEFAULT_PORT_syncReq]
86882 +
86883 + May be used for all port types
86884 +
86885 + @Param[in] h_FmPort A handle to a FM Port module.
86886 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
86887 +
86888 + @Return E_OK on success; Error code otherwise.
86889 +
86890 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86891 +*//***************************************************************************/
86892 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
86893 +
86894 +/**************************************************************************//**
86895 + @Function FM_PORT_ConfigForwardReuseIntContext
86896 +
86897 + @Description This routine is relevant for Rx ports that are routed to OP port.
86898 + It changes the internal context reuse option in the internal
86899 + driver data base from its default configuration:
86900 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
86901 +
86902 + May be used for Rx ports only
86903 +
86904 + @Param[in] h_FmPort A handle to a FM Port module.
86905 + @Param[in] reuse TRUE to reuse internal context on frames
86906 + forwarded to OP port.
86907 +
86908 + @Return E_OK on success; Error code otherwise.
86909 +
86910 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86911 +*//***************************************************************************/
86912 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
86913 +
86914 +/**************************************************************************//**
86915 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
86916 +
86917 + @Description This routine should be called if no Tx confirmation
86918 + is done, and yet buffers should not be released to the BM.
86919 + Normally, buffers are returned using the Tx confirmation
86920 + process. When Tx confirmation is not used (defFqid=0),
86921 + buffers are typically released to the BM. This routine
86922 + may be called to avoid this behavior and not release the
86923 + buffers.
86924 +
86925 + May be used for Tx ports only
86926 +
86927 + @Param[in] h_FmPort A handle to a FM Port module.
86928 +
86929 + @Return E_OK on success; Error code otherwise.
86930 +
86931 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86932 +*//***************************************************************************/
86933 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
86934 +
86935 +/**************************************************************************//**
86936 + @Function FM_PORT_ConfigIMMaxRxBufLength
86937 +
86938 + @Description Changes the maximum receive buffer length from its default
86939 + configuration: Closest rounded down power of 2 value of the
86940 + data buffer size.
86941 +
86942 + The maximum receive buffer length directly affects the structure
86943 + of received frames (single- or multi-buffered) and the performance
86944 + of both the FM and the driver.
86945 +
86946 + The selection between single- or multi-buffered frames should be
86947 + done according to the characteristics of the specific application.
86948 + The recommended mode is to use a single data buffer per packet,
86949 + as this mode provides the best performance. However, the user can
86950 + select to use multiple data buffers per packet.
86951 +
86952 + @Param[in] h_FmPort A handle to a FM Port module.
86953 + @Param[in] newVal Maximum receive buffer length (in bytes).
86954 +
86955 + @Return E_OK on success; Error code otherwise.
86956 +
86957 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86958 + This routine is to be used only if Independent-Mode is enabled.
86959 +*//***************************************************************************/
86960 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
86961 +
86962 +/**************************************************************************//**
86963 + @Function FM_PORT_ConfigIMRxBdRingLength
86964 +
86965 + @Description Changes the receive BD ring length from its default
86966 + configuration:[DEFAULT_PORT_rxBdRingLength]
86967 +
86968 + @Param[in] h_FmPort A handle to a FM Port module.
86969 + @Param[in] newVal The desired BD ring length.
86970 +
86971 + @Return E_OK on success; Error code otherwise.
86972 +
86973 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86974 + This routine is to be used only if Independent-Mode is enabled.
86975 +*//***************************************************************************/
86976 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
86977 +
86978 +/**************************************************************************//**
86979 + @Function FM_PORT_ConfigIMTxBdRingLength
86980 +
86981 + @Description Changes the transmit BD ring length from its default
86982 + configuration:[DEFAULT_PORT_txBdRingLength]
86983 +
86984 + @Param[in] h_FmPort A handle to a FM Port module.
86985 + @Param[in] newVal The desired BD ring length.
86986 +
86987 + @Return E_OK on success; Error code otherwise.
86988 +
86989 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86990 + This routine is to be used only if Independent-Mode is enabled.
86991 +*//***************************************************************************/
86992 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
86993 +
86994 +/**************************************************************************//**
86995 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
86996 +
86997 + @Description Configures memory partition and attributes for FMan-Controller
86998 + data structures (e.g. BD rings).
86999 + Calling this routine changes the internal driver data base
87000 + from its default configuration
87001 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
87002 +
87003 + @Param[in] h_FmPort A handle to a FM Port module.
87004 + @Param[in] memId Memory partition ID.
87005 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
87006 +
87007 + @Return E_OK on success; Error code otherwise.
87008 +*//***************************************************************************/
87009 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
87010 + uint8_t memId,
87011 + uint32_t memAttributes);
87012 +
87013 +/**************************************************************************//**
87014 + @Function FM_PORT_ConfigIMPolling
87015 +
87016 + @Description Changes the Rx flow from interrupt driven (default) to polling.
87017 +
87018 + @Param[in] h_FmPort A handle to a FM Port module.
87019 +
87020 + @Return E_OK on success; Error code otherwise.
87021 +
87022 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87023 + This routine is to be used only if Independent-Mode is enabled.
87024 +*//***************************************************************************/
87025 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
87026 +
87027 +/**************************************************************************//**
87028 + @Function FM_PORT_ConfigMaxFrameLength
87029 +
87030 + @Description Changes the definition of the max size of frame that should be
87031 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
87032 + This parameter is used for confirmation of the minimum Fifo
87033 + size calculations and only for Tx ports or ports working in
87034 + independent mode. This should be larger than the maximum possible
87035 + MTU that will be used for this port (i.e. its MAC).
87036 +
87037 + @Param[in] h_FmPort A handle to a FM Port module.
87038 + @Param[in] length Max size of frame
87039 +
87040 + @Return E_OK on success; Error code otherwise.
87041 +
87042 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87043 + This routine is to be used only if Independent-Mode is enabled.
87044 +*//***************************************************************************/
87045 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
87046 +
87047 +/**************************************************************************//*
87048 + @Function FM_PORT_ConfigTxFifoMinFillLevel
87049 +
87050 + @Description Calling this routine changes the fifo minimum
87051 + fill level parameter in the internal driver data base
87052 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
87053 +
87054 + May be used for Tx ports only
87055 +
87056 + @Param[in] h_FmPort A handle to a FM Port module.
87057 + @Param[in] minFillLevel New value
87058 +
87059 + @Return E_OK on success; Error code otherwise.
87060 +
87061 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87062 +*//***************************************************************************/
87063 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
87064 +
87065 +/**************************************************************************//*
87066 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
87067 +
87068 + @Description Calling this routine changes the fifo dequeue
87069 + pipeline depth parameter in the internal driver data base
87070 +
87071 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
87072 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
87073 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
87074 +
87075 + May be used for Tx/OP ports only
87076 +
87077 + @Param[in] h_FmPort A handle to a FM Port module.
87078 + @Param[in] deqPipelineDepth New value
87079 +
87080 + @Return E_OK on success; Error code otherwise.
87081 +
87082 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87083 +*//***************************************************************************/
87084 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
87085 +
87086 +/**************************************************************************//*
87087 + @Function FM_PORT_ConfigTxFifoLowComfLevel
87088 +
87089 + @Description Calling this routine changes the fifo low comfort level
87090 + parameter in internal driver data base
87091 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
87092 +
87093 + May be used for Tx ports only
87094 +
87095 + @Param[in] h_FmPort A handle to a FM Port module.
87096 + @Param[in] fifoLowComfLevel New value
87097 +
87098 + @Return E_OK on success; Error code otherwise.
87099 +
87100 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87101 +*//***************************************************************************/
87102 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
87103 +
87104 +/**************************************************************************//*
87105 + @Function FM_PORT_ConfigRxFifoThreshold
87106 +
87107 + @Description Calling this routine changes the threshold of the FIFO
87108 + fill level parameter in the internal driver data base
87109 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
87110 +
87111 + If the total number of buffers which are
87112 + currently in use and associated with the
87113 + specific RX port exceed this threshold, the
87114 + BMI will signal the MAC to send a pause frame
87115 + over the link.
87116 +
87117 + May be used for Rx ports only
87118 +
87119 + @Param[in] h_FmPort A handle to a FM Port module.
87120 + @Param[in] fifoThreshold New value
87121 +
87122 + @Return E_OK on success; Error code otherwise.
87123 +
87124 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87125 +*//***************************************************************************/
87126 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
87127 +
87128 +/**************************************************************************//*
87129 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
87130 +
87131 + @Description Calling this routine changes the priority elevation level
87132 + parameter in the internal driver data base from its default
87133 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
87134 +
87135 + If the total number of buffers which are currently in use and
87136 + associated with the specific RX port exceed the amount specified
87137 + in priElevationLevel, BMI will signal the main FM's DMA to
87138 + elevate the FM priority on the system bus.
87139 +
87140 + May be used for Rx ports only
87141 +
87142 + @Param[in] h_FmPort A handle to a FM Port module.
87143 + @Param[in] priElevationLevel New value
87144 +
87145 + @Return E_OK on success; Error code otherwise.
87146 +
87147 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87148 +*//***************************************************************************/
87149 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
87150 +
87151 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
87152 +/**************************************************************************//*
87153 + @Function FM_PORT_ConfigBCBWorkaround
87154 +
87155 + @Description Configures BCB errata workaround.
87156 +
87157 + When BCB errata is applicable, the workaround is always
87158 + performed by FM Controller. Thus, this functions doesn't
87159 + actually enable errata workaround but rather allows driver
87160 + to perform adjustments required due to errata workaround
87161 + execution in FM controller.
87162 +
87163 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
87164 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
87165 + set by FM_PORT_SetErrorsRoute() function.
87166 +
87167 + @Param[in] h_FmPort A handle to a FM Port module.
87168 +
87169 + @Return E_OK on success; Error code otherwise.
87170 +
87171 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87172 +*//***************************************************************************/
87173 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
87174 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
87175 +
87176 +#if (DPAA_VERSION >= 11)
87177 +/**************************************************************************//*
87178 + @Function FM_PORT_ConfigInternalBuffOffset
87179 +
87180 + @Description Configures internal buffer offset.
87181 +
87182 + May be used for Rx and OP ports only
87183 +
87184 + @Param[in] h_FmPort A handle to a FM Port module.
87185 + @Param[in] val New value
87186 +
87187 + @Return E_OK on success; Error code otherwise.
87188 +
87189 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87190 +*//***************************************************************************/
87191 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
87192 +#endif /* (DPAA_VERSION >= 11) */
87193 +
87194 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
87195 +/** @} */ /* end of FM_PORT_init_grp group */
87196 +
87197 +
87198 +/**************************************************************************//**
87199 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
87200 +
87201 + @Description FM Port Runtime control unit API functions, definitions and enums.
87202 +
87203 + @{
87204 +*//***************************************************************************/
87205 +
87206 +/**************************************************************************//**
87207 + @Description enum for defining FM Port counters
87208 +*//***************************************************************************/
87209 +typedef enum e_FmPortCounters {
87210 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
87211 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
87212 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
87213 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
87214 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
87215 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
87216 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
87217 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
87218 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
87219 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
87220 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
87221 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
87222 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
87223 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
87224 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
87225 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
87226 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
87227 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
87228 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
87229 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
87230 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
87231 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
87232 +} e_FmPortCounters;
87233 +
87234 +typedef struct t_FmPortBmiStats {
87235 + uint32_t cntCycle;
87236 + uint32_t cntTaskUtil;
87237 + uint32_t cntQueueUtil;
87238 + uint32_t cntDmaUtil;
87239 + uint32_t cntFifoUtil;
87240 + uint32_t cntRxPauseActivation;
87241 + uint32_t cntFrame;
87242 + uint32_t cntDiscardFrame;
87243 + uint32_t cntDeallocBuf;
87244 + uint32_t cntRxBadFrame;
87245 + uint32_t cntRxLargeFrame;
87246 + uint32_t cntRxFilterFrame;
87247 + uint32_t cntRxListDmaErr;
87248 + uint32_t cntRxOutOfBuffersDiscard;
87249 + uint32_t cntWredDiscard;
87250 + uint32_t cntLengthErr;
87251 + uint32_t cntUnsupportedFormat;
87252 +} t_FmPortBmiStats;
87253 +
87254 +/**************************************************************************//**
87255 + @Description Structure for Port id parameters.
87256 + Fields commented 'IN' are passed by the port module to be used
87257 + by the FM module.
87258 + Fields commented 'OUT' will be filled by FM before returning to port.
87259 +*//***************************************************************************/
87260 +typedef struct t_FmPortCongestionGrps {
87261 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
87262 + to define the size of the following array */
87263 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
87264 + /**< An array of CG indexes;
87265 + Note that the size of the array should be
87266 + 'numOfCongestionGrpsToConsider'. */
87267 +#if (DPAA_VERSION >= 11)
87268 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
87269 + /**< a matrix that represents the map between the CG ids
87270 + defined in 'congestionGrpsToConsider' to the priorties
87271 + mapping array. */
87272 +#endif /* (DPAA_VERSION >= 11) */
87273 +} t_FmPortCongestionGrps;
87274 +
87275 +/**************************************************************************//**
87276 + @Description Structure for Deep Sleep Auto Response ARP Entry
87277 +*//***************************************************************************/
87278 +typedef struct t_FmPortDsarArpEntry
87279 +{
87280 + uint32_t ipAddress;
87281 + uint8_t mac[6];
87282 + bool isVlan;
87283 + uint16_t vid;
87284 +} t_FmPortDsarArpEntry;
87285 +
87286 +/**************************************************************************//**
87287 + @Description Structure for Deep Sleep Auto Response ARP info
87288 +*//***************************************************************************/
87289 +typedef struct t_FmPortDsarArpInfo
87290 +{
87291 + uint8_t tableSize;
87292 + t_FmPortDsarArpEntry *p_AutoResTable;
87293 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
87294 +} t_FmPortDsarArpInfo;
87295 +
87296 +/**************************************************************************//**
87297 + @Description Structure for Deep Sleep Auto Response NDP Entry
87298 +*//***************************************************************************/
87299 +typedef struct t_FmPortDsarNdpEntry
87300 +{
87301 + uint32_t ipAddress[4];
87302 + uint8_t mac[6];
87303 + bool isVlan;
87304 + uint16_t vid;
87305 +} t_FmPortDsarNdpEntry;
87306 +
87307 +/**************************************************************************//**
87308 + @Description Structure for Deep Sleep Auto Response NDP info
87309 +*//***************************************************************************/
87310 +typedef struct t_FmPortDsarNdpInfo
87311 +{
87312 + uint32_t multicastGroup;
87313 +
87314 + uint8_t tableSizeAssigned;
87315 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
87316 + Note that all IP adresses must be from the same multicast group.
87317 + This will be checked and if not operation will fail. */
87318 + uint8_t tableSizeTmp;
87319 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
87320 + Note that all temp IP adresses must be from the same multicast group.
87321 + This will be checked and if not operation will fail. */
87322 +
87323 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
87324 +
87325 +} t_FmPortDsarNdpInfo;
87326 +
87327 +/**************************************************************************//**
87328 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
87329 +*//***************************************************************************/
87330 +typedef struct t_FmPortDsarEchoIpv4Info
87331 +{
87332 + uint8_t tableSize;
87333 + t_FmPortDsarArpEntry *p_AutoResTable;
87334 +} t_FmPortDsarEchoIpv4Info;
87335 +
87336 +/**************************************************************************//**
87337 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
87338 +*//***************************************************************************/
87339 +typedef struct t_FmPortDsarEchoIpv6Info
87340 +{
87341 + uint8_t tableSize;
87342 + t_FmPortDsarNdpEntry *p_AutoResTable;
87343 +} t_FmPortDsarEchoIpv6Info;
87344 +
87345 +/**************************************************************************//**
87346 +@Description Deep Sleep Auto Response SNMP OIDs table entry
87347 +
87348 +*//***************************************************************************/
87349 +typedef struct {
87350 + uint16_t oidSize;
87351 + uint8_t *oidVal; /* only the oid string */
87352 + uint16_t resSize;
87353 + uint8_t *resVal; /* resVal will be the entire reply,
87354 + i.e. "Type|Length|Value" */
87355 +} t_FmPortDsarOidsEntry;
87356 +
87357 +/**************************************************************************//**
87358 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
87359 + Refer to the FMan Controller spec for more details.
87360 +*//***************************************************************************/
87361 +typedef struct
87362 +{
87363 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
87364 + bool isVlan;
87365 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
87366 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
87367 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
87368 +
87369 +/**************************************************************************//**
87370 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
87371 + Refer to the FMan Controller spec for more details.
87372 +*//***************************************************************************/
87373 +typedef struct
87374 +{
87375 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
87376 + bool isVlan;
87377 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
87378 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
87379 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
87380 +
87381 +/**************************************************************************//**
87382 + @Description Deep Sleep Auto Response SNMP Descriptor
87383 +
87384 +*//***************************************************************************/
87385 +typedef struct
87386 +{
87387 + uint16_t control; /**< Control bits [0-15]. */
87388 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
87389 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
87390 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
87391 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
87392 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
87393 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
87394 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
87395 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
87396 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
87397 +} t_FmPortDsarSnmpInfo;
87398 +
87399 +/**************************************************************************//**
87400 + @Description Structure for Deep Sleep Auto Response filtering Entry
87401 +*//***************************************************************************/
87402 +typedef struct t_FmPortDsarFilteringEntry
87403 +{
87404 + uint16_t srcPort;
87405 + uint16_t dstPort;
87406 + uint16_t srcPortMask;
87407 + uint16_t dstPortMask;
87408 +} t_FmPortDsarFilteringEntry;
87409 +
87410 +/**************************************************************************//**
87411 + @Description Structure for Deep Sleep Auto Response filtering info
87412 +*//***************************************************************************/
87413 +typedef struct t_FmPortDsarFilteringInfo
87414 +{
87415 + /* IP protocol filtering parameters */
87416 + uint8_t ipProtTableSize;
87417 + uint8_t *p_IpProtTablePtr;
87418 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
87419 + hit will pass the packet to UDP/TCP filters if needed and if not
87420 + to the classification tree. If the classification tree will pass
87421 + the packet to a queue it will cause a wake interupt.
87422 + When FALSE it the other way around. */
87423 + /* UDP port filtering parameters */
87424 + uint8_t udpPortsTableSize;
87425 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
87426 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
87427 + hit will pass the packet to classification tree.
87428 + If the classification tree will pass the packet to a queue it
87429 + will cause a wake interupt.
87430 + When FALSE it the other way around. */
87431 + /* TCP port filtering parameters */
87432 + uint16_t tcpFlagsMask;
87433 + uint8_t tcpPortsTableSize;
87434 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
87435 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
87436 + hit will pass the packet to classification tree.
87437 + If the classification tree will pass the packet to a queue it
87438 + will cause a wake interupt.
87439 + When FALSE it the other way around. */
87440 +} t_FmPortDsarFilteringInfo;
87441 +
87442 +/**************************************************************************//**
87443 + @Description Structure for Deep Sleep Auto Response parameters
87444 +*//***************************************************************************/
87445 +typedef struct t_FmPortDsarParams
87446 +{
87447 + t_Handle h_FmPortTx;
87448 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
87449 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
87450 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
87451 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
87452 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
87453 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
87454 +} t_FmPortDsarParams;
87455 +
87456 +/**************************************************************************//**
87457 + @Function FM_PORT_EnterDsar
87458 +
87459 + @Description Enter Deep Sleep Auto Response mode.
87460 + This function write the apropriate values to in the relevant
87461 + tables in the MURAM.
87462 +
87463 + @Param[in] h_FmPortRx - FM PORT module descriptor
87464 + @Param[in] params - Auto Response parameters
87465 +
87466 + @Return E_OK on success; Error code otherwise.
87467 +
87468 + @Cautions Allowed only following FM_PORT_Init().
87469 +*//***************************************************************************/
87470 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
87471 +
87472 +/**************************************************************************//**
87473 + @Function FM_PORT_EnterDsarFinal
87474 +
87475 + @Description Enter Deep Sleep Auto Response mode.
87476 + This function sets the Tx port in independent mode as needed
87477 + and redirect the receive flow to go through the
87478 + Dsar Fman-ctrl code
87479 +
87480 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
87481 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
87482 +
87483 + @Return E_OK on success; Error code otherwise.
87484 +
87485 + @Cautions Allowed only following FM_PORT_Init().
87486 +*//***************************************************************************/
87487 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
87488 +
87489 +/**************************************************************************//**
87490 + @Function FM_PORT_ExitDsar
87491 +
87492 + @Description Exit Deep Sleep Auto Response mode.
87493 + This function reverse the AR mode and put the ports back into
87494 + their original wake mode
87495 +
87496 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
87497 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
87498 +
87499 + @Return E_OK on success; Error code otherwise.
87500 +
87501 + @Cautions Allowed only following FM_PORT_EnterDsar().
87502 +*//***************************************************************************/
87503 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
87504 +
87505 +/**************************************************************************//**
87506 + @Function FM_PORT_IsInDsar
87507 +
87508 + @Description This function returns TRUE if the port was set as Auto Response
87509 + and FALSE if not. Once Exit AR mode it will return FALSE as well
87510 + until re-enabled once more.
87511 +
87512 + @Param[in] h_FmPort - FM PORT module descriptor
87513 +
87514 + @Return E_OK on success; Error code otherwise.
87515 +*//***************************************************************************/
87516 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
87517 +
87518 +typedef struct t_FmPortDsarStats
87519 +{
87520 + uint32_t arpArCnt;
87521 + uint32_t echoIcmpv4ArCnt;
87522 + uint32_t ndpArCnt;
87523 + uint32_t echoIcmpv6ArCnt;
87524 + uint32_t snmpGetCnt;
87525 + uint32_t snmpGetNextCnt;
87526 +} t_FmPortDsarStats;
87527 +
87528 +/**************************************************************************//**
87529 + @Function FM_PORT_GetDsarStats
87530 +
87531 + @Description Return statistics for Deep Sleep Auto Response
87532 +
87533 + @Param[in] h_FmPortRx - FM PORT module descriptor
87534 + @Param[out] stats - structure containing the statistics counters
87535 +
87536 + @Return E_OK on success; Error code otherwise.
87537 +*//***************************************************************************/
87538 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
87539 +
87540 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87541 +/**************************************************************************//**
87542 + @Function FM_PORT_DumpRegs
87543 +
87544 + @Description Dump all regs.
87545 +
87546 + Calling this routine invalidates the descriptor.
87547 +
87548 + @Param[in] h_FmPort - FM PORT module descriptor
87549 +
87550 + @Return E_OK on success; Error code otherwise.
87551 +
87552 + @Cautions Allowed only following FM_PORT_Init().
87553 +*//***************************************************************************/
87554 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
87555 +#endif /* (defined(DEBUG_ERRORS) && ... */
87556 +
87557 +/**************************************************************************//**
87558 + @Function FM_PORT_GetBufferDataOffset
87559 +
87560 + @Description Relevant for Rx ports.
87561 + Returns the data offset from the beginning of the data buffer
87562 +
87563 + @Param[in] h_FmPort - FM PORT module descriptor
87564 +
87565 + @Return data offset.
87566 +
87567 + @Cautions Allowed only following FM_PORT_Init().
87568 +*//***************************************************************************/
87569 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
87570 +
87571 +/**************************************************************************//**
87572 + @Function FM_PORT_GetBufferICInfo
87573 +
87574 + @Description Returns the Internal Context offset from the beginning of the data buffer
87575 +
87576 + @Param[in] h_FmPort - FM PORT module descriptor
87577 + @Param[in] p_Data - A pointer to the data buffer.
87578 +
87579 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
87580 + configured for this port.
87581 +
87582 + @Cautions Allowed only following FM_PORT_Init().
87583 +*//***************************************************************************/
87584 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
87585 +
87586 +/**************************************************************************//**
87587 + @Function FM_PORT_GetBufferPrsResult
87588 +
87589 + @Description Returns the pointer to the parse result in the data buffer.
87590 + In Rx ports this is relevant after reception, if parse
87591 + result is configured to be part of the data passed to the
87592 + application. For non Rx ports it may be used to get the pointer
87593 + of the area in the buffer where parse result should be
87594 + initialized - if so configured.
87595 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
87596 + configuration.
87597 +
87598 + @Param[in] h_FmPort - FM PORT module descriptor
87599 + @Param[in] p_Data - A pointer to the data buffer.
87600 +
87601 + @Return Parse result pointer on success, NULL if parse result was not
87602 + configured for this port.
87603 +
87604 + @Cautions Allowed only following FM_PORT_Init().
87605 +*//***************************************************************************/
87606 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
87607 +
87608 +/**************************************************************************//**
87609 + @Function FM_PORT_GetBufferTimeStamp
87610 +
87611 + @Description Returns the time stamp in the data buffer.
87612 + Relevant for Rx ports for getting the buffer time stamp.
87613 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
87614 + configuration.
87615 +
87616 + @Param[in] h_FmPort - FM PORT module descriptor
87617 + @Param[in] p_Data - A pointer to the data buffer.
87618 +
87619 + @Return A pointer to the hash result on success, NULL otherwise.
87620 +
87621 + @Cautions Allowed only following FM_PORT_Init().
87622 +*//***************************************************************************/
87623 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
87624 +
87625 +/**************************************************************************//**
87626 + @Function FM_PORT_GetBufferHashResult
87627 +
87628 + @Description Given a data buffer, on the condition that hash result was defined
87629 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
87630 + this routine will return the pointer to the hash result location in the
87631 + buffer prefix.
87632 +
87633 + @Param[in] h_FmPort - FM PORT module descriptor
87634 + @Param[in] p_Data - A pointer to the data buffer.
87635 +
87636 + @Return A pointer to the hash result on success, NULL otherwise.
87637 +
87638 + @Cautions Allowed only following FM_PORT_Init().
87639 +*//***************************************************************************/
87640 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
87641 +
87642 +/**************************************************************************//**
87643 + @Function FM_PORT_Disable
87644 +
87645 + @Description Gracefully disable an FM port. The port will not start new tasks after all
87646 + tasks associated with the port are terminated.
87647 +
87648 + @Param[in] h_FmPort A handle to a FM Port module.
87649 +
87650 + @Return E_OK on success; Error code otherwise.
87651 +
87652 + @Cautions Allowed only following FM_PORT_Init().
87653 + This is a blocking routine, it returns after port is
87654 + gracefully stopped, i.e. the port will not except new frames,
87655 + but it will finish all frames or tasks which were already began
87656 +*//***************************************************************************/
87657 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
87658 +
87659 +/**************************************************************************//**
87660 + @Function FM_PORT_Enable
87661 +
87662 + @Description A runtime routine provided to allow disable/enable of port.
87663 +
87664 + @Param[in] h_FmPort A handle to a FM Port module.
87665 +
87666 + @Return E_OK on success; Error code otherwise.
87667 +
87668 + @Cautions Allowed only following FM_PORT_Init().
87669 +*//***************************************************************************/
87670 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
87671 +
87672 +/**************************************************************************//**
87673 + @Function FM_PORT_SetRateLimit
87674 +
87675 + @Description Calling this routine enables rate limit algorithm.
87676 + By default, this functionality is disabled.
87677 + Note that rate-limit mechanism uses the FM time stamp.
87678 + The selected rate limit specified here would be
87679 + rounded DOWN to the nearest 16M.
87680 +
87681 + May be used for Tx and OP ports only
87682 +
87683 + @Param[in] h_FmPort A handle to a FM Port module.
87684 + @Param[in] p_RateLimit A structure of rate limit parameters
87685 +
87686 + @Return E_OK on success; Error code otherwise.
87687 +
87688 + @Cautions Allowed only following FM_PORT_Init().
87689 + If rate limit is set on a port that need to send PFC frames,
87690 + it might violate the stop transmit timing.
87691 +*//***************************************************************************/
87692 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
87693 +
87694 +/**************************************************************************//**
87695 + @Function FM_PORT_DeleteRateLimit
87696 +
87697 + @Description Calling this routine disables and clears rate limit
87698 + initialization.
87699 +
87700 + May be used for Tx and OP ports only
87701 +
87702 + @Param[in] h_FmPort A handle to a FM Port module.
87703 +
87704 + @Return E_OK on success; Error code otherwise.
87705 +
87706 + @Cautions Allowed only following FM_PORT_Init().
87707 +*//***************************************************************************/
87708 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
87709 +
87710 +/**************************************************************************//**
87711 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
87712 +
87713 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
87714 + This WQ will be blocked upon receiving a PFC frame with this priority.
87715 +
87716 + May be used for Tx ports only.
87717 +
87718 + @Param[in] h_FmPort A handle to a FM Port module.
87719 + @Param[in] prio PFC priority (0-7).
87720 + @Param[in] wq Work Queue (0-7).
87721 +
87722 + @Return E_OK on success; Error code otherwise.
87723 +
87724 + @Cautions Allowed only following FM_PORT_Init().
87725 +*//***************************************************************************/
87726 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
87727 +
87728 +/**************************************************************************//**
87729 + @Function FM_PORT_SetStatisticsCounters
87730 +
87731 + @Description Calling this routine enables/disables port's statistics counters.
87732 + By default, counters are enabled.
87733 +
87734 + May be used for all port types
87735 +
87736 + @Param[in] h_FmPort A handle to a FM Port module.
87737 + @Param[in] enable TRUE to enable, FALSE to disable.
87738 +
87739 + @Return E_OK on success; Error code otherwise.
87740 +
87741 + @Cautions Allowed only following FM_PORT_Init().
87742 +*//***************************************************************************/
87743 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
87744 +
87745 +/**************************************************************************//**
87746 + @Function FM_PORT_SetFrameQueueCounters
87747 +
87748 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
87749 + By default, counters are enabled.
87750 +
87751 + May be used for all ports
87752 +
87753 + @Param[in] h_FmPort A handle to a FM Port module.
87754 + @Param[in] enable TRUE to enable, FALSE to disable.
87755 +
87756 + @Return E_OK on success; Error code otherwise.
87757 +
87758 + @Cautions Allowed only following FM_PORT_Init().
87759 +*//***************************************************************************/
87760 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
87761 +
87762 +/**************************************************************************//**
87763 + @Function FM_PORT_AnalyzePerformanceParams
87764 +
87765 + @Description User may call this routine to so the driver will analyze if the
87766 + basic performance parameters are correct and also the driver may
87767 + suggest of improvements; The basic parameters are FIFO sizes, number
87768 + of DMAs and number of TNUMs for the port.
87769 +
87770 + May be used for all port types
87771 +
87772 + @Param[in] h_FmPort A handle to a FM Port module.
87773 +
87774 + @Return E_OK on success; Error code otherwise.
87775 +
87776 + @Cautions Allowed only following FM_PORT_Init().
87777 +*//***************************************************************************/
87778 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
87779 +
87780 +
87781 +/**************************************************************************//**
87782 + @Function FM_PORT_SetAllocBufCounter
87783 +
87784 + @Description Calling this routine enables/disables BM pool allocate
87785 + buffer counters.
87786 + By default, counters are enabled.
87787 +
87788 + May be used for Rx ports only
87789 +
87790 + @Param[in] h_FmPort A handle to a FM Port module.
87791 + @Param[in] poolId BM pool id.
87792 + @Param[in] enable TRUE to enable, FALSE to disable.
87793 +
87794 + @Return E_OK on success; Error code otherwise.
87795 +
87796 + @Cautions Allowed only following FM_PORT_Init().
87797 +*//***************************************************************************/
87798 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
87799 +
87800 +/**************************************************************************//**
87801 + @Function FM_PORT_GetBmiCounters
87802 +
87803 + @Description Read port's BMI stat counters and place them into
87804 + a designated structure of counters.
87805 +
87806 + @Param[in] h_FmPort A handle to a FM Port module.
87807 + @Param[out] p_BmiStats counters structure
87808 +
87809 + @Return E_OK on success; Error code otherwise.
87810 +
87811 + @Cautions Allowed only following FM_PORT_Init().
87812 +*//***************************************************************************/
87813 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
87814 +
87815 +/**************************************************************************//**
87816 + @Function FM_PORT_GetCounter
87817 +
87818 + @Description Reads one of the FM PORT counters.
87819 +
87820 + @Param[in] h_FmPort A handle to a FM Port module.
87821 + @Param[in] fmPortCounter The requested counter.
87822 +
87823 + @Return Counter's current value.
87824 +
87825 + @Cautions Allowed only following FM_PORT_Init().
87826 + Note that it is user's responsibility to call this routine only
87827 + for enabled counters, and there will be no indication if a
87828 + disabled counter is accessed.
87829 +*//***************************************************************************/
87830 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
87831 +
87832 +/**************************************************************************//**
87833 + @Function FM_PORT_ModifyCounter
87834 +
87835 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
87836 +
87837 + @Param[in] h_FmPort A handle to a FM Port module.
87838 + @Param[in] fmPortCounter The requested counter.
87839 + @Param[in] value The requested value to be written into the counter.
87840 +
87841 + @Return E_OK on success; Error code otherwise.
87842 +
87843 + @Cautions Allowed only following FM_PORT_Init().
87844 +*//***************************************************************************/
87845 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
87846 +
87847 +/**************************************************************************//**
87848 + @Function FM_PORT_GetAllocBufCounter
87849 +
87850 + @Description Reads one of the FM PORT buffer counters.
87851 +
87852 + @Param[in] h_FmPort A handle to a FM Port module.
87853 + @Param[in] poolId The requested pool.
87854 +
87855 + @Return Counter's current value.
87856 +
87857 + @Cautions Allowed only following FM_PORT_Init().
87858 + Note that it is user's responsibility to call this routine only
87859 + for enabled counters, and there will be no indication if a
87860 + disabled counter is accessed.
87861 +*//***************************************************************************/
87862 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
87863 +
87864 +/**************************************************************************//**
87865 + @Function FM_PORT_ModifyAllocBufCounter
87866 +
87867 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
87868 +
87869 + @Param[in] h_FmPort A handle to a FM Port module.
87870 + @Param[in] poolId The requested pool.
87871 + @Param[in] value The requested value to be written into the counter.
87872 +
87873 + @Return E_OK on success; Error code otherwise.
87874 +
87875 + @Cautions Allowed only following FM_PORT_Init().
87876 +*//***************************************************************************/
87877 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
87878 +
87879 +/**************************************************************************//**
87880 + @Function FM_PORT_AddCongestionGrps
87881 +
87882 + @Description This routine effects the corresponding Tx port.
87883 + It should be called in order to enable pause
87884 + frame transmission in case of congestion in one or more
87885 + of the congestion groups relevant to this port.
87886 + Each call to this routine may add one or more congestion
87887 + groups to be considered relevant to this port.
87888 +
87889 + May be used for Rx, or RX+OP ports only (depending on chip)
87890 +
87891 + @Param[in] h_FmPort A handle to a FM Port module.
87892 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
87893 + id's to consider.
87894 +
87895 + @Return E_OK on success; Error code otherwise.
87896 +
87897 + @Cautions Allowed only following FM_PORT_Init().
87898 +*//***************************************************************************/
87899 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
87900 +
87901 +/**************************************************************************//**
87902 + @Function FM_PORT_RemoveCongestionGrps
87903 +
87904 + @Description This routine effects the corresponding Tx port. It should be
87905 + called when congestion groups were
87906 + defined for this port and are no longer relevant, or pause
87907 + frames transmitting is not required on their behalf.
87908 + Each call to this routine may remove one or more congestion
87909 + groups to be considered relevant to this port.
87910 +
87911 + May be used for Rx, or RX+OP ports only (depending on chip)
87912 +
87913 + @Param[in] h_FmPort A handle to a FM Port module.
87914 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
87915 + id's to consider.
87916 +
87917 + @Return E_OK on success; Error code otherwise.
87918 +
87919 + @Cautions Allowed only following FM_PORT_Init().
87920 +*//***************************************************************************/
87921 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
87922 +
87923 +/**************************************************************************//**
87924 + @Function FM_PORT_IsStalled
87925 +
87926 + @Description A routine for checking whether the specified port is stalled.
87927 +
87928 + @Param[in] h_FmPort A handle to a FM Port module.
87929 +
87930 + @Return TRUE if port is stalled, FALSE otherwize
87931 +
87932 + @Cautions Allowed only following FM_PORT_Init().
87933 +*//***************************************************************************/
87934 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
87935 +
87936 +/**************************************************************************//**
87937 + @Function FM_PORT_ReleaseStalled
87938 +
87939 + @Description This routine may be called in case the port was stalled and may
87940 + now be released.
87941 + Note that this routine is available only on older FMan revisions
87942 + (FMan v2, DPAA v1.0 only).
87943 +
87944 + @Param[in] h_FmPort A handle to a FM Port module.
87945 +
87946 + @Return E_OK on success; Error code otherwise.
87947 +
87948 + @Cautions Allowed only following FM_PORT_Init().
87949 +*//***************************************************************************/
87950 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
87951 +
87952 +/**************************************************************************//**
87953 + @Function FM_PORT_SetRxL4ChecksumVerify
87954 +
87955 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
87956 + set/clear the L3/L4 checksum verification (on RX side).
87957 + Note that this takes affect only if hw-parser is enabled!
87958 +
87959 + @Param[in] h_FmPort A handle to a FM Port module.
87960 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
87961 + on frames or not.
87962 +
87963 + @Return E_OK on success; Error code otherwise.
87964 +
87965 + @Cautions Allowed only following FM_PORT_Init().
87966 +*//***************************************************************************/
87967 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
87968 +
87969 +/**************************************************************************//**
87970 + @Function FM_PORT_SetErrorsRoute
87971 +
87972 + @Description Errors selected for this routine will cause a frame with that error
87973 + to be enqueued to error queue.
87974 + Errors not selected for this routine will cause a frame with that error
87975 + to be enqueued to the one of the other port queues.
87976 + By default all errors are defined to be enqueued to error queue.
87977 + Errors that were configured to be discarded (at initialization)
87978 + may not be selected here.
87979 +
87980 + May be used for Rx and OP ports only
87981 +
87982 + @Param[in] h_FmPort A handle to a FM Port module.
87983 + @Param[in] errs A list of errors to enqueue to error queue
87984 +
87985 + @Return E_OK on success; Error code otherwise.
87986 +
87987 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87988 +*//***************************************************************************/
87989 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
87990 +
87991 +/**************************************************************************//**
87992 + @Function FM_PORT_SetIMExceptions
87993 +
87994 + @Description Calling this routine enables/disables FM PORT interrupts.
87995 +
87996 + @Param[in] h_FmPort FM PORT module descriptor.
87997 + @Param[in] exception The exception to be selected.
87998 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
87999 +
88000 + @Return E_OK on success; Error code otherwise.
88001 +
88002 + @Cautions Allowed only following FM_PORT_Init().
88003 + This routine should NOT be called from guest-partition
88004 + (i.e. guestId != NCSW_MASTER_ID)
88005 +*//***************************************************************************/
88006 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
88007 +
88008 +/**************************************************************************//*
88009 + @Function FM_PORT_SetPerformanceCounters
88010 +
88011 + @Description Calling this routine enables/disables port's performance counters.
88012 + By default, counters are enabled.
88013 +
88014 + May be used for all port types
88015 +
88016 + @Param[in] h_FmPort A handle to a FM Port module.
88017 + @Param[in] enable TRUE to enable, FALSE to disable.
88018 +
88019 + @Return E_OK on success; Error code otherwise.
88020 +
88021 + @Cautions Allowed only following FM_PORT_Init().
88022 +*//***************************************************************************/
88023 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
88024 +
88025 +/**************************************************************************//*
88026 + @Function FM_PORT_SetPerformanceCountersParams
88027 +
88028 + @Description Calling this routine defines port's performance
88029 + counters parameters.
88030 +
88031 + May be used for all port types
88032 +
88033 + @Param[in] h_FmPort A handle to a FM Port module.
88034 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
88035 + counters parameters.
88036 +
88037 + @Return E_OK on success; Error code otherwise.
88038 +
88039 + @Cautions Allowed only following FM_PORT_Init().
88040 +*//***************************************************************************/
88041 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
88042 +
88043 +/**************************************************************************//**
88044 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
88045 +
88046 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
88047 +
88048 + @{
88049 +*//***************************************************************************/
88050 +
88051 +/**************************************************************************//**
88052 + @Description A structure defining the KG scheme after the parser.
88053 + This is relevant only to change scheme selection mode - from
88054 + direct to indirect and vice versa, or when the scheme is selected directly,
88055 + to select the scheme id.
88056 +
88057 +*//***************************************************************************/
88058 +typedef struct t_FmPcdKgSchemeSelect {
88059 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
88060 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
88061 + Relevant only when 'direct' is TRUE. */
88062 +} t_FmPcdKgSchemeSelect;
88063 +
88064 +/**************************************************************************//**
88065 + @Description A structure of scheme parameters
88066 +*//***************************************************************************/
88067 +typedef struct t_FmPcdPortSchemesParams {
88068 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
88069 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
88070 + port to be bound to */
88071 +} t_FmPcdPortSchemesParams;
88072 +
88073 +/**************************************************************************//**
88074 + @Description Union for defining port protocol parameters for parser
88075 +*//***************************************************************************/
88076 +typedef union u_FmPcdHdrPrsOpts {
88077 + /* MPLS */
88078 + struct {
88079 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
88080 + interpreted as described in HW spec table. When the bit
88081 + is cleared, the parser will advance to MPLS next parse */
88082 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
88083 + } mplsPrsOptions;
88084 + /* VLAN */
88085 + struct {
88086 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
88087 + on VLAN TAG on top of 0x8100 and 0x88A8 */
88088 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
88089 + on VLAN TAG on top of 0x8100 and 0x88A8 */
88090 + } vlanPrsOptions;
88091 + /* PPP */
88092 + struct{
88093 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
88094 + } pppoePrsOptions;
88095 +
88096 + /* IPV6 */
88097 + struct{
88098 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
88099 + } ipv6PrsOptions;
88100 +
88101 + /* UDP */
88102 + struct{
88103 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
88104 + } udpPrsOptions;
88105 +
88106 + /* TCP */
88107 + struct {
88108 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
88109 + } tcpPrsOptions;
88110 +} u_FmPcdHdrPrsOpts;
88111 +
88112 +/**************************************************************************//**
88113 + @Description A structure for defining each header for the parser
88114 +*//***************************************************************************/
88115 +typedef struct t_FmPcdPrsAdditionalHdrParams {
88116 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
88117 + to indicate that sw parser is to run first
88118 + (before HW parser, and independent of the
88119 + existence of any protocol), in this case,
88120 + swPrsEnable must be set, and all other
88121 + parameters are irrelevant. */
88122 + bool errDisable; /**< TRUE to disable error indication */
88123 + bool swPrsEnable; /**< Enable jump to SW parser when this
88124 + header is recognized by the HW parser. */
88125 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
88126 + attachments exists for the same header,
88127 + (in the main sw parser code) use this
88128 + index to distinguish between them. */
88129 + bool usePrsOpts; /**< TRUE to use parser options. */
88130 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
88131 + defining the parser options selected.*/
88132 +} t_FmPcdPrsAdditionalHdrParams;
88133 +
88134 +/**************************************************************************//**
88135 + @Description struct for defining port PCD parameters
88136 +*//***************************************************************************/
88137 +typedef struct t_FmPortPcdPrsParams {
88138 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
88139 + port information into the parser result. This information
88140 + may be extracted by Keygen and be used for frames
88141 + distribution when a per-port distinction is required,
88142 + it may also be used as a port logical id for analyzing
88143 + incoming frames. */
88144 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
88145 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
88146 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
88147 + NOTE: this field is not valid when the FM is in "guest" mode
88148 + and IPC is not available. */
88149 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
88150 + special parameters */
88151 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
88152 + /**< 'numOfHdrsWithAdditionalParams' structures
88153 + of additional parameters
88154 + for each header that requires them */
88155 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
88156 + indicate a VLAN tag (in addition to the TPID values
88157 + 0x8100 and 0x88A8). */
88158 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
88159 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
88160 + indicate a VLAN tag (in addition to the TPID values
88161 + 0x8100 and 0x88A8). */
88162 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
88163 +} t_FmPortPcdPrsParams;
88164 +
88165 +/**************************************************************************//**
88166 + @Description struct for defining coarse alassification parameters
88167 +*//***************************************************************************/
88168 +typedef struct t_FmPortPcdCcParams {
88169 + t_Handle h_CcTree; /**< A handle to a CC tree */
88170 +} t_FmPortPcdCcParams;
88171 +
88172 +/**************************************************************************//**
88173 + @Description struct for defining keygen parameters
88174 +*//***************************************************************************/
88175 +typedef struct t_FmPortPcdKgParams {
88176 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
88177 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
88178 + /**< Array of 'numOfSchemes' schemes handles for the
88179 + port to be bound to */
88180 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
88181 + regardless of parser result */
88182 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
88183 + as returned by FM_PCD_KgSetScheme */
88184 +} t_FmPortPcdKgParams;
88185 +
88186 +/**************************************************************************//**
88187 + @Description struct for defining policer parameters
88188 +*//***************************************************************************/
88189 +typedef struct t_FmPortPcdPlcrParams {
88190 + t_Handle h_Profile; /**< Selected profile handle */
88191 +} t_FmPortPcdPlcrParams;
88192 +
88193 +/**************************************************************************//**
88194 + @Description struct for defining port PCD parameters
88195 +*//***************************************************************************/
88196 +typedef struct t_FmPortPcdParams {
88197 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
88198 + Describes the active PCD engines for this port. */
88199 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
88200 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
88201 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
88202 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
88203 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
88204 + following cases:
88205 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
88206 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
88207 + or if any flow uses a KG scheme were policer
88208 + profile is not generated
88209 + ('bypassPlcrProfileGeneration selected'). */
88210 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
88211 +#if (DPAA_VERSION >= 11)
88212 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
88213 +#endif /* (DPAA_VERSION >= 11) */
88214 +} t_FmPortPcdParams;
88215 +
88216 +/**************************************************************************//**
88217 + @Description A structure for defining the Parser starting point
88218 +*//***************************************************************************/
88219 +typedef struct t_FmPcdPrsStart {
88220 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
88221 + start parsing */
88222 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
88223 + 'parsingOffset' */
88224 +} t_FmPcdPrsStart;
88225 +
88226 +#if (DPAA_VERSION >= 11)
88227 +/**************************************************************************//**
88228 + @Description struct for defining external buffer margins
88229 +*//***************************************************************************/
88230 +typedef struct t_FmPortVSPAllocParams {
88231 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
88232 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
88233 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
88234 + if relevant function called for Rx port */
88235 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
88236 +} t_FmPortVSPAllocParams;
88237 +#endif /* (DPAA_VERSION >= 11) */
88238 +
88239 +
88240 +/**************************************************************************//**
88241 + @Function FM_PORT_SetPCD
88242 +
88243 + @Description Calling this routine defines the port's PCD configuration.
88244 + It changes it from its default configuration which is PCD
88245 + disabled (BMI to BMI) and configures it according to the passed
88246 + parameters.
88247 +
88248 + May be used for Rx and OP ports only
88249 +
88250 + @Param[in] h_FmPort A handle to a FM Port module.
88251 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
88252 + configuration.
88253 +
88254 + @Return E_OK on success; Error code otherwise.
88255 +
88256 + @Cautions Allowed only following FM_PORT_Init().
88257 +*//***************************************************************************/
88258 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
88259 +
88260 +/**************************************************************************//**
88261 + @Function FM_PORT_DeletePCD
88262 +
88263 + @Description Calling this routine releases the port's PCD configuration.
88264 + The port returns to its default configuration which is PCD
88265 + disabled (BMI to BMI) and all PCD configuration is removed.
88266 +
88267 + May be used for Rx and OP ports which are
88268 + in PCD mode only
88269 +
88270 + @Param[in] h_FmPort A handle to a FM Port module.
88271 +
88272 + @Return E_OK on success; Error code otherwise.
88273 +
88274 + @Cautions Allowed only following FM_PORT_Init().
88275 +*//***************************************************************************/
88276 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
88277 +
88278 +/**************************************************************************//**
88279 + @Function FM_PORT_AttachPCD
88280 +
88281 + @Description This routine may be called after FM_PORT_DetachPCD was called,
88282 + to return to the originally configured PCD support flow.
88283 + The couple of routines are used to allow PCD configuration changes
88284 + that demand that PCD will not be used while changes take place.
88285 +
88286 + May be used for Rx and OP ports which are
88287 + in PCD mode only
88288 +
88289 + @Param[in] h_FmPort A handle to a FM Port module.
88290 +
88291 + @Return E_OK on success; Error code otherwise.
88292 +
88293 + @Cautions Allowed only following FM_PORT_Init().
88294 +*//***************************************************************************/
88295 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
88296 +
88297 +/**************************************************************************//**
88298 + @Function FM_PORT_DetachPCD
88299 +
88300 + @Description Calling this routine detaches the port from its PCD functionality.
88301 + The port returns to its default flow which is BMI to BMI.
88302 +
88303 + May be used for Rx and OP ports which are
88304 + in PCD mode only
88305 +
88306 + @Param[in] h_FmPort A handle to a FM Port module.
88307 +
88308 + @Return E_OK on success; Error code otherwise.
88309 +
88310 + @Cautions Allowed only following FM_PORT_AttachPCD().
88311 +*//***************************************************************************/
88312 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
88313 +
88314 +/**************************************************************************//**
88315 + @Function FM_PORT_PcdPlcrAllocProfiles
88316 +
88317 + @Description This routine may be called only for ports that use the Policer in
88318 + order to allocate private policer profiles.
88319 +
88320 + @Param[in] h_FmPort A handle to a FM Port module.
88321 + @Param[in] numOfProfiles The number of required policer profiles
88322 +
88323 + @Return E_OK on success; Error code otherwise.
88324 +
88325 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
88326 + and before FM_PORT_SetPCD().
88327 +*//***************************************************************************/
88328 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
88329 +
88330 +/**************************************************************************//**
88331 + @Function FM_PORT_PcdPlcrFreeProfiles
88332 +
88333 + @Description This routine should be called for freeing private policer profiles.
88334 +
88335 + @Param[in] h_FmPort A handle to a FM Port module.
88336 +
88337 + @Return E_OK on success; Error code otherwise.
88338 +
88339 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
88340 + and before FM_PORT_SetPCD().
88341 +*//***************************************************************************/
88342 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
88343 +
88344 +#if (DPAA_VERSION >= 11)
88345 +/**************************************************************************//**
88346 + @Function FM_PORT_VSPAlloc
88347 +
88348 + @Description This routine allocated VSPs per port and forces the port to work
88349 + in VSP mode. Note that the port is initialized by default with the
88350 + physical-storage-profile only.
88351 +
88352 + @Param[in] h_FmPort A handle to a FM Port module.
88353 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
88354 +
88355 + @Return E_OK on success; Error code otherwise.
88356 +
88357 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
88358 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
88359 +*//***************************************************************************/
88360 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
88361 +#endif /* (DPAA_VERSION >= 11) */
88362 +
88363 +/**************************************************************************//**
88364 + @Function FM_PORT_PcdKgModifyInitialScheme
88365 +
88366 + @Description This routine may be called only for ports that use the keygen in
88367 + order to change the initial scheme frame should be routed to.
88368 + The change may be of a scheme id (in case of direct mode),
88369 + from direct to indirect, or from indirect to direct - specifying the scheme id.
88370 +
88371 + @Param[in] h_FmPort A handle to a FM Port module.
88372 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
88373 + a scheme is direct/indirect, and if direct - scheme id.
88374 +
88375 + @Return E_OK on success; Error code otherwise.
88376 +
88377 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88378 +*//***************************************************************************/
88379 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
88380 +
88381 +/**************************************************************************//**
88382 + @Function FM_PORT_PcdPlcrModifyInitialProfile
88383 +
88384 + @Description This routine may be called for ports with flows
88385 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
88386 + only, to change the initial Policer profile frame should be
88387 + routed to. The change may be of a profile and/or absolute/direct
88388 + mode selection.
88389 +
88390 + @Param[in] h_FmPort A handle to a FM Port module.
88391 + @Param[in] h_Profile Policer profile handle
88392 +
88393 + @Return E_OK on success; Error code otherwise.
88394 +
88395 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88396 +*//***************************************************************************/
88397 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
88398 +
88399 +/**************************************************************************//**
88400 + @Function FM_PORT_PcdCcModifyTree
88401 +
88402 + @Description This routine may be called for ports that use coarse classification tree
88403 + if the user wishes to replace the tree. The routine may not be called while port
88404 + receives packets using the PCD functionalities, therefor port must be first detached
88405 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
88406 +
88407 + @Param[in] h_FmPort A handle to a FM Port module.
88408 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
88409 + the BuildTree routine.
88410 +
88411 + @Return E_OK on success; Error code otherwise.
88412 +
88413 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
88414 +*//***************************************************************************/
88415 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
88416 +
88417 +/**************************************************************************//**
88418 + @Function FM_PORT_PcdKgBindSchemes
88419 +
88420 + @Description These routines may be called for adding more schemes for the
88421 + port to be bound to. The selected schemes are not added,
88422 + just this specific port starts using them.
88423 +
88424 + @Param[in] h_FmPort A handle to a FM Port module.
88425 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
88426 +
88427 + @Return E_OK on success; Error code otherwise.
88428 +
88429 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88430 +*//***************************************************************************/
88431 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
88432 +
88433 +/**************************************************************************//**
88434 + @Function FM_PORT_PcdKgUnbindSchemes
88435 +
88436 + @Description These routines may be called for adding more schemes for the
88437 + port to be bound to. The selected schemes are not removed or invalidated,
88438 + just this specific port stops using them.
88439 +
88440 + @Param[in] h_FmPort A handle to a FM Port module.
88441 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
88442 +
88443 + @Return E_OK on success; Error code otherwise.
88444 +
88445 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88446 +*//***************************************************************************/
88447 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
88448 +
88449 +/**************************************************************************//**
88450 + @Function FM_PORT_GetIPv4OptionsCount
88451 +
88452 + @Description TODO
88453 +
88454 + @Param[in] h_FmPort A handle to a FM Port module.
88455 + @Param[out] p_Ipv4OptionsCount will hold the counter value
88456 +
88457 + @Return E_OK on success; Error code otherwise.
88458 +
88459 + @Cautions Allowed only following FM_PORT_Init()
88460 +*//***************************************************************************/
88461 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
88462 +
88463 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
88464 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
88465 +
88466 +
88467 +/**************************************************************************//**
88468 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
88469 +
88470 + @Description FM Port Runtime data unit API functions, definitions and enums.
88471 + This API is valid only if working in Independent-Mode.
88472 +
88473 + @{
88474 +*//***************************************************************************/
88475 +
88476 +/**************************************************************************//**
88477 + @Function FM_PORT_ImTx
88478 +
88479 + @Description Tx function, called to transmit a data buffer on the port.
88480 +
88481 + @Param[in] h_FmPort A handle to a FM Port module.
88482 + @Param[in] p_Data A pointer to an LCP data buffer.
88483 + @Param[in] length Size of data for transmission.
88484 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
88485 + of a frame, including a single buffer frame
88486 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
88487 +
88488 + @Return E_OK on success; Error code otherwise.
88489 +
88490 + @Cautions Allowed only following FM_PORT_Init().
88491 + NOTE - This routine can be used only when working in
88492 + Independent-Mode mode.
88493 +*//***************************************************************************/
88494 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
88495 + uint8_t *p_Data,
88496 + uint16_t length,
88497 + bool lastBuffer,
88498 + t_Handle h_BufContext);
88499 +
88500 +/**************************************************************************//**
88501 + @Function FM_PORT_ImTxConf
88502 +
88503 + @Description Tx port confirmation routine, optional, may be called to verify
88504 + transmission of all frames. The procedure performed by this
88505 + routine will be performed automatically on next buffer transmission,
88506 + but if desired, calling this routine will invoke this action on
88507 + demand.
88508 +
88509 + @Param[in] h_FmPort A handle to a FM Port module.
88510 +
88511 + @Cautions Allowed only following FM_PORT_Init().
88512 + NOTE - This routine can be used only when working in
88513 + Independent-Mode mode.
88514 +*//***************************************************************************/
88515 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
88516 +
88517 +/**************************************************************************//**
88518 + @Function FM_PORT_ImRx
88519 +
88520 + @Description Rx function, may be called to poll for received buffers.
88521 + Normally, Rx process is invoked by the driver on Rx interrupt.
88522 + Alternatively, this routine may be called on demand.
88523 +
88524 + @Param[in] h_FmPort A handle to a FM Port module.
88525 +
88526 + @Return E_OK on success; Error code otherwise.
88527 +
88528 + @Cautions Allowed only following FM_PORT_Init().
88529 + NOTE - This routine can be used only when working in
88530 + Independent-Mode mode.
88531 +*//***************************************************************************/
88532 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
88533 +
88534 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
88535 +/** @} */ /* end of FM_PORT_grp group */
88536 +/** @} */ /* end of FM_grp group */
88537 +
88538 +
88539 +
88540 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
88541 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
88542 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
88543 +
88544 +
88545 +#endif /* __FM_PORT_EXT */
88546 --- /dev/null
88547 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
88548 @@ -0,0 +1,619 @@
88549 +/*
88550 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88551 + *
88552 + * Redistribution and use in source and binary forms, with or without
88553 + * modification, are permitted provided that the following conditions are met:
88554 + * * Redistributions of source code must retain the above copyright
88555 + * notice, this list of conditions and the following disclaimer.
88556 + * * Redistributions in binary form must reproduce the above copyright
88557 + * notice, this list of conditions and the following disclaimer in the
88558 + * documentation and/or other materials provided with the distribution.
88559 + * * Neither the name of Freescale Semiconductor nor the
88560 + * names of its contributors may be used to endorse or promote products
88561 + * derived from this software without specific prior written permission.
88562 + *
88563 + *
88564 + * ALTERNATIVELY, this software may be distributed under the terms of the
88565 + * GNU General Public License ("GPL") as published by the Free Software
88566 + * Foundation, either version 2 of that License or (at your option) any
88567 + * later version.
88568 + *
88569 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88570 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88571 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88572 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88573 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88574 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88575 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88576 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88577 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88578 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88579 + */
88580 +
88581 +
88582 +/**************************************************************************//**
88583 + @File fm_rtc_ext.h
88584 +
88585 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
88586 +
88587 + @Cautions None.
88588 +*//***************************************************************************/
88589 +
88590 +#ifndef __FM_RTC_EXT_H__
88591 +#define __FM_RTC_EXT_H__
88592 +
88593 +
88594 +#include "error_ext.h"
88595 +#include "std_ext.h"
88596 +#include "fsl_fman_rtc.h"
88597 +
88598 +/**************************************************************************//**
88599 +
88600 + @Group FM_grp Frame Manager API
88601 +
88602 + @Description FM API functions, definitions and enums
88603 +
88604 + @{
88605 +*//***************************************************************************/
88606 +
88607 +/**************************************************************************//**
88608 + @Group fm_rtc_grp FM RTC
88609 +
88610 + @Description FM RTC functions, definitions and enums.
88611 +
88612 + @{
88613 +*//***************************************************************************/
88614 +
88615 +/**************************************************************************//**
88616 + @Group fm_rtc_init_grp FM RTC Initialization Unit
88617 +
88618 + @Description FM RTC initialization API.
88619 +
88620 + @{
88621 +*//***************************************************************************/
88622 +
88623 +/**************************************************************************//**
88624 + @Description FM RTC Alarm Polarity Options.
88625 +*//***************************************************************************/
88626 +typedef enum e_FmRtcAlarmPolarity
88627 +{
88628 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
88629 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
88630 +} e_FmRtcAlarmPolarity;
88631 +
88632 +/**************************************************************************//**
88633 + @Description FM RTC Trigger Polarity Options.
88634 +*//***************************************************************************/
88635 +typedef enum e_FmRtcTriggerPolarity
88636 +{
88637 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
88638 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
88639 +} e_FmRtcTriggerPolarity;
88640 +
88641 +/**************************************************************************//**
88642 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
88643 +*//***************************************************************************/
88644 +typedef enum e_FmSrcClock
88645 +{
88646 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
88647 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
88648 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
88649 +}e_FmSrcClk;
88650 +
88651 +/**************************************************************************//**
88652 + @Description FM RTC configuration parameters structure.
88653 +
88654 + This structure should be passed to FM_RTC_Config().
88655 +*//***************************************************************************/
88656 +typedef struct t_FmRtcParams
88657 +{
88658 + t_Handle h_Fm; /**< FM Handle*/
88659 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
88660 + t_Handle h_App; /**< A handle to an application layer object; This handle will
88661 + be passed by the driver upon calling the above callbacks */
88662 +} t_FmRtcParams;
88663 +
88664 +
88665 +/**************************************************************************//**
88666 + @Function FM_RTC_Config
88667 +
88668 + @Description Configures the FM RTC module according to user's parameters.
88669 +
88670 + The driver assigns default values to some FM RTC parameters.
88671 + These parameters can be overwritten using the advanced
88672 + configuration routines.
88673 +
88674 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
88675 +
88676 + @Return Handle to the new FM RTC object; NULL pointer on failure.
88677 +
88678 + @Cautions None
88679 +*//***************************************************************************/
88680 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
88681 +
88682 +/**************************************************************************//**
88683 + @Function FM_RTC_Init
88684 +
88685 + @Description Initializes the FM RTC driver and hardware.
88686 +
88687 + @Param[in] h_FmRtc - Handle to FM RTC object.
88688 +
88689 + @Return E_OK on success; Error code otherwise.
88690 +
88691 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88692 +*//***************************************************************************/
88693 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
88694 +
88695 +/**************************************************************************//**
88696 + @Function FM_RTC_Free
88697 +
88698 + @Description Frees the FM RTC object and all allocated resources.
88699 +
88700 + @Param[in] h_FmRtc - Handle to FM RTC object.
88701 +
88702 + @Return E_OK on success; Error code otherwise.
88703 +
88704 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88705 +*//***************************************************************************/
88706 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
88707 +
88708 +
88709 +/**************************************************************************//**
88710 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
88711 +
88712 + @Description FM RTC advanced configuration functions.
88713 +
88714 + @{
88715 +*//***************************************************************************/
88716 +
88717 +/**************************************************************************//**
88718 + @Function FM_RTC_ConfigPeriod
88719 +
88720 + @Description Configures the period of the timestamp if different than
88721 + default [DEFAULT_clockPeriod].
88722 +
88723 + @Param[in] h_FmRtc - Handle to FM RTC object.
88724 + @Param[in] period - Period in nano-seconds.
88725 +
88726 + @Return E_OK on success; Error code otherwise.
88727 +
88728 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88729 +*//***************************************************************************/
88730 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
88731 +
88732 +/**************************************************************************//**
88733 + @Function FM_RTC_ConfigSourceClock
88734 +
88735 + @Description Configures the source clock of the RTC.
88736 +
88737 + @Param[in] h_FmRtc - Handle to FM RTC object.
88738 + @Param[in] srcClk - Source clock selection.
88739 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
88740 +
88741 + @Return E_OK on success; Error code otherwise.
88742 +
88743 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88744 +*//***************************************************************************/
88745 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
88746 + e_FmSrcClk srcClk,
88747 + uint32_t freqInMhz);
88748 +
88749 +/**************************************************************************//**
88750 + @Function FM_RTC_ConfigPulseRealignment
88751 +
88752 + @Description Configures the RTC to automatic FIPER pulse realignment in
88753 + response to timer adjustments [DEFAULT_pulseRealign]
88754 +
88755 + In this mode, the RTC clock is identical to the source clock.
88756 + This feature can be useful when the system contains an external
88757 + RTC with inherent frequency compensation.
88758 +
88759 + @Param[in] h_FmRtc - Handle to FM RTC object.
88760 + @Param[in] enable - TRUE to enable automatic realignment.
88761 +
88762 + @Return E_OK on success; Error code otherwise.
88763 +
88764 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88765 +*//***************************************************************************/
88766 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
88767 +
88768 +/**************************************************************************//**
88769 + @Function FM_RTC_ConfigFrequencyBypass
88770 +
88771 + @Description Configures the RTC to bypass the frequency compensation
88772 + mechanism. [DEFAULT_bypass]
88773 +
88774 + In this mode, the RTC clock is identical to the source clock.
88775 + This feature can be useful when the system contains an external
88776 + RTC with inherent frequency compensation.
88777 +
88778 + @Param[in] h_FmRtc - Handle to FM RTC object.
88779 + @Param[in] enabled - TRUE to bypass frequency compensation;
88780 + FALSE otherwise.
88781 +
88782 + @Return E_OK on success; Error code otherwise.
88783 +
88784 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88785 +*//***************************************************************************/
88786 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
88787 +
88788 +/**************************************************************************//**
88789 + @Function FM_RTC_ConfigInvertedInputClockPhase
88790 +
88791 + @Description Configures the RTC to invert the source clock phase on input.
88792 + [DEFAULT_invertInputClkPhase]
88793 +
88794 + @Param[in] h_FmRtc - Handle to FM RTC object.
88795 + @Param[in] inverted - TRUE to invert the source clock phase on input.
88796 + FALSE otherwise.
88797 +
88798 + @Return E_OK on success; Error code otherwise.
88799 +
88800 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88801 +*//***************************************************************************/
88802 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
88803 +
88804 +/**************************************************************************//**
88805 + @Function FM_RTC_ConfigInvertedOutputClockPhase
88806 +
88807 + @Description Configures the RTC to invert the output clock phase.
88808 + [DEFAULT_invertOutputClkPhase]
88809 +
88810 + @Param[in] h_FmRtc - Handle to FM RTC object.
88811 + @Param[in] inverted - TRUE to invert the output clock phase.
88812 + FALSE otherwise.
88813 +
88814 + @Return E_OK on success; Error code otherwise.
88815 +
88816 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88817 +*//***************************************************************************/
88818 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
88819 +
88820 +/**************************************************************************//**
88821 + @Function FM_RTC_ConfigOutputClockDivisor
88822 +
88823 + @Description Configures the divisor for generating the output clock from
88824 + the RTC clock. [DEFAULT_outputClockDivisor]
88825 +
88826 + @Param[in] h_FmRtc - Handle to FM RTC object.
88827 + @Param[in] divisor - Divisor for generation of the output clock.
88828 +
88829 + @Return E_OK on success; Error code otherwise.
88830 +
88831 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88832 +*//***************************************************************************/
88833 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
88834 +
88835 +/**************************************************************************//**
88836 + @Function FM_RTC_ConfigAlarmPolarity
88837 +
88838 + @Description Configures the polarity (active-high/active-low) of a specific
88839 + alarm signal. [DEFAULT_alarmPolarity]
88840 +
88841 + @Param[in] h_FmRtc - Handle to FM RTC object.
88842 + @Param[in] alarmId - Alarm ID.
88843 + @Param[in] alarmPolarity - Alarm polarity.
88844 +
88845 + @Return E_OK on success; Error code otherwise.
88846 +
88847 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88848 +*//***************************************************************************/
88849 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
88850 + uint8_t alarmId,
88851 + e_FmRtcAlarmPolarity alarmPolarity);
88852 +
88853 +/**************************************************************************//**
88854 + @Function FM_RTC_ConfigExternalTriggerPolarity
88855 +
88856 + @Description Configures the polarity (rising/falling edge) of a specific
88857 + external trigger signal. [DEFAULT_triggerPolarity]
88858 +
88859 + @Param[in] h_FmRtc - Handle to FM RTC object.
88860 + @Param[in] triggerId - Trigger ID.
88861 + @Param[in] triggerPolarity - Trigger polarity.
88862 +
88863 + @Return E_OK on success; Error code otherwise.
88864 +
88865 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
88866 +*//***************************************************************************/
88867 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
88868 + uint8_t triggerId,
88869 + e_FmRtcTriggerPolarity triggerPolarity);
88870 +
88871 +/** @} */ /* end of fm_rtc_adv_config_grp */
88872 +/** @} */ /* end of fm_rtc_init_grp */
88873 +
88874 +
88875 +/**************************************************************************//**
88876 + @Group fm_rtc_control_grp FM RTC Control Unit
88877 +
88878 + @Description FM RTC runtime control API.
88879 +
88880 + @{
88881 +*//***************************************************************************/
88882 +
88883 +/**************************************************************************//**
88884 + @Function t_FmRtcExceptionsCallback
88885 +
88886 + @Description Exceptions user callback routine, used for RTC different mechanisms.
88887 +
88888 + @Param[in] h_App - User's application descriptor.
88889 + @Param[in] id - source id.
88890 +*//***************************************************************************/
88891 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
88892 +
88893 +/**************************************************************************//**
88894 + @Description FM RTC alarm parameters.
88895 +*//***************************************************************************/
88896 +typedef struct t_FmRtcAlarmParams {
88897 + uint8_t alarmId; /**< 0 or 1 */
88898 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
88899 + should go off - must be a multiple of
88900 + the RTC period */
88901 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
88902 + reaches alarmTime */
88903 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
88904 +} t_FmRtcAlarmParams;
88905 +
88906 +/**************************************************************************//**
88907 + @Description FM RTC Periodic Pulse parameters.
88908 +*//***************************************************************************/
88909 +typedef struct t_FmRtcPeriodicPulseParams {
88910 + uint8_t periodicPulseId; /**< 0 or 1 */
88911 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
88912 + a multiple of the RTC period */
88913 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
88914 + periodicPulsePeriod. */
88915 +} t_FmRtcPeriodicPulseParams;
88916 +
88917 +/**************************************************************************//**
88918 + @Description FM RTC Periodic Pulse parameters.
88919 +*//***************************************************************************/
88920 +typedef struct t_FmRtcExternalTriggerParams {
88921 + uint8_t externalTriggerId; /**< 0 or 1 */
88922 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
88923 + an external signal */
88924 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
88925 + periodicPulsePeriod. */
88926 +} t_FmRtcExternalTriggerParams;
88927 +
88928 +
88929 +/**************************************************************************//**
88930 + @Function FM_RTC_Enable
88931 +
88932 + @Description Enable the RTC (time count is started).
88933 +
88934 + The user can select to resume the time count from previous
88935 + point, or to restart the time count.
88936 +
88937 + @Param[in] h_FmRtc - Handle to FM RTC object.
88938 + @Param[in] resetClock - Restart the time count from zero.
88939 +
88940 + @Return E_OK on success; Error code otherwise.
88941 +
88942 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
88943 +*//***************************************************************************/
88944 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
88945 +
88946 +/**************************************************************************//**
88947 + @Function FM_RTC_Disable
88948 +
88949 + @Description Disables the RTC (time count is stopped).
88950 +
88951 + @Param[in] h_FmRtc - Handle to FM RTC object.
88952 +
88953 + @Return E_OK on success; Error code otherwise.
88954 +
88955 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
88956 +*//***************************************************************************/
88957 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
88958 +
88959 +/**************************************************************************//**
88960 + @Function FM_RTC_SetClockOffset
88961 +
88962 + @Description Sets the clock offset (usually relative to another clock).
88963 +
88964 + The user can pass a negative offset value.
88965 +
88966 + @Param[in] h_FmRtc - Handle to FM RTC object.
88967 + @Param[in] offset - New clock offset (in nanoseconds).
88968 +
88969 + @Return E_OK on success; Error code otherwise.
88970 +
88971 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
88972 +*//***************************************************************************/
88973 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
88974 +
88975 +/**************************************************************************//**
88976 + @Function FM_RTC_SetAlarm
88977 +
88978 + @Description Schedules an alarm event to a given RTC time.
88979 +
88980 + @Param[in] h_FmRtc - Handle to FM RTC object.
88981 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
88982 +
88983 + @Return E_OK on success; Error code otherwise.
88984 +
88985 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
88986 + Must be called only prior to FM_RTC_Enable().
88987 +*//***************************************************************************/
88988 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
88989 +
88990 +/**************************************************************************//**
88991 + @Function FM_RTC_SetPeriodicPulse
88992 +
88993 + @Description Sets a periodic pulse.
88994 +
88995 + @Param[in] h_FmRtc - Handle to FM RTC object.
88996 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
88997 +
88998 + @Return E_OK on success; Error code otherwise.
88999 +
89000 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89001 + Must be called only prior to FM_RTC_Enable().
89002 +*//***************************************************************************/
89003 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
89004 +
89005 +/**************************************************************************//**
89006 + @Function FM_RTC_ClearPeriodicPulse
89007 +
89008 + @Description Clears a periodic pulse.
89009 +
89010 + @Param[in] h_FmRtc - Handle to FM RTC object.
89011 + @Param[in] periodicPulseId - Periodic pulse id.
89012 +
89013 + @Return E_OK on success; Error code otherwise.
89014 +
89015 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89016 +*//***************************************************************************/
89017 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
89018 +
89019 +/**************************************************************************//**
89020 + @Function FM_RTC_SetExternalTrigger
89021 +
89022 + @Description Sets an external trigger indication and define a callback
89023 + routine to be called on such event.
89024 +
89025 + @Param[in] h_FmRtc - Handle to FM RTC object.
89026 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
89027 +
89028 + @Return E_OK on success; Error code otherwise.
89029 +
89030 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89031 +*//***************************************************************************/
89032 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
89033 +
89034 +/**************************************************************************//**
89035 + @Function FM_RTC_ClearExternalTrigger
89036 +
89037 + @Description Clears external trigger indication.
89038 +
89039 + @Param[in] h_FmRtc - Handle to FM RTC object.
89040 + @Param[in] id - External Trigger id.
89041 +
89042 + @Return E_OK on success; Error code otherwise.
89043 +
89044 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89045 +*//***************************************************************************/
89046 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
89047 +
89048 +/**************************************************************************//**
89049 + @Function FM_RTC_GetExternalTriggerTimeStamp
89050 +
89051 + @Description Reads the External Trigger TimeStamp.
89052 +
89053 + @Param[in] h_FmRtc - Handle to FM RTC object.
89054 + @Param[in] triggerId - External Trigger id.
89055 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
89056 +
89057 + @Return E_OK on success; Error code otherwise.
89058 +
89059 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89060 +*//***************************************************************************/
89061 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
89062 + uint8_t triggerId,
89063 + uint64_t *p_TimeStamp);
89064 +
89065 +/**************************************************************************//**
89066 + @Function FM_RTC_GetCurrentTime
89067 +
89068 + @Description Returns the current RTC time.
89069 +
89070 + @Param[in] h_FmRtc - Handle to FM RTC object.
89071 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
89072 +
89073 + @Return E_OK on success; Error code otherwise.
89074 +
89075 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89076 +*//***************************************************************************/
89077 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
89078 +
89079 +/**************************************************************************//**
89080 + @Function FM_RTC_SetCurrentTime
89081 +
89082 + @Description Sets the current RTC time.
89083 +
89084 + @Param[in] h_FmRtc - Handle to FM RTC object.
89085 + @Param[in] ts - The new time stamp (in nanoseconds).
89086 +
89087 + @Return E_OK on success; Error code otherwise.
89088 +
89089 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89090 +*//***************************************************************************/
89091 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
89092 +
89093 +/**************************************************************************//**
89094 + @Function FM_RTC_GetFreqCompensation
89095 +
89096 + @Description Retrieves the frequency compensation value
89097 +
89098 + @Param[in] h_FmRtc - Handle to FM RTC object.
89099 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
89100 +
89101 + @Return E_OK on success; Error code otherwise.
89102 +
89103 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89104 +*//***************************************************************************/
89105 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
89106 +
89107 +/**************************************************************************//**
89108 + @Function FM_RTC_SetFreqCompensation
89109 +
89110 + @Description Sets a new frequency compensation value.
89111 +
89112 + @Param[in] h_FmRtc - Handle to FM RTC object.
89113 + @Param[in] freqCompensation - The new frequency compensation value to set.
89114 +
89115 + @Return E_OK on success; Error code otherwise.
89116 +
89117 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89118 +*//***************************************************************************/
89119 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
89120 +
89121 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
89122 +/**************************************************************************//**
89123 +*@Function FM_RTC_EnableInterrupt
89124 +*
89125 +*@Description Enable interrupt of FM RTC.
89126 +*
89127 +*@Param[in] h_FmRtc - Handle to FM RTC object.
89128 +*@Param[in] events - Interrupt events.
89129 +*
89130 +*@Return E_OK on success; Error code otherwise.
89131 +*//***************************************************************************/
89132 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
89133 +
89134 +/**************************************************************************//**
89135 +*@Function FM_RTC_DisableInterrupt
89136 +*
89137 +*@Description Disable interrupt of FM RTC.
89138 +*
89139 +*@Param[in] h_FmRtc - Handle to FM RTC object.
89140 +*@Param[in] events - Interrupt events.
89141 +*
89142 +*@Return E_OK on success; Error code otherwise.
89143 +*//***************************************************************************/
89144 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
89145 +#endif
89146 +
89147 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
89148 +/**************************************************************************//**
89149 + @Function FM_RTC_DumpRegs
89150 +
89151 + @Description Dumps all FM registers
89152 +
89153 + @Param[in] h_FmRtc A handle to an FM RTC Module.
89154 +
89155 + @Return E_OK on success;
89156 +
89157 + @Cautions Allowed only FM_Init().
89158 +*//***************************************************************************/
89159 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
89160 +#endif /* (defined(DEBUG_ERRORS) && ... */
89161 +
89162 +/** @} */ /* end of fm_rtc_control_grp */
89163 +/** @} */ /* end of fm_rtc_grp */
89164 +/** @} */ /* end of FM_grp group */
89165 +
89166 +
89167 +#endif /* __FM_RTC_EXT_H__ */
89168 --- /dev/null
89169 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
89170 @@ -0,0 +1,411 @@
89171 +/*
89172 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89173 + *
89174 + * Redistribution and use in source and binary forms, with or without
89175 + * modification, are permitted provided that the following conditions are met:
89176 + * * Redistributions of source code must retain the above copyright
89177 + * notice, this list of conditions and the following disclaimer.
89178 + * * Redistributions in binary form must reproduce the above copyright
89179 + * notice, this list of conditions and the following disclaimer in the
89180 + * documentation and/or other materials provided with the distribution.
89181 + * * Neither the name of Freescale Semiconductor nor the
89182 + * names of its contributors may be used to endorse or promote products
89183 + * derived from this software without specific prior written permission.
89184 + *
89185 + *
89186 + * ALTERNATIVELY, this software may be distributed under the terms of the
89187 + * GNU General Public License ("GPL") as published by the Free Software
89188 + * Foundation, either version 2 of that License or (at your option) any
89189 + * later version.
89190 + *
89191 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89192 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89193 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89194 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89195 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89196 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89197 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89198 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89199 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89200 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89201 + */
89202 +
89203 +
89204 +/**************************************************************************//**
89205 + @File fm_vsp_ext.h
89206 +
89207 + @Description FM Virtual Storage-Profile ...
89208 +*//***************************************************************************/
89209 +#ifndef __FM_VSP_EXT_H
89210 +#define __FM_VSP_EXT_H
89211 +
89212 +#include "std_ext.h"
89213 +#include "error_ext.h"
89214 +#include "string_ext.h"
89215 +#include "debug_ext.h"
89216 +
89217 +#include "fm_ext.h"
89218 +
89219 +
89220 +/**************************************************************************//**
89221 +
89222 + @Group FM_grp Frame Manager API
89223 +
89224 + @Description FM API functions, definitions and enums
89225 +
89226 + @{
89227 +*//***************************************************************************/
89228 +
89229 +/**************************************************************************//**
89230 + @Group FM_VSP_grp FM Virtual-Storage-Profile
89231 +
89232 + @Description FM Virtual-Storage-Profile API
89233 +
89234 + @{
89235 +*//***************************************************************************/
89236 +
89237 +/**************************************************************************//**
89238 + @Group FM_VSP_init_grp FM VSP Initialization Unit
89239 +
89240 + @Description FM VSP initialization API.
89241 +
89242 + @{
89243 +*//***************************************************************************/
89244 +
89245 +/**************************************************************************//**
89246 + @Description Virtual Storage Profile
89247 +*//***************************************************************************/
89248 +typedef struct t_FmVspParams {
89249 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
89250 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
89251 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
89252 + parameter associated with Rx / OP port */
89253 + uint16_t liodnOffset; /**< VSP's LIODN offset */
89254 + struct {
89255 + e_FmPortType portType; /**< Port type */
89256 + uint8_t portId; /**< Port Id - relative to type */
89257 + } portParams;
89258 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
89259 + defined in relevant FM object */
89260 +} t_FmVspParams;
89261 +
89262 +
89263 +/**************************************************************************//**
89264 + @Function FM_VSP_Config
89265 +
89266 + @Description Creates descriptor for the FM VSP module.
89267 +
89268 + The routine returns a handle (descriptor) to the FM VSP object.
89269 + This descriptor must be passed as first parameter to all other
89270 + FM VSP function calls.
89271 +
89272 + No actual initialization or configuration of FM hardware is
89273 + done by this routine.
89274 +
89275 +@Param[in] p_FmVspParams Pointer to data structure of parameters
89276 +
89277 + @Retval Handle to FM VSP object, or NULL for Failure.
89278 +*//***************************************************************************/
89279 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
89280 +
89281 +/**************************************************************************//**
89282 + @Function FM_VSP_Init
89283 +
89284 + @Description Initializes the FM VSP module
89285 +
89286 + @Param[in] h_FmVsp - FM VSP module descriptor
89287 +
89288 + @Return E_OK on success; Error code otherwise.
89289 +*//***************************************************************************/
89290 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
89291 +
89292 +/**************************************************************************//**
89293 + @Function FM_VSP_Free
89294 +
89295 + @Description Frees all resources that were assigned to FM VSP module.
89296 +
89297 + Calling this routine invalidates the descriptor.
89298 +
89299 + @Param[in] h_FmVsp - FM VSP module descriptor
89300 +
89301 + @Return E_OK on success; Error code otherwise.
89302 +*//***************************************************************************/
89303 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
89304 +
89305 +
89306 +/**************************************************************************//**
89307 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
89308 +
89309 + @Description FM VSP advanced configuration functions.
89310 +
89311 + @{
89312 +*//***************************************************************************/
89313 +
89314 +/**************************************************************************//**
89315 + @Function FM_VSP_ConfigBufferPrefixContent
89316 +
89317 + @Description Defines the structure, size and content of the application buffer.
89318 +
89319 + The prefix will
89320 + In VSPs defined for Tx ports, if 'passPrsResult', the application
89321 + should set a value to their offsets in the prefix of
89322 + the FM will save the first 'privDataSize', than,
89323 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
89324 + and timeStamp, and the packet itself (in this order), to the
89325 + application buffer, and to offset.
89326 +
89327 + Calling this routine changes the buffer margins definitions
89328 + in the internal driver data base from its default
89329 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
89330 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
89331 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
89332 +
89333 + @Param[in] h_FmVsp A handle to a FM VSP module.
89334 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
89335 + structure of the buffer.
89336 + Out parameter: Start margin - offset
89337 + of data from start of external buffer.
89338 +
89339 + @Return E_OK on success; Error code otherwise.
89340 +
89341 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89342 +*//***************************************************************************/
89343 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
89344 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
89345 +
89346 +/**************************************************************************//**
89347 + @Function FM_VSP_ConfigDmaSwapData
89348 +
89349 + @Description Calling this routine changes the DMA swap data parameter
89350 + in the internal driver data base from its default
89351 + configuration [DEFAULT_FM_SP_dmaSwapData]
89352 +
89353 + @Param[in] h_FmVsp A handle to a FM VSP module.
89354 + @Param[in] swapData New selection
89355 +
89356 + @Return E_OK on success; Error code otherwise.
89357 +
89358 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89359 +*//***************************************************************************/
89360 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
89361 +
89362 +/**************************************************************************//**
89363 + @Function FM_VSP_ConfigDmaIcCacheAttr
89364 +
89365 + @Description Calling this routine changes the internal context cache
89366 + attribute parameter in the internal driver data base
89367 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
89368 +
89369 + @Param[in] h_FmVsp A handle to a FM VSP module.
89370 + @Param[in] intContextCacheAttr New selection
89371 +
89372 + @Return E_OK on success; Error code otherwise.
89373 +
89374 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89375 +*//***************************************************************************/
89376 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
89377 + e_FmDmaCacheOption intContextCacheAttr);
89378 +
89379 +/**************************************************************************//**
89380 + @Function FM_VSP_ConfigDmaHdrAttr
89381 +
89382 + @Description Calling this routine changes the header cache
89383 + attribute parameter in the internal driver data base
89384 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
89385 +
89386 + @Param[in] h_FmVsp A handle to a FM VSP module.
89387 + @Param[in] headerCacheAttr New selection
89388 +
89389 + @Return E_OK on success; Error code otherwise.
89390 +
89391 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89392 +*//***************************************************************************/
89393 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
89394 +
89395 +/**************************************************************************//**
89396 + @Function FM_VSP_ConfigDmaScatterGatherAttr
89397 +
89398 + @Description Calling this routine changes the scatter gather cache
89399 + attribute parameter in the internal driver data base
89400 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
89401 +
89402 + @Param[in] h_FmVsp A handle to a FM VSP module.
89403 + @Param[in] scatterGatherCacheAttr New selection
89404 +
89405 + @Return E_OK on success; Error code otherwise.
89406 +
89407 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89408 +*//***************************************************************************/
89409 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
89410 + e_FmDmaCacheOption scatterGatherCacheAttr);
89411 +
89412 +/**************************************************************************//**
89413 + @Function FM_VSP_ConfigDmaWriteOptimize
89414 +
89415 + @Description Calling this routine changes the write optimization
89416 + parameter in the internal driver data base
89417 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
89418 +
89419 + @Param[in] h_FmVsp A handle to a FM VSP module.
89420 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
89421 +
89422 + @Return E_OK on success; Error code otherwise.
89423 +
89424 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89425 +*//***************************************************************************/
89426 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
89427 +
89428 +/**************************************************************************//**
89429 + @Function FM_VSP_ConfigNoScatherGather
89430 +
89431 + @Description Calling this routine changes the possibility to receive S/G frame
89432 + in the internal driver data base
89433 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
89434 +
89435 + @Param[in] h_FmVsp A handle to a FM VSP module.
89436 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
89437 +
89438 + @Return E_OK on success; Error code otherwise.
89439 +
89440 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89441 +*//***************************************************************************/
89442 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
89443 +
89444 +/**************************************************************************//**
89445 + @Function FM_VSP_ConfigPoolDepletion
89446 +
89447 + @Description Calling this routine enables pause frame generation depending on the
89448 + depletion status of BM pools. It also defines the conditions to activate
89449 + this functionality. By default, this functionality is disabled.
89450 +
89451 + @Param[in] h_FmVsp A handle to a FM VSP module.
89452 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
89453 +
89454 + @Return E_OK on success; Error code otherwise.
89455 +
89456 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89457 +*//***************************************************************************/
89458 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
89459 +
89460 +/**************************************************************************//**
89461 + @Function FM_VSP_ConfigBackupPools
89462 +
89463 + @Description Calling this routine allows the configuration of some of the BM pools
89464 + defined for this port as backup pools.
89465 + A pool configured to be a backup pool will be used only if all other
89466 + enabled non-backup pools are depleted.
89467 +
89468 + @Param[in] h_FmVsp A handle to a FM VSP module.
89469 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
89470 + be defined as backup pools.
89471 +
89472 + @Return E_OK on success; Error code otherwise.
89473 +
89474 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89475 +*//***************************************************************************/
89476 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
89477 +
89478 +/** @} */ /* end of FM_VSP_adv_config_grp group */
89479 +/** @} */ /* end of FM_VSP_init_grp group */
89480 +
89481 +
89482 +/**************************************************************************//**
89483 + @Group FM_VSP_control_grp FM VSP Control Unit
89484 +
89485 + @Description FM VSP runtime control API.
89486 +
89487 + @{
89488 +*//***************************************************************************/
89489 +
89490 +/**************************************************************************//**
89491 + @Function FM_VSP_GetBufferDataOffset
89492 +
89493 + @Description Relevant for Rx ports.
89494 + Returns the data offset from the beginning of the data buffer
89495 +
89496 + @Param[in] h_FmVsp - FM PORT module descriptor
89497 +
89498 + @Return data offset.
89499 +
89500 + @Cautions Allowed only following FM_VSP_Init().
89501 +*//***************************************************************************/
89502 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
89503 +
89504 +/**************************************************************************//**
89505 + @Function FM_VSP_GetBufferICInfo
89506 +
89507 + @Description Returns the Internal Context offset from the beginning of the data buffer
89508 +
89509 + @Param[in] h_FmVsp - FM PORT module descriptor
89510 + @Param[in] p_Data - A pointer to the data buffer.
89511 +
89512 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
89513 + configured for this port.
89514 +
89515 + @Cautions Allowed only following FM_VSP_Init().
89516 +*//***************************************************************************/
89517 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
89518 +
89519 +/**************************************************************************//**
89520 + @Function FM_VSP_GetBufferPrsResult
89521 +
89522 + @Description Returns the pointer to the parse result in the data buffer.
89523 + In Rx ports this is relevant after reception, if parse
89524 + result is configured to be part of the data passed to the
89525 + application. For non Rx ports it may be used to get the pointer
89526 + of the area in the buffer where parse result should be
89527 + initialized - if so configured.
89528 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
89529 + configuration.
89530 +
89531 + @Param[in] h_FmVsp - FM PORT module descriptor
89532 + @Param[in] p_Data - A pointer to the data buffer.
89533 +
89534 + @Return Parse result pointer on success, NULL if parse result was not
89535 + configured for this port.
89536 +
89537 + @Cautions Allowed only following FM_VSP_Init().
89538 +*//***************************************************************************/
89539 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
89540 +
89541 +/**************************************************************************//**
89542 + @Function FM_VSP_GetBufferTimeStamp
89543 +
89544 + @Description Returns the time stamp in the data buffer.
89545 + Relevant for Rx ports for getting the buffer time stamp.
89546 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
89547 + configuration.
89548 +
89549 + @Param[in] h_FmVsp - FM PORT module descriptor
89550 + @Param[in] p_Data - A pointer to the data buffer.
89551 +
89552 + @Return A pointer to the hash result on success, NULL otherwise.
89553 +
89554 + @Cautions Allowed only following FM_VSP_Init().
89555 +*//***************************************************************************/
89556 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
89557 +
89558 +/**************************************************************************//**
89559 + @Function FM_VSP_GetBufferHashResult
89560 +
89561 + @Description Given a data buffer, on the condition that hash result was defined
89562 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
89563 + this routine will return the pointer to the hash result location in the
89564 + buffer prefix.
89565 +
89566 + @Param[in] h_FmVsp - FM PORT module descriptor
89567 + @Param[in] p_Data - A pointer to the data buffer.
89568 +
89569 + @Return A pointer to the hash result on success, NULL otherwise.
89570 +
89571 + @Cautions Allowed only following FM_VSP_Init().
89572 +*//***************************************************************************/
89573 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
89574 +
89575 +
89576 +/** @} */ /* end of FM_VSP_control_grp group */
89577 +/** @} */ /* end of FM_VSP_grp group */
89578 +/** @} */ /* end of FM_grp group */
89579 +
89580 +
89581 +#endif /* __FM_VSP_EXT_H */
89582 --- /dev/null
89583 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
89584 @@ -0,0 +1,76 @@
89585 +/*
89586 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89587 + *
89588 + * Redistribution and use in source and binary forms, with or without
89589 + * modification, are permitted provided that the following conditions are met:
89590 + * * Redistributions of source code must retain the above copyright
89591 + * notice, this list of conditions and the following disclaimer.
89592 + * * Redistributions in binary form must reproduce the above copyright
89593 + * notice, this list of conditions and the following disclaimer in the
89594 + * documentation and/or other materials provided with the distribution.
89595 + * * Neither the name of Freescale Semiconductor nor the
89596 + * names of its contributors may be used to endorse or promote products
89597 + * derived from this software without specific prior written permission.
89598 + *
89599 + *
89600 + * ALTERNATIVELY, this software may be distributed under the terms of the
89601 + * GNU General Public License ("GPL") as published by the Free Software
89602 + * Foundation, either version 2 of that License or (at your option) any
89603 + * later version.
89604 + *
89605 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89606 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89607 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89608 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89609 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89610 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89611 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89612 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89613 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89614 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89615 + */
89616 +
89617 +
89618 +
89619 +#ifndef __MII_ACC_EXT_H
89620 +#define __MII_ACC_EXT_H
89621 +
89622 +
89623 +/**************************************************************************//**
89624 + @Function MII_ReadPhyReg
89625 +
89626 + @Description This routine is called to read a specified PHY
89627 + register value.
89628 +
89629 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
89630 + @Param[in] phyAddr - PHY address (0-31).
89631 + @Param[in] reg - PHY register to read
89632 + @Param[out] p_Data - Gets the register value.
89633 +
89634 + @Return Always zero (success).
89635 +*//***************************************************************************/
89636 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
89637 + uint8_t phyAddr,
89638 + uint8_t reg,
89639 + uint16_t *p_Data);
89640 +
89641 +/**************************************************************************//**
89642 + @Function MII_WritePhyReg
89643 +
89644 + @Description This routine is called to write data to a specified PHY
89645 + register.
89646 +
89647 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
89648 + @Param[in] phyAddr - PHY address (0-31).
89649 + @Param[in] reg - PHY register to write
89650 + @Param[in] data - Data to write in register.
89651 +
89652 + @Return Always zero (success).
89653 +*//***************************************************************************/
89654 +int MII_WritePhyReg(t_Handle h_MiiAccess,
89655 + uint8_t phyAddr,
89656 + uint8_t reg,
89657 + uint16_t data);
89658 +
89659 +
89660 +#endif /* __MII_ACC_EXT_H */
89661 --- /dev/null
89662 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
89663 @@ -0,0 +1,90 @@
89664 +/*
89665 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89666 + *
89667 + * Redistribution and use in source and binary forms, with or without
89668 + * modification, are permitted provided that the following conditions are met:
89669 + * * Redistributions of source code must retain the above copyright
89670 + * notice, this list of conditions and the following disclaimer.
89671 + * * Redistributions in binary form must reproduce the above copyright
89672 + * notice, this list of conditions and the following disclaimer in the
89673 + * documentation and/or other materials provided with the distribution.
89674 + * * Neither the name of Freescale Semiconductor nor the
89675 + * names of its contributors may be used to endorse or promote products
89676 + * derived from this software without specific prior written permission.
89677 + *
89678 + *
89679 + * ALTERNATIVELY, this software may be distributed under the terms of the
89680 + * GNU General Public License ("GPL") as published by the Free Software
89681 + * Foundation, either version 2 of that License or (at your option) any
89682 + * later version.
89683 + *
89684 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89685 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89686 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89687 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89688 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89689 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89690 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89691 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89692 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89693 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89694 + */
89695 +
89696 +
89697 +/**************************************************************************//**
89698 + @File core_ext.h
89699 +
89700 + @Description Generic interface to basic core operations.
89701 +
89702 + The system integrator must ensure that this interface is
89703 + mapped to a specific core implementation, by including the
89704 + appropriate header file.
89705 +*//***************************************************************************/
89706 +#ifndef __CORE_EXT_H
89707 +#define __CORE_EXT_H
89708 +
89709 +#ifdef CONFIG_FMAN_ARM
89710 +#include "arm_ext.h"
89711 +#include <linux/smp.h>
89712 +#else
89713 +#ifdef NCSW_PPC_CORE
89714 +#include "ppc_ext.h"
89715 +#elif defined(NCSW_VXWORKS)
89716 +#include "core_vxw_ext.h"
89717 +#else
89718 +#error "Core is not defined!"
89719 +#endif /* NCSW_CORE */
89720 +
89721 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
89722 +#error "Must define core as little-endian or big-endian!"
89723 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
89724 +
89725 +#ifndef CORE_CACHELINE_SIZE
89726 +#error "Must define the core cache-line size!"
89727 +#endif /* !CORE_CACHELINE_SIZE */
89728 +
89729 +#endif /* CONFIG_FMAN_ARM */
89730 +
89731 +
89732 +/**************************************************************************//**
89733 + @Function CORE_GetId
89734 +
89735 + @Description Returns the core ID in the system.
89736 +
89737 + @Return Core ID.
89738 +*//***************************************************************************/
89739 +uint32_t CORE_GetId(void);
89740 +
89741 +/**************************************************************************//**
89742 + @Function CORE_MemoryBarrier
89743 +
89744 + @Description This routine will cause the core to stop executing any commands
89745 + until all previous memory read/write commands are completely out
89746 + of the core's pipeline.
89747 +
89748 + @Return None.
89749 +*//***************************************************************************/
89750 +void CORE_MemoryBarrier(void);
89751 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
89752 +
89753 +#endif /* __CORE_EXT_H */
89754 --- /dev/null
89755 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
89756 @@ -0,0 +1,55 @@
89757 +/*
89758 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89759 + *
89760 + * Redistribution and use in source and binary forms, with or without
89761 + * modification, are permitted provided that the following conditions are met:
89762 + * * Redistributions of source code must retain the above copyright
89763 + * notice, this list of conditions and the following disclaimer.
89764 + * * Redistributions in binary form must reproduce the above copyright
89765 + * notice, this list of conditions and the following disclaimer in the
89766 + * documentation and/or other materials provided with the distribution.
89767 + * * Neither the name of Freescale Semiconductor nor the
89768 + * names of its contributors may be used to endorse or promote products
89769 + * derived from this software without specific prior written permission.
89770 + *
89771 + *
89772 + * ALTERNATIVELY, this software may be distributed under the terms of the
89773 + * GNU General Public License ("GPL") as published by the Free Software
89774 + * Foundation, either version 2 of that License or (at your option) any
89775 + * later version.
89776 + *
89777 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89778 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89779 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89780 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89781 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89782 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89783 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89784 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89785 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89786 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89787 + */
89788 +
89789 +
89790 +/**************************************************************************//**
89791 + @File arm_ext.h
89792 +
89793 + @Description Core API for ARM cores
89794 +
89795 + These routines must be implemented by each specific PowerPC
89796 + core driver.
89797 +*//***************************************************************************/
89798 +#ifndef __ARM_EXT_H
89799 +#define __ARM_EXT_H
89800 +
89801 +#include "part_ext.h"
89802 +
89803 +
89804 +#define CORE_IS_LITTLE_ENDIAN
89805 +
89806 +static __inline__ void CORE_MemoryBarrier(void)
89807 +{
89808 + mb();
89809 +}
89810 +
89811 +#endif /* __PPC_EXT_H */
89812 --- /dev/null
89813 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
89814 @@ -0,0 +1,476 @@
89815 +/*
89816 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89817 + *
89818 + * Redistribution and use in source and binary forms, with or without
89819 + * modification, are permitted provided that the following conditions are met:
89820 + * * Redistributions of source code must retain the above copyright
89821 + * notice, this list of conditions and the following disclaimer.
89822 + * * Redistributions in binary form must reproduce the above copyright
89823 + * notice, this list of conditions and the following disclaimer in the
89824 + * documentation and/or other materials provided with the distribution.
89825 + * * Neither the name of Freescale Semiconductor nor the
89826 + * names of its contributors may be used to endorse or promote products
89827 + * derived from this software without specific prior written permission.
89828 + *
89829 + *
89830 + * ALTERNATIVELY, this software may be distributed under the terms of the
89831 + * GNU General Public License ("GPL") as published by the Free Software
89832 + * Foundation, either version 2 of that License or (at your option) any
89833 + * later version.
89834 + *
89835 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89836 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89837 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89838 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89839 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89840 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89841 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89842 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89843 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89844 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89845 + */
89846 +
89847 +
89848 +/**************************************************************************//**
89849 + @File e500v2_ext.h
89850 +
89851 + @Description E500 external definitions prototypes
89852 + This file is not included by the E500
89853 + source file as it is an assembly file. It is used
89854 + only for prototypes exposure, for inclusion
89855 + by user and other modules.
89856 +*//***************************************************************************/
89857 +
89858 +#ifndef __E500V2_EXT_H
89859 +#define __E500V2_EXT_H
89860 +
89861 +#include "std_ext.h"
89862 +
89863 +
89864 +/* Layer 1 Cache Manipulations
89865 + *==============================
89866 + * Should not be called directly by the user.
89867 + */
89868 +void L1DCache_Invalidate (void);
89869 +void L1ICache_Invalidate(void);
89870 +void L1DCache_Enable(void);
89871 +void L1ICache_Enable(void);
89872 +void L1DCache_Disable(void);
89873 +void L1ICache_Disable(void);
89874 +void L1DCache_Flush(void);
89875 +void L1ICache_Flush(void);
89876 +uint32_t L1ICache_IsEnabled(void);
89877 +uint32_t L1DCache_IsEnabled(void);
89878 +/*
89879 + *
89880 + */
89881 +uint32_t L1DCache_LineLock(uint32_t addr);
89882 +uint32_t L1ICache_LineLock(uint32_t addr);
89883 +void L1Cache_BroadCastEnable(void);
89884 +void L1Cache_BroadCastDisable(void);
89885 +
89886 +
89887 +#define CORE_DCacheEnable E500_DCacheEnable
89888 +#define CORE_ICacheEnable E500_ICacheEnable
89889 +#define CORE_DCacheDisable E500_DCacheDisable
89890 +#define CORE_ICacheDisable E500_ICacheDisable
89891 +#define CORE_GetId E500_GetId
89892 +#define CORE_TestAndSet E500_TestAndSet
89893 +#define CORE_MemoryBarrier E500_MemoryBarrier
89894 +#define CORE_InstructionSync E500_InstructionSync
89895 +
89896 +#define CORE_SetDozeMode E500_SetDozeMode
89897 +#define CORE_SetNapMode E500_SetNapMode
89898 +#define CORE_SetSleepMode E500_SetSleepMode
89899 +#define CORE_SetJogMode E500_SetJogMode
89900 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
89901 +
89902 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
89903 +#define CORE_RecoverNapMode E500_RecoverNapMode
89904 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
89905 +#define CORE_RecoverJogMode E500_RecoverJogMode
89906 +
89907 +void E500_SetDozeMode(void);
89908 +void E500_SetNapMode(void);
89909 +void E500_SetSleepMode(void);
89910 +void E500_SetJogMode(void);
89911 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
89912 +
89913 +void E500_RecoverDozeMode(void);
89914 +void E500_RecoverNapMode(void);
89915 +void E500_RecoverSleepMode(void);
89916 +void E500_RecoverJogMode(void);
89917 +
89918 +
89919 +/**************************************************************************//**
89920 + @Group E500_id E500 Application Programming Interface
89921 +
89922 + @Description E500 API functions, definitions and enums
89923 +
89924 + @{
89925 +*//***************************************************************************/
89926 +
89927 +/**************************************************************************//**
89928 + @Group E500_init_grp E500 Initialization Unit
89929 +
89930 + @Description E500 initialization unit API functions, definitions and enums
89931 +
89932 + @{
89933 +*//***************************************************************************/
89934 +
89935 +
89936 +/**************************************************************************//**
89937 + @Function E500_DCacheEnable
89938 +
89939 + @Description Enables the data cache for memory pages that are
89940 + not cache inhibited.
89941 +
89942 + @Return None.
89943 +*//***************************************************************************/
89944 +void E500_DCacheEnable(void);
89945 +
89946 +/**************************************************************************//**
89947 + @Function E500_ICacheEnable
89948 +
89949 + @Description Enables the instruction cache for memory pages that are
89950 + not cache inhibited.
89951 +
89952 + @Return None.
89953 +*//***************************************************************************/
89954 +void E500_ICacheEnable(void);
89955 +
89956 +/**************************************************************************//**
89957 + @Function E500_DCacheDisable
89958 +
89959 + @Description Disables the data cache.
89960 +
89961 + @Return None.
89962 +*//***************************************************************************/
89963 +void E500_DCacheDisable(void);
89964 +
89965 +/**************************************************************************//**
89966 + @Function E500_ICacheDisable
89967 +
89968 + @Description Disables the instruction cache.
89969 +
89970 + @Return None.
89971 +*//***************************************************************************/
89972 +void E500_ICacheDisable(void);
89973 +
89974 +/**************************************************************************//**
89975 + @Function E500_DCacheFlush
89976 +
89977 + @Description Flushes the data cache
89978 +
89979 + @Return None.
89980 +*//***************************************************************************/
89981 +void E500_DCacheFlush(void);
89982 +
89983 +/**************************************************************************//**
89984 + @Function E500_ICacheFlush
89985 +
89986 + @Description Flushes the instruction cache.
89987 +
89988 + @Return None.
89989 +*//***************************************************************************/
89990 +void E500_ICacheFlush(void);
89991 +
89992 +/**************************************************************************//**
89993 + @Function E500_DCacheSetStashId
89994 +
89995 + @Description Set Stash Id for data cache
89996 +
89997 + @Param[in] stashId the stash id to be set.
89998 +
89999 + @Return None.
90000 +*//***************************************************************************/
90001 +void E500_DCacheSetStashId(uint8_t stashId);
90002 +
90003 +/**************************************************************************//**
90004 + @Description E500mc L2 Cache Operation Mode
90005 +*//***************************************************************************/
90006 +typedef enum e_E500mcL2CacheMode
90007 +{
90008 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
90009 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
90010 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
90011 +} e_E500mcL2CacheMode;
90012 +
90013 +#if defined(CORE_E500MC) || defined(CORE_E5500)
90014 +/**************************************************************************//**
90015 + @Function E500_L2CacheEnable
90016 +
90017 + @Description Enables the cache for memory pages that are not cache inhibited.
90018 +
90019 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
90020 +
90021 + @Return None.
90022 +
90023 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
90024 + not possible to call this routine for i-cache and than to call
90025 + again for d-cache; The second call will override the first one.
90026 +*//***************************************************************************/
90027 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
90028 +
90029 +/**************************************************************************//**
90030 + @Function E500_L2CacheDisable
90031 +
90032 + @Description Disables the cache (data instruction or both).
90033 +
90034 + @Return None.
90035 +
90036 +*//***************************************************************************/
90037 +void E500_L2CacheDisable(void);
90038 +
90039 +/**************************************************************************//**
90040 + @Function E500_L2CacheFlush
90041 +
90042 + @Description Flushes the cache.
90043 +
90044 + @Return None.
90045 +*//***************************************************************************/
90046 +void E500_L2CacheFlush(void);
90047 +
90048 +/**************************************************************************//**
90049 + @Function E500_L2SetStashId
90050 +
90051 + @Description Set Stash Id
90052 +
90053 + @Param[in] stashId the stash id to be set.
90054 +
90055 + @Return None.
90056 +*//***************************************************************************/
90057 +void E500_L2SetStashId(uint8_t stashId);
90058 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
90059 +
90060 +#ifdef CORE_E6500
90061 +/**************************************************************************//**
90062 + @Function E6500_L2CacheEnable
90063 +
90064 + @Description Enables the cache for memory pages that are not cache inhibited.
90065 +
90066 + @param[in] mode - L2 cache mode: support data & instruction only.
90067 +
90068 + @Return None.
90069 +
90070 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
90071 + not possible to call this routine for i-cache and than to call
90072 + again for d-cache; The second call will override the first one.
90073 +*//***************************************************************************/
90074 +void E6500_L2CacheEnable(uintptr_t clusterBase);
90075 +
90076 +/**************************************************************************//**
90077 + @Function E6500_L2CacheDisable
90078 +
90079 + @Description Disables the cache (data instruction or both).
90080 +
90081 + @Return None.
90082 +
90083 +*//***************************************************************************/
90084 +void E6500_L2CacheDisable(uintptr_t clusterBase);
90085 +
90086 +/**************************************************************************//**
90087 + @Function E6500_L2CacheFlush
90088 +
90089 + @Description Flushes the cache.
90090 +
90091 + @Return None.
90092 +*//***************************************************************************/
90093 +void E6500_L2CacheFlush(uintptr_t clusterBase);
90094 +
90095 +/**************************************************************************//**
90096 + @Function E6500_L2SetStashId
90097 +
90098 + @Description Set Stash Id
90099 +
90100 + @Param[in] stashId the stash id to be set.
90101 +
90102 + @Return None.
90103 +*//***************************************************************************/
90104 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
90105 +
90106 +/**************************************************************************//**
90107 + @Function E6500_GetCcsrBase
90108 +
90109 + @Description Obtain SoC CCSR base address
90110 +
90111 + @Param[in] None.
90112 +
90113 + @Return Physical CCSR base address.
90114 +*//***************************************************************************/
90115 +physAddress_t E6500_GetCcsrBase(void);
90116 +#endif /* CORE_E6500 */
90117 +
90118 +/**************************************************************************//**
90119 + @Function E500_AddressBusStreamingEnable
90120 +
90121 + @Description Enables address bus streaming on the CCB.
90122 +
90123 + This setting, along with the ECM streaming configuration
90124 + parameters, enables address bus streaming on the CCB.
90125 +
90126 + @Return None.
90127 +*//***************************************************************************/
90128 +void E500_AddressBusStreamingEnable(void);
90129 +
90130 +/**************************************************************************//**
90131 + @Function E500_AddressBusStreamingDisable
90132 +
90133 + @Description Disables address bus streaming on the CCB.
90134 +
90135 + @Return None.
90136 +*//***************************************************************************/
90137 +void E500_AddressBusStreamingDisable(void);
90138 +
90139 +/**************************************************************************//**
90140 + @Function E500_AddressBroadcastEnable
90141 +
90142 + @Description Enables address broadcast.
90143 +
90144 + The e500 broadcasts cache management instructions (dcbst, dcblc
90145 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
90146 + based on ABE. ABE must be set to allow management of external
90147 + L2 caches.
90148 +
90149 + @Return None.
90150 +*//***************************************************************************/
90151 +void E500_AddressBroadcastEnable(void);
90152 +
90153 +/**************************************************************************//**
90154 + @Function E500_AddressBroadcastDisable
90155 +
90156 + @Description Disables address broadcast.
90157 +
90158 + The e500 broadcasts cache management instructions (dcbst, dcblc
90159 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
90160 + based on ABE. ABE must be set to allow management of external
90161 + L2 caches.
90162 +
90163 + @Return None.
90164 +*//***************************************************************************/
90165 +void E500_AddressBroadcastDisable(void);
90166 +
90167 +/**************************************************************************//**
90168 + @Function E500_IsTaskletSupported
90169 +
90170 + @Description Checks if tasklets are supported by the e500 interrupt handler.
90171 +
90172 + @Retval TRUE - Tasklets are supported.
90173 + @Retval FALSE - Tasklets are not supported.
90174 +*//***************************************************************************/
90175 +bool E500_IsTaskletSupported(void);
90176 +
90177 +void E500_EnableTimeBase(void);
90178 +void E500_DisableTimeBase(void);
90179 +
90180 +uint64_t E500_GetTimeBaseTime(void);
90181 +
90182 +void E500_GenericIntrInit(void);
90183 +
90184 +t_Error E500_SetIntr(int ppcIntrSrc,
90185 + void (* Isr)(t_Handle handle),
90186 + t_Handle handle);
90187 +
90188 +t_Error E500_ClearIntr(int ppcIntrSrc);
90189 +
90190 +/**************************************************************************//**
90191 + @Function E500_GenericIntrHandler
90192 +
90193 + @Description This is the general e500 interrupt handler.
90194 +
90195 + It is called by the main assembly interrupt handler
90196 + when an exception occurs and no other function has been
90197 + assigned to this exception.
90198 +
90199 + @Param intrEntry - (In) The exception interrupt vector entry.
90200 +*//***************************************************************************/
90201 +void E500_GenericIntrHandler(uint32_t intrEntry);
90202 +
90203 +/**************************************************************************//**
90204 + @Function CriticalIntr
90205 +
90206 + @Description This is the specific critical e500 interrupt handler.
90207 +
90208 + It is called by the main assembly interrupt handler
90209 + when an critical interrupt.
90210 +
90211 + @Param intrEntry - (In) The exception interrupt vector entry.
90212 +*//***************************************************************************/
90213 +void CriticalIntr(uint32_t intrEntry);
90214 +
90215 +
90216 +/**************************************************************************//**
90217 + @Function E500_GetId
90218 +
90219 + @Description Returns the core ID in the system.
90220 +
90221 + @Return Core ID.
90222 +*//***************************************************************************/
90223 +uint32_t E500_GetId(void);
90224 +
90225 +/**************************************************************************//**
90226 + @Function E500_TestAndSet
90227 +
90228 + @Description This routine tries to atomically test-and-set an integer
90229 + in memory to a non-zero value.
90230 +
90231 + The memory will be set only if it is tested as zero, in which
90232 + case the routine returns the new non-zero value; otherwise the
90233 + routine returns zero.
90234 +
90235 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
90236 + operation should be made.
90237 +
90238 + @Retval Zero - Operation failed - memory was already set.
90239 + @Retval Non-zero - Operation succeeded - memory has been set.
90240 +*//***************************************************************************/
90241 +int E500_TestAndSet(volatile int *p);
90242 +
90243 +/**************************************************************************//**
90244 + @Function E500_MemoryBarrier
90245 +
90246 + @Description This routine will cause the core to stop executing any commands
90247 + until all previous memory read/write commands are completely out
90248 + of the core's pipeline.
90249 +
90250 + @Return None.
90251 +*//***************************************************************************/
90252 +static __inline__ void E500_MemoryBarrier(void)
90253 +{
90254 +#ifndef CORE_E500V2
90255 + __asm__ ("mbar 1");
90256 +#else /* CORE_E500V2 */
90257 + /**** ERRATA WORK AROUND START ****/
90258 + /* ERRATA num: CPU1 */
90259 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
90260 + guarded loads and stores. */
90261 +
90262 + /* "msync" instruction is used instead */
90263 +
90264 + __asm__ ("msync");
90265 +
90266 + /**** ERRATA WORK AROUND END ****/
90267 +#endif /* CORE_E500V2 */
90268 +}
90269 +
90270 +/**************************************************************************//**
90271 + @Function E500_InstructionSync
90272 +
90273 + @Description This routine will cause the core to wait for previous instructions
90274 + (including any interrupts they generate) to complete before the
90275 + synchronization command executes, which purges all instructions
90276 + from the processor's pipeline and refetches the next instruction.
90277 +
90278 + @Return None.
90279 +*//***************************************************************************/
90280 +static __inline__ void E500_InstructionSync(void)
90281 +{
90282 + __asm__ ("isync");
90283 +}
90284 +
90285 +
90286 +/** @} */ /* end of E500_init_grp group */
90287 +/** @} */ /* end of E500_grp group */
90288 +
90289 +
90290 +#endif /* __E500V2_EXT_H */
90291 --- /dev/null
90292 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
90293 @@ -0,0 +1,141 @@
90294 +/*
90295 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90296 + *
90297 + * Redistribution and use in source and binary forms, with or without
90298 + * modification, are permitted provided that the following conditions are met:
90299 + * * Redistributions of source code must retain the above copyright
90300 + * notice, this list of conditions and the following disclaimer.
90301 + * * Redistributions in binary form must reproduce the above copyright
90302 + * notice, this list of conditions and the following disclaimer in the
90303 + * documentation and/or other materials provided with the distribution.
90304 + * * Neither the name of Freescale Semiconductor nor the
90305 + * names of its contributors may be used to endorse or promote products
90306 + * derived from this software without specific prior written permission.
90307 + *
90308 + *
90309 + * ALTERNATIVELY, this software may be distributed under the terms of the
90310 + * GNU General Public License ("GPL") as published by the Free Software
90311 + * Foundation, either version 2 of that License or (at your option) any
90312 + * later version.
90313 + *
90314 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90315 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90316 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90317 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90318 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90319 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90320 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90321 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90322 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90323 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90324 + */
90325 +
90326 +
90327 +/**************************************************************************//**
90328 + @File ppc_ext.h
90329 +
90330 + @Description Core API for PowerPC cores
90331 +
90332 + These routines must be implemented by each specific PowerPC
90333 + core driver.
90334 +*//***************************************************************************/
90335 +#ifndef __PPC_EXT_H
90336 +#define __PPC_EXT_H
90337 +
90338 +#include "part_ext.h"
90339 +
90340 +
90341 +#define CORE_IS_BIG_ENDIAN
90342 +
90343 +#if defined(CORE_E300) || defined(CORE_E500V2)
90344 +#define CORE_CACHELINE_SIZE 32
90345 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
90346 +#define CORE_CACHELINE_SIZE 64
90347 +#else
90348 +#error "Core not defined!"
90349 +#endif /* defined(CORE_E300) || ... */
90350 +
90351 +
90352 +/**************************************************************************//**
90353 + @Function CORE_TestAndSet
90354 +
90355 + @Description This routine tries to atomically test-and-set an integer
90356 + in memory to a non-zero value.
90357 +
90358 + The memory will be set only if it is tested as zero, in which
90359 + case the routine returns the new non-zero value; otherwise the
90360 + routine returns zero.
90361 +
90362 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
90363 + operation should be made.
90364 +
90365 + @Retval Zero - Operation failed - memory was already set.
90366 + @Retval Non-zero - Operation succeeded - memory has been set.
90367 +*//***************************************************************************/
90368 +int CORE_TestAndSet(volatile int *p);
90369 +
90370 +/**************************************************************************//**
90371 + @Function CORE_InstructionSync
90372 +
90373 + @Description This routine will cause the core to wait for previous instructions
90374 + (including any interrupts they generate) to complete before the
90375 + synchronization command executes, which purges all instructions
90376 + from the processor's pipeline and refetches the next instruction.
90377 +
90378 + @Return None.
90379 +*//***************************************************************************/
90380 +void CORE_InstructionSync(void);
90381 +
90382 +/**************************************************************************//**
90383 + @Function CORE_DCacheEnable
90384 +
90385 + @Description Enables the data cache for memory pages that are
90386 + not cache inhibited.
90387 +
90388 + @Return None.
90389 +*//***************************************************************************/
90390 +void CORE_DCacheEnable(void);
90391 +
90392 +/**************************************************************************//**
90393 + @Function CORE_ICacheEnable
90394 +
90395 + @Description Enables the instruction cache for memory pages that are
90396 + not cache inhibited.
90397 +
90398 + @Return None.
90399 +*//***************************************************************************/
90400 +void CORE_ICacheEnable(void);
90401 +
90402 +/**************************************************************************//**
90403 + @Function CORE_DCacheDisable
90404 +
90405 + @Description Disables the data cache.
90406 +
90407 + @Return None.
90408 +*//***************************************************************************/
90409 +void CORE_DCacheDisable(void);
90410 +
90411 +/**************************************************************************//**
90412 + @Function CORE_ICacheDisable
90413 +
90414 + @Description Disables the instruction cache.
90415 +
90416 + @Return None.
90417 +*//***************************************************************************/
90418 +void CORE_ICacheDisable(void);
90419 +
90420 +
90421 +
90422 +#if defined(CORE_E300)
90423 +#include "e300_ext.h"
90424 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
90425 +#include "e500v2_ext.h"
90426 +#if !defined(NCSW_LINUX)
90427 +#include "e500v2_asm_ext.h"
90428 +#endif
90429 +#else
90430 +#error "Core not defined!"
90431 +#endif
90432 +
90433 +
90434 +#endif /* __PPC_EXT_H */
90435 --- /dev/null
90436 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
90437 @@ -0,0 +1,77 @@
90438 +/*
90439 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90440 + *
90441 + * Redistribution and use in source and binary forms, with or without
90442 + * modification, are permitted provided that the following conditions are met:
90443 + * * Redistributions of source code must retain the above copyright
90444 + * notice, this list of conditions and the following disclaimer.
90445 + * * Redistributions in binary form must reproduce the above copyright
90446 + * notice, this list of conditions and the following disclaimer in the
90447 + * documentation and/or other materials provided with the distribution.
90448 + * * Neither the name of Freescale Semiconductor nor the
90449 + * names of its contributors may be used to endorse or promote products
90450 + * derived from this software without specific prior written permission.
90451 + *
90452 + *
90453 + * ALTERNATIVELY, this software may be distributed under the terms of the
90454 + * GNU General Public License ("GPL") as published by the Free Software
90455 + * Foundation, either version 2 of that License or (at your option) any
90456 + * later version.
90457 + *
90458 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90459 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90460 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90461 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90462 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90463 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90464 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90465 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90466 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90467 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90468 + */
90469 +
90470 +#ifndef __DDR_SDT_EXT_H
90471 +#define __DDR_SDT_EXT_H
90472 +
90473 +
90474 +/**************************************************************************//**
90475 + @Group ddr_Generic_Resources
90476 +
90477 + @Description ddr generic functions, definitions and enums.
90478 +
90479 + @{
90480 +*//***************************************************************************/
90481 +
90482 +
90483 +/**************************************************************************//**
90484 + @Description SPD maximum size
90485 +*//***************************************************************************/
90486 +#define SPD_MAX_SIZE 256
90487 +
90488 +/**************************************************************************//**
90489 + @Description DDR types select
90490 +*//***************************************************************************/
90491 +typedef enum e_DdrType
90492 +{
90493 + e_DDR_DDR1,
90494 + e_DDR_DDR2,
90495 + e_DDR_DDR3,
90496 + e_DDR_DDR3L,
90497 + e_DDR_DDR4
90498 +} e_DdrType;
90499 +
90500 +/**************************************************************************//**
90501 + @Description DDR Mode.
90502 +*//***************************************************************************/
90503 +typedef enum e_DdrMode
90504 +{
90505 + e_DDR_BUS_WIDTH_32BIT,
90506 + e_DDR_BUS_WIDTH_64BIT
90507 +} e_DdrMode;
90508 +
90509 +/** @} */ /* end of ddr_Generic_Resources group */
90510 +
90511 +
90512 +
90513 +#endif /* __DDR_SDT_EXT_H */
90514 +
90515 --- /dev/null
90516 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
90517 @@ -0,0 +1,233 @@
90518 +/*
90519 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90520 + *
90521 + * Redistribution and use in source and binary forms, with or without
90522 + * modification, are permitted provided that the following conditions are met:
90523 + * * Redistributions of source code must retain the above copyright
90524 + * notice, this list of conditions and the following disclaimer.
90525 + * * Redistributions in binary form must reproduce the above copyright
90526 + * notice, this list of conditions and the following disclaimer in the
90527 + * documentation and/or other materials provided with the distribution.
90528 + * * Neither the name of Freescale Semiconductor nor the
90529 + * names of its contributors may be used to endorse or promote products
90530 + * derived from this software without specific prior written permission.
90531 + *
90532 + *
90533 + * ALTERNATIVELY, this software may be distributed under the terms of the
90534 + * GNU General Public License ("GPL") as published by the Free Software
90535 + * Foundation, either version 2 of that License or (at your option) any
90536 + * later version.
90537 + *
90538 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90539 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90540 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90541 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90542 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90543 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90544 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90545 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90546 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90547 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90548 + */
90549 +
90550 +
90551 +/**************************************************************************//**
90552 + @File debug_ext.h
90553 +
90554 + @Description Debug mode definitions.
90555 +*//***************************************************************************/
90556 +
90557 +#ifndef __DEBUG_EXT_H
90558 +#define __DEBUG_EXT_H
90559 +
90560 +#include "std_ext.h"
90561 +#include "xx_ext.h"
90562 +#include "memcpy_ext.h"
90563 +#if (DEBUG_ERRORS > 0)
90564 +#include "sprint_ext.h"
90565 +#include "string_ext.h"
90566 +#endif /* DEBUG_ERRORS > 0 */
90567 +
90568 +
90569 +#if (DEBUG_ERRORS > 0)
90570 +
90571 +/* Internally used macros */
90572 +
90573 +#define DUMP_Print XX_Print
90574 +#define DUMP_MAX_LEVELS 6
90575 +#define DUMP_IDX_LEN 6
90576 +#define DUMP_MAX_STR 64
90577 +
90578 +
90579 +#define _CREATE_DUMP_SUBSTR(phrase) \
90580 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
90581 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
90582 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
90583 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
90584 + { \
90585 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
90586 + if (dumpIsArr[dumpTmpLevel]) \
90587 + { \
90588 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
90589 + p_DumpToken = strtok(NULL, "."); \
90590 + } \
90591 + if ((p_DumpToken != NULL) && \
90592 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
90593 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
90594 + }
90595 +
90596 +
90597 +/**************************************************************************//**
90598 + @Group gen_id General Drivers Utilities
90599 +
90600 + @Description External routines.
90601 +
90602 + @{
90603 +*//***************************************************************************/
90604 +
90605 +/**************************************************************************//**
90606 + @Group dump_id Memory and Registers Dump Mechanism
90607 +
90608 + @Description Macros for dumping memory mapped structures.
90609 +
90610 + @{
90611 +*//***************************************************************************/
90612 +
90613 +/**************************************************************************//**
90614 + @Description Declaration of dump mechanism variables.
90615 +
90616 + This macro must be declared at the beginning of each routine
90617 + which uses the dump mechanism macros, before the routine's code
90618 + starts.
90619 +*//***************************************************************************/
90620 +#define DECLARE_DUMP \
90621 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
90622 + char dumpSubStr[DUMP_MAX_STR] = ""; \
90623 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
90624 + char *p_DumpToken = NULL; \
90625 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
90626 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
90627 + /* Prevent warnings if not all used */ \
90628 + UNUSED(dumpIdxStr[0][0]); \
90629 + UNUSED(dumpSubStr[0]); \
90630 + UNUSED(dumpTmpStr[0]); \
90631 + UNUSED(p_DumpToken); \
90632 + UNUSED(dumpArrIdx); \
90633 + UNUSED(dumpArrSize); \
90634 + UNUSED(dumpLevel); \
90635 + UNUSED(dumpTmpLevel); \
90636 + UNUSED(dumpIsArr[0]);
90637 +
90638 +
90639 +/**************************************************************************//**
90640 + @Description Prints a title for a subsequent dumped structure or memory.
90641 +
90642 + The inputs for this macro are the structure/memory title and
90643 + its base addresses.
90644 +*//***************************************************************************/
90645 +#define DUMP_TITLE(addr, msg) \
90646 + DUMP_Print("\r\n"); DUMP_Print msg; \
90647 + if (addr) \
90648 + DUMP_Print(" (%p)", (addr)); \
90649 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
90650 +
90651 +/**************************************************************************//**
90652 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
90653 +
90654 + The inputs for this macro are the sub-structure subtitle.
90655 + A separating line with this subtitle will be printed.
90656 +*//***************************************************************************/
90657 +#define DUMP_SUBTITLE(subtitle) \
90658 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
90659 +
90660 +
90661 +/**************************************************************************//**
90662 + @Description Dumps a memory region in 4-bytes aligned format.
90663 +
90664 + The inputs for this macro are the base addresses and size
90665 + (in bytes) of the memory region.
90666 +*//***************************************************************************/
90667 +#define DUMP_MEMORY(addr, size) \
90668 + MemDisp((uint8_t *)(addr), (int)(size))
90669 +
90670 +
90671 +/**************************************************************************//**
90672 + @Description Declares a dump loop, for dumping a sub-structure array.
90673 +
90674 + The inputs for this macro are:
90675 + - idx: an index variable, for indexing the sub-structure items
90676 + inside the loop. This variable must be declared separately
90677 + in the beginning of the routine.
90678 + - cnt: the number of times to repeat the loop. This number should
90679 + equal the number of items in the sub-structures array.
90680 +
90681 + Note, that the body of the loop must be written inside brackets.
90682 +*//***************************************************************************/
90683 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
90684 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
90685 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
90686 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
90687 +
90688 +
90689 +/**************************************************************************//**
90690 + @Description Dumps a structure's member variable.
90691 +
90692 + The input for this macro is the full reference for the member
90693 + variable, where the structure is referenced using a pointer.
90694 +
90695 + Note, that a members array must be dumped using DUMP_ARR macro,
90696 + rather than using this macro.
90697 +
90698 + If the member variable is part of a sub-structure hierarchy,
90699 + the full hierarchy (including array indexing) must be specified.
90700 +
90701 + Examples: p_Struct->member
90702 + p_Struct->sub.member
90703 + p_Struct->sub[i].member
90704 +*//***************************************************************************/
90705 +#define DUMP_VAR(st, phrase) \
90706 + do { \
90707 + void *addr = (void *)&((st)->phrase); \
90708 + physAddress_t physAddr = XX_VirtToPhys(addr); \
90709 + _CREATE_DUMP_SUBSTR(phrase); \
90710 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
90711 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
90712 + } while (0)
90713 +
90714 +
90715 +/**************************************************************************//**
90716 + @Description Dumps a structure's members array.
90717 +
90718 + The input for this macro is the full reference for the members
90719 + array, where the structure is referenced using a pointer.
90720 +
90721 + If the members array is part of a sub-structure hierarchy,
90722 + the full hierarchy (including array indexing) must be specified.
90723 +
90724 + Examples: p_Struct->array
90725 + p_Struct->sub.array
90726 + p_Struct->sub[i].array
90727 +*//***************************************************************************/
90728 +#define DUMP_ARR(st, phrase) \
90729 + do { \
90730 + physAddress_t physAddr; \
90731 + _CREATE_DUMP_SUBSTR(phrase); \
90732 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
90733 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
90734 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
90735 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
90736 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
90737 + } \
90738 + } while (0)
90739 +
90740 +
90741 +
90742 +#endif /* DEBUG_ERRORS > 0 */
90743 +
90744 +
90745 +/** @} */ /* end of dump_id group */
90746 +/** @} */ /* end of gen_id group */
90747 +
90748 +
90749 +#endif /* __DEBUG_EXT_H */
90750 +
90751 --- /dev/null
90752 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
90753 @@ -0,0 +1,447 @@
90754 +/*
90755 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90756 + *
90757 + * Redistribution and use in source and binary forms, with or without
90758 + * modification, are permitted provided that the following conditions are met:
90759 + * * Redistributions of source code must retain the above copyright
90760 + * notice, this list of conditions and the following disclaimer.
90761 + * * Redistributions in binary form must reproduce the above copyright
90762 + * notice, this list of conditions and the following disclaimer in the
90763 + * documentation and/or other materials provided with the distribution.
90764 + * * Neither the name of Freescale Semiconductor nor the
90765 + * names of its contributors may be used to endorse or promote products
90766 + * derived from this software without specific prior written permission.
90767 + *
90768 + *
90769 + * ALTERNATIVELY, this software may be distributed under the terms of the
90770 + * GNU General Public License ("GPL") as published by the Free Software
90771 + * Foundation, either version 2 of that License or (at your option) any
90772 + * later version.
90773 + *
90774 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90775 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90776 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90777 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90778 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90779 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90780 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90781 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90782 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90783 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90784 + */
90785 +
90786 +
90787 +/**************************************************************************//**
90788 +
90789 + @File endian_ext.h
90790 +
90791 + @Description Big/little endian swapping routines.
90792 +*//***************************************************************************/
90793 +
90794 +#ifndef __ENDIAN_EXT_H
90795 +#define __ENDIAN_EXT_H
90796 +
90797 +#include "std_ext.h"
90798 +
90799 +
90800 +/**************************************************************************//**
90801 + @Group gen_id General Drivers Utilities
90802 +
90803 + @Description General usage API. This API is intended for usage by both the
90804 + internal modules and the user's application.
90805 +
90806 + @{
90807 +*//***************************************************************************/
90808 +
90809 +/**************************************************************************//**
90810 + @Group endian_id Big/Little-Endian Conversion
90811 +
90812 + @Description Routines and macros for Big/Little-Endian conversion and
90813 + general byte swapping.
90814 +
90815 + All routines and macros are expecting unsigned values as
90816 + parameters, but will generate the correct result also for
90817 + signed values. Therefore, signed/unsigned casting is allowed.
90818 + @{
90819 +*//***************************************************************************/
90820 +
90821 +/**************************************************************************//**
90822 + @Collection Byte-Swap Macros
90823 +
90824 + Macros for swapping byte order.
90825 +
90826 + @Cautions The parameters of these macros are evaluated multiple times.
90827 + For calculated expressions or expressions that contain function
90828 + calls it is recommended to use the byte-swap routines.
90829 +
90830 + @{
90831 +*//***************************************************************************/
90832 +
90833 +/**************************************************************************//**
90834 + @Description Swaps the byte order of a given 16-bit value.
90835 +
90836 + @Param[in] val - The 16-bit value to swap.
90837 +
90838 + @Return The byte-swapped value..
90839 +
90840 + @Cautions The given value is evaluated multiple times by this macro.
90841 + For calculated expressions or expressions that contain function
90842 + calls it is recommended to use the SwapUint16() routine.
90843 +
90844 + @hideinitializer
90845 +*//***************************************************************************/
90846 +#define SWAP_UINT16(val) \
90847 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
90848 +
90849 +/**************************************************************************//**
90850 + @Description Swaps the byte order of a given 32-bit value.
90851 +
90852 + @Param[in] val - The 32-bit value to swap.
90853 +
90854 + @Return The byte-swapped value..
90855 +
90856 + @Cautions The given value is evaluated multiple times by this macro.
90857 + For calculated expressions or expressions that contain function
90858 + calls it is recommended to use the SwapUint32() routine.
90859 +
90860 + @hideinitializer
90861 +*//***************************************************************************/
90862 +#define SWAP_UINT32(val) \
90863 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
90864 + (((val) & 0x0000FF00) << 8) | \
90865 + (((val) & 0x00FF0000) >> 8) | \
90866 + (((val) & 0xFF000000) >> 24)))
90867 +
90868 +/**************************************************************************//**
90869 + @Description Swaps the byte order of a given 64-bit value.
90870 +
90871 + @Param[in] val - The 64-bit value to swap.
90872 +
90873 + @Return The byte-swapped value..
90874 +
90875 + @Cautions The given value is evaluated multiple times by this macro.
90876 + For calculated expressions or expressions that contain function
90877 + calls it is recommended to use the SwapUint64() routine.
90878 +
90879 + @hideinitializer
90880 +*//***************************************************************************/
90881 +#define SWAP_UINT64(val) \
90882 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
90883 + (((val) & 0x000000000000FF00ULL) << 40) | \
90884 + (((val) & 0x0000000000FF0000ULL) << 24) | \
90885 + (((val) & 0x00000000FF000000ULL) << 8) | \
90886 + (((val) & 0x000000FF00000000ULL) >> 8) | \
90887 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
90888 + (((val) & 0x00FF000000000000ULL) >> 40) | \
90889 + (((val) & 0xFF00000000000000ULL) >> 56)))
90890 +
90891 +/* @} */
90892 +
90893 +/**************************************************************************//**
90894 + @Collection Byte-Swap Routines
90895 +
90896 + Routines for swapping the byte order of a given parameter and
90897 + returning the swapped value.
90898 +
90899 + These inline routines are safer than the byte-swap macros,
90900 + because they evaluate the parameter expression only once.
90901 + @{
90902 +*//***************************************************************************/
90903 +
90904 +/**************************************************************************//**
90905 + @Function SwapUint16
90906 +
90907 + @Description Returns the byte-swapped value of a given 16-bit value.
90908 +
90909 + @Param[in] val - The 16-bit value.
90910 +
90911 + @Return The byte-swapped value of the parameter.
90912 +*//***************************************************************************/
90913 +static __inline__ uint16_t SwapUint16(uint16_t val)
90914 +{
90915 + return (uint16_t)(((val & 0x00FF) << 8) |
90916 + ((val & 0xFF00) >> 8));
90917 +}
90918 +
90919 +/**************************************************************************//**
90920 + @Function SwapUint32
90921 +
90922 + @Description Returns the byte-swapped value of a given 32-bit value.
90923 +
90924 + @Param[in] val - The 32-bit value.
90925 +
90926 + @Return The byte-swapped value of the parameter.
90927 +*//***************************************************************************/
90928 +static __inline__ uint32_t SwapUint32(uint32_t val)
90929 +{
90930 + return (uint32_t)(((val & 0x000000FF) << 24) |
90931 + ((val & 0x0000FF00) << 8) |
90932 + ((val & 0x00FF0000) >> 8) |
90933 + ((val & 0xFF000000) >> 24));
90934 +}
90935 +
90936 +/**************************************************************************//**
90937 + @Function SwapUint64
90938 +
90939 + @Description Returns the byte-swapped value of a given 64-bit value.
90940 +
90941 + @Param[in] val - The 64-bit value.
90942 +
90943 + @Return The byte-swapped value of the parameter.
90944 +*//***************************************************************************/
90945 +static __inline__ uint64_t SwapUint64(uint64_t val)
90946 +{
90947 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
90948 + ((val & 0x000000000000FF00ULL) << 40) |
90949 + ((val & 0x0000000000FF0000ULL) << 24) |
90950 + ((val & 0x00000000FF000000ULL) << 8) |
90951 + ((val & 0x000000FF00000000ULL) >> 8) |
90952 + ((val & 0x0000FF0000000000ULL) >> 24) |
90953 + ((val & 0x00FF000000000000ULL) >> 40) |
90954 + ((val & 0xFF00000000000000ULL) >> 56));
90955 +}
90956 +
90957 +/* @} */
90958 +
90959 +/**************************************************************************//**
90960 + @Collection In-place Byte-Swap-And-Set Routines
90961 +
90962 + Routines for swapping the byte order of a given variable and
90963 + setting the swapped value back to the same variable.
90964 + @{
90965 +*//***************************************************************************/
90966 +
90967 +/**************************************************************************//**
90968 + @Function SwapUint16P
90969 +
90970 + @Description Swaps the byte order of a given 16-bit variable.
90971 +
90972 + @Param[in] p_Val - Pointer to the 16-bit variable.
90973 +
90974 + @Return None.
90975 +*//***************************************************************************/
90976 +static __inline__ void SwapUint16P(uint16_t *p_Val)
90977 +{
90978 + *p_Val = SwapUint16(*p_Val);
90979 +}
90980 +
90981 +/**************************************************************************//**
90982 + @Function SwapUint32P
90983 +
90984 + @Description Swaps the byte order of a given 32-bit variable.
90985 +
90986 + @Param[in] p_Val - Pointer to the 32-bit variable.
90987 +
90988 + @Return None.
90989 +*//***************************************************************************/
90990 +static __inline__ void SwapUint32P(uint32_t *p_Val)
90991 +{
90992 + *p_Val = SwapUint32(*p_Val);
90993 +}
90994 +
90995 +/**************************************************************************//**
90996 + @Function SwapUint64P
90997 +
90998 + @Description Swaps the byte order of a given 64-bit variable.
90999 +
91000 + @Param[in] p_Val - Pointer to the 64-bit variable.
91001 +
91002 + @Return None.
91003 +*//***************************************************************************/
91004 +static __inline__ void SwapUint64P(uint64_t *p_Val)
91005 +{
91006 + *p_Val = SwapUint64(*p_Val);
91007 +}
91008 +
91009 +/* @} */
91010 +
91011 +
91012 +/**************************************************************************//**
91013 + @Collection Little-Endian Conversion Macros
91014 +
91015 + These macros convert given parameters to or from Little-Endian
91016 + format. Use these macros when you want to read or write a specific
91017 + Little-Endian value in memory, without a-priori knowing the CPU
91018 + byte order.
91019 +
91020 + These macros use the byte-swap routines. For conversion of
91021 + constants in initialization structures, you may use the CONST
91022 + versions of these macros (see below), which are using the
91023 + byte-swap macros instead.
91024 + @{
91025 +*//***************************************************************************/
91026 +
91027 +/**************************************************************************//**
91028 + @Description Converts a given 16-bit value from CPU byte order to
91029 + Little-Endian byte order.
91030 +
91031 + @Param[in] val - The 16-bit value to convert.
91032 +
91033 + @Return The converted value.
91034 +
91035 + @hideinitializer
91036 +*//***************************************************************************/
91037 +#define CPU_TO_LE16(val) SwapUint16(val)
91038 +
91039 +/**************************************************************************//**
91040 + @Description Converts a given 32-bit value from CPU byte order to
91041 + Little-Endian byte order.
91042 +
91043 + @Param[in] val - The 32-bit value to convert.
91044 +
91045 + @Return The converted value.
91046 +
91047 + @hideinitializer
91048 +*//***************************************************************************/
91049 +#define CPU_TO_LE32(val) SwapUint32(val)
91050 +
91051 +/**************************************************************************//**
91052 + @Description Converts a given 64-bit value from CPU byte order to
91053 + Little-Endian byte order.
91054 +
91055 + @Param[in] val - The 64-bit value to convert.
91056 +
91057 + @Return The converted value.
91058 +
91059 + @hideinitializer
91060 +*//***************************************************************************/
91061 +#define CPU_TO_LE64(val) SwapUint64(val)
91062 +
91063 +
91064 +/**************************************************************************//**
91065 + @Description Converts a given 16-bit value from Little-Endian byte order to
91066 + CPU byte order.
91067 +
91068 + @Param[in] val - The 16-bit value to convert.
91069 +
91070 + @Return The converted value.
91071 +
91072 + @hideinitializer
91073 +*//***************************************************************************/
91074 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
91075 +
91076 +/**************************************************************************//**
91077 + @Description Converts a given 32-bit value from Little-Endian byte order to
91078 + CPU byte order.
91079 +
91080 + @Param[in] val - The 32-bit value to convert.
91081 +
91082 + @Return The converted value.
91083 +
91084 + @hideinitializer
91085 +*//***************************************************************************/
91086 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
91087 +
91088 +/**************************************************************************//**
91089 + @Description Converts a given 64-bit value from Little-Endian byte order to
91090 + CPU byte order.
91091 +
91092 + @Param[in] val - The 64-bit value to convert.
91093 +
91094 + @Return The converted value.
91095 +
91096 + @hideinitializer
91097 +*//***************************************************************************/
91098 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
91099 +
91100 +/* @} */
91101 +
91102 +/**************************************************************************//**
91103 + @Collection Little-Endian Constant Conversion Macros
91104 +
91105 + These macros convert given constants to or from Little-Endian
91106 + format. Use these macros when you want to read or write a specific
91107 + Little-Endian constant in memory, without a-priori knowing the
91108 + CPU byte order.
91109 +
91110 + These macros use the byte-swap macros, therefore can be used for
91111 + conversion of constants in initialization structures.
91112 +
91113 + @Cautions The parameters of these macros are evaluated multiple times.
91114 + For non-constant expressions, use the non-CONST macro versions.
91115 +
91116 + @{
91117 +*//***************************************************************************/
91118 +
91119 +/**************************************************************************//**
91120 + @Description Converts a given 16-bit constant from CPU byte order to
91121 + Little-Endian byte order.
91122 +
91123 + @Param[in] val - The 16-bit value to convert.
91124 +
91125 + @Return The converted value.
91126 +
91127 + @hideinitializer
91128 +*//***************************************************************************/
91129 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
91130 +
91131 +/**************************************************************************//**
91132 + @Description Converts a given 32-bit constant from CPU byte order to
91133 + Little-Endian byte order.
91134 +
91135 + @Param[in] val - The 32-bit value to convert.
91136 +
91137 + @Return The converted value.
91138 +
91139 + @hideinitializer
91140 +*//***************************************************************************/
91141 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
91142 +
91143 +/**************************************************************************//**
91144 + @Description Converts a given 64-bit constant from CPU byte order to
91145 + Little-Endian byte order.
91146 +
91147 + @Param[in] val - The 64-bit value to convert.
91148 +
91149 + @Return The converted value.
91150 +
91151 + @hideinitializer
91152 +*//***************************************************************************/
91153 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
91154 +
91155 +
91156 +/**************************************************************************//**
91157 + @Description Converts a given 16-bit constant from Little-Endian byte order
91158 + to CPU byte order.
91159 +
91160 + @Param[in] val - The 16-bit value to convert.
91161 +
91162 + @Return The converted value.
91163 +
91164 + @hideinitializer
91165 +*//***************************************************************************/
91166 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
91167 +
91168 +/**************************************************************************//**
91169 + @Description Converts a given 32-bit constant from Little-Endian byte order
91170 + to CPU byte order.
91171 +
91172 + @Param[in] val - The 32-bit value to convert.
91173 +
91174 + @Return The converted value.
91175 +
91176 + @hideinitializer
91177 +*//***************************************************************************/
91178 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
91179 +
91180 +/**************************************************************************//**
91181 + @Description Converts a given 64-bit constant from Little-Endian byte order
91182 + to CPU byte order.
91183 +
91184 + @Param[in] val - The 64-bit value to convert.
91185 +
91186 + @Return The converted value.
91187 +
91188 + @hideinitializer
91189 +*//***************************************************************************/
91190 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
91191 +
91192 +/* @} */
91193 +
91194 +
91195 +/** @} */ /* end of endian_id group */
91196 +/** @} */ /* end of gen_id group */
91197 +
91198 +
91199 +#endif /* __ENDIAN_EXT_H */
91200 +
91201 --- /dev/null
91202 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
91203 @@ -0,0 +1,205 @@
91204 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91205 + * All rights reserved.
91206 + *
91207 + * Redistribution and use in source and binary forms, with or without
91208 + * modification, are permitted provided that the following conditions are met:
91209 + * * Redistributions of source code must retain the above copyright
91210 + * notice, this list of conditions and the following disclaimer.
91211 + * * Redistributions in binary form must reproduce the above copyright
91212 + * notice, this list of conditions and the following disclaimer in the
91213 + * documentation and/or other materials provided with the distribution.
91214 + * * Neither the name of Freescale Semiconductor nor the
91215 + * names of its contributors may be used to endorse or promote products
91216 + * derived from this software without specific prior written permission.
91217 + *
91218 + *
91219 + * ALTERNATIVELY, this software may be distributed under the terms of the
91220 + * GNU General Public License ("GPL") as published by the Free Software
91221 + * Foundation, either version 2 of that License or (at your option) any
91222 + * later version.
91223 + *
91224 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91225 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91226 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91227 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91228 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91229 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91230 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91231 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91232 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91233 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91234 + */
91235 +
91236 +
91237 +/**************************************************************************//**
91238 + @File enet_ext.h
91239 +
91240 + @Description Ethernet generic definitions and enums.
91241 +*//***************************************************************************/
91242 +
91243 +#ifndef __ENET_EXT_H
91244 +#define __ENET_EXT_H
91245 +
91246 +#include "fsl_enet.h"
91247 +
91248 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
91249 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
91250 +
91251 +
91252 +/**************************************************************************//**
91253 + @Description Ethernet Address
91254 +*//***************************************************************************/
91255 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
91256 +
91257 +/**************************************************************************//**
91258 + @Description Ethernet Address Type.
91259 +*//***************************************************************************/
91260 +typedef enum e_EnetAddrType
91261 +{
91262 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
91263 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
91264 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
91265 +} e_EnetAddrType;
91266 +
91267 +/**************************************************************************//**
91268 + @Description Ethernet MAC-PHY Interface
91269 +*//***************************************************************************/
91270 +typedef enum e_EnetInterface
91271 +{
91272 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
91273 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
91274 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
91275 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
91276 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
91277 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
91278 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
91279 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
91280 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
91281 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
91282 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
91283 +} e_EnetInterface;
91284 +
91285 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
91286 + auto-negotiation between MAC and phy
91287 + or backplane;
91288 + Note: 1000BaseX auto-negotiation relates
91289 + only to interface between MAC and phy/backplane,
91290 + SGMII phy can still synchronize with far-end phy
91291 + at 10Mbps, 100Mbps or 1000Mbps */
91292 +
91293 +/**************************************************************************//**
91294 + @Description Ethernet Duplex Mode
91295 +*//***************************************************************************/
91296 +typedef enum e_EnetDuplexMode
91297 +{
91298 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
91299 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
91300 +} e_EnetDuplexMode;
91301 +
91302 +/**************************************************************************//**
91303 + @Description Ethernet Speed (nominal data rate)
91304 +*//***************************************************************************/
91305 +typedef enum e_EnetSpeed
91306 +{
91307 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
91308 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
91309 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
91310 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
91311 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
91312 +} e_EnetSpeed;
91313 +
91314 +/**************************************************************************//**
91315 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
91316 +*//***************************************************************************/
91317 +typedef enum e_EnetMode
91318 +{
91319 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
91320 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
91321 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
91322 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
91323 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
91324 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
91325 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
91326 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
91327 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
91328 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
91329 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
91330 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
91331 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
91332 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
91333 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
91334 + SGMII phy according to Cisco SGMII specification */
91335 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
91336 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
91337 + SGMII phy according to Cisco SGMII specification */
91338 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
91339 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
91340 + SGMII phy according to Cisco SGMII specification */
91341 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
91342 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
91343 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
91344 + MAC and SGMII phy or backplane */
91345 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
91346 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
91347 + MAC and SGMII phy or backplane */
91348 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
91349 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
91350 + MAC and SGMII phy or backplane */
91351 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
91352 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
91353 + QSGMII phy according to Cisco QSGMII specification */
91354 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
91355 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
91356 + MAC and QSGMII phy or backplane */
91357 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
91358 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
91359 +} e_EnetMode;
91360 +
91361 +
91362 +#define IS_ENET_MODE_VALID(mode) \
91363 + (((mode) == e_ENET_MODE_MII_10 ) || \
91364 + ((mode) == e_ENET_MODE_MII_100 ) || \
91365 + ((mode) == e_ENET_MODE_RMII_10 ) || \
91366 + ((mode) == e_ENET_MODE_RMII_100 ) || \
91367 + ((mode) == e_ENET_MODE_SMII_10 ) || \
91368 + ((mode) == e_ENET_MODE_SMII_100 ) || \
91369 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
91370 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
91371 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
91372 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
91373 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
91374 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
91375 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
91376 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
91377 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
91378 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
91379 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
91380 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
91381 + ((mode) == e_ENET_MODE_XGMII_10000) || \
91382 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
91383 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
91384 + ((mode) == e_ENET_MODE_XFI_10000))
91385 +
91386 +
91387 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
91388 +
91389 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
91390 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
91391 +
91392 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
91393 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
91394 + ((uint64_t)(_enetAddr)[1] << 32) | \
91395 + ((uint64_t)(_enetAddr)[2] << 24) | \
91396 + ((uint64_t)(_enetAddr)[3] << 16) | \
91397 + ((uint64_t)(_enetAddr)[4] << 8) | \
91398 + ((uint64_t)(_enetAddr)[5]))
91399 +
91400 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
91401 + do { \
91402 + int i; \
91403 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
91404 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
91405 + } while (0)
91406 +
91407 +
91408 +#endif /* __ENET_EXT_H */
91409 --- /dev/null
91410 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
91411 @@ -0,0 +1,529 @@
91412 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91413 + * All rights reserved.
91414 + *
91415 + * Redistribution and use in source and binary forms, with or without
91416 + * modification, are permitted provided that the following conditions are met:
91417 + * * Redistributions of source code must retain the above copyright
91418 + * notice, this list of conditions and the following disclaimer.
91419 + * * Redistributions in binary form must reproduce the above copyright
91420 + * notice, this list of conditions and the following disclaimer in the
91421 + * documentation and/or other materials provided with the distribution.
91422 + * * Neither the name of Freescale Semiconductor nor the
91423 + * names of its contributors may be used to endorse or promote products
91424 + * derived from this software without specific prior written permission.
91425 + *
91426 + *
91427 + * ALTERNATIVELY, this software may be distributed under the terms of the
91428 + * GNU General Public License ("GPL") as published by the Free Software
91429 + * Foundation, either version 2 of that License or (at your option) any
91430 + * later version.
91431 + *
91432 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91433 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91434 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91435 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91436 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91437 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91438 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91439 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91440 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91441 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91442 + */
91443 +
91444 +
91445 +/**************************************************************************//**
91446 + @File error_ext.h
91447 +
91448 + @Description Error definitions.
91449 +*//***************************************************************************/
91450 +
91451 +#ifndef __ERROR_EXT_H
91452 +#define __ERROR_EXT_H
91453 +
91454 +#if !defined(NCSW_LINUX)
91455 +#include <errno.h>
91456 +#endif
91457 +
91458 +#include "std_ext.h"
91459 +#include "xx_ext.h"
91460 +#include "core_ext.h"
91461 +
91462 +
91463 +
91464 +
91465 +/**************************************************************************//**
91466 + @Group gen_id General Drivers Utilities
91467 +
91468 + @Description External routines.
91469 +
91470 + @{
91471 +*//***************************************************************************/
91472 +
91473 +/**************************************************************************//**
91474 + @Group gen_error_id Errors, Events and Debug
91475 +
91476 + @Description External routines.
91477 +
91478 + @{
91479 +*//***************************************************************************/
91480 +
91481 +/******************************************************************************
91482 +The scheme below provides the bits description for error codes:
91483 +
91484 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
91485 +| Reserved (should be zero) | Module ID |
91486 +
91487 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
91488 +| Error Type |
91489 +******************************************************************************/
91490 +
91491 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
91492 +
91493 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
91494 + /**< Extract module code from error code (#t_Error) */
91495 +
91496 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
91497 + /**< Extract error type (#e_ErrorType) from
91498 + error code (#t_Error) */
91499 +
91500 +
91501 +/**************************************************************************//**
91502 + @Description Error Type Enumeration
91503 +*//***************************************************************************/
91504 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
91505 +{ /* ------------------------------------------------------------ */
91506 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
91507 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
91508 + /* String: none, or device name. */
91509 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
91510 + /* String: none. */
91511 + ,E_NOT_AVAILABLE = EAGAIN
91512 + /**< Resource is unavailable. */
91513 + /* String: none, unless the operation is not the main goal
91514 + of the function (in this case add resource description). */
91515 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
91516 + /* String: description of item for which allocation failed. */
91517 + ,E_INVALID_ADDRESS = EFAULT
91518 + /**< Invalid address. */
91519 + /* String: description of the specific violation. */
91520 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
91521 + /* String: none, unless the operation is not the main goal
91522 + of the function (in this case add resource description). */
91523 + ,E_ALREADY_EXISTS = EEXIST
91524 + /**< Requested resource or item already exists. */
91525 + /* Use when resource duplication or sharing are not allowed.
91526 + String: none, unless the operation is not the main goal
91527 + of the function (in this case add item description). */
91528 + ,E_INVALID_OPERATION = ENODEV
91529 + /**< The operation/command is invalid (unrecognized). */
91530 + /* String: none. */
91531 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
91532 + /* Use for non-enumeration parameters, and
91533 + only when other error types are not suitable.
91534 + String: parameter description + "(should be <attribute>)",
91535 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
91536 + "Channel number (should be even)". */
91537 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
91538 + /* Don't use this error for enumeration parameters.
91539 + String: parameter description + "(should be %d-%d)",
91540 + e.g: "Number of pad characters (should be 0-15)". */
91541 + ,E_NOT_SUPPORTED = ENOSYS
91542 + /**< The function is not supported or not implemented. */
91543 + /* String: none. */
91544 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
91545 + /* String: none. */
91546 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
91547 + /* String: none, unless the function takes in more than one
91548 + handle (in this case add the handle description) */
91549 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
91550 + /* String: none, unless the function takes in more than one
91551 + ID (in this case add the ID description) */
91552 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
91553 + /* String: pointer description. */
91554 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
91555 + /* Use for enumeration values, only when other error types
91556 + are not suitable.
91557 + String: parameter description. */
91558 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
91559 + /* String: none, unless the function takes in more than one
91560 + communication mode indications (in this case add
91561 + parameter description). */
91562 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
91563 + /* String: none, unless the function takes in more than one
91564 + memory types (in this case add memory description,
91565 + e.g: "Data memory", "Buffer descriptors memory"). */
91566 + ,E_INVALID_CLOCK /**< Invalid clock. */
91567 + /* String: none, unless the function takes in more than one
91568 + clocks (in this case add clock description,
91569 + e.g: "Rx clock", "Tx clock"). */
91570 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
91571 + /* String: description of the conflicting settings. */
91572 + ,E_NOT_ALIGNED /**< Non-aligned address. */
91573 + /* String: parameter description + "(should be %d-bytes aligned)",
91574 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
91575 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
91576 + /* Use only when the resource/item is uniquely identified.
91577 + String: none, unless the operation is not the main goal
91578 + of the function (in this case add item description). */
91579 + ,E_FULL /**< Resource is full. */
91580 + /* String: none, unless the operation is not the main goal
91581 + of the function (in this case add resource description). */
91582 + ,E_EMPTY /**< Resource is empty. */
91583 + /* String: none, unless the operation is not the main goal
91584 + of the function (in this case add resource description). */
91585 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
91586 + /* String: none, unless the operation is not the main goal
91587 + of the function (in this case add item description). */
91588 + ,E_READ_FAILED /**< Read access failed on memory/device. */
91589 + /* String: none, or device name. */
91590 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
91591 + /* String: none. */
91592 + ,E_SEND_FAILED /**< Send operation failed on device. */
91593 + /* String: none, or device name. */
91594 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
91595 + /* String: none, or device name. */
91596 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
91597 + /* String: none. */
91598 +
91599 + ,E_DUMMY_LAST /* NEVER USED */
91600 +
91601 +} e_ErrorType;
91602 +
91603 +/**************************************************************************//**
91604 + @Description Event Type Enumeration
91605 +*//***************************************************************************/
91606 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
91607 +{ /* ------------------------------------------------------------ */
91608 + EV_NO_EVENT = 0 /**< No event; Never used. */
91609 +
91610 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
91611 + complete packets);
91612 + Flags: error flags in case of error, zero otherwise. */
91613 + /* String: reason for discard, e.g: "Error in frame",
91614 + "Disordered frame", "Incomplete frame", "No frame object". */
91615 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
91616 + Flags: usually status flags from the buffer descriptor. */
91617 + /* String: none. */
91618 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
91619 + Flags: usually status flags from the buffer descriptor. */
91620 + /* String: none. */
91621 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
91622 + Flags: zero. */
91623 + /* String: none. */
91624 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
91625 + Flags: zero. */
91626 + /* String: none. */
91627 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
91628 + Flags: zero. */
91629 + /* String: none. */
91630 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
91631 + Flags: zero. */
91632 + /* String: none. */
91633 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
91634 + Flags: zero. */
91635 + /* String: none. */
91636 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
91637 + Flags: zero. */
91638 + /* String: none. */
91639 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
91640 + Flags: zero. */
91641 + /* String: none. */
91642 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
91643 + Flags: zero. */
91644 + /* String: object description (name). */
91645 + ,EV_BUS_ERROR /**< Illegal access on bus;
91646 + Flags: the address (if available) or bus identifier */
91647 + /* String: bus/address/module description. */
91648 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
91649 + Flags: zero. */
91650 + /* String: none. */
91651 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
91652 + Flags: zero. */
91653 + /* String: none. */
91654 + ,EV_DUMMY_LAST
91655 +
91656 +} e_Event;
91657 +
91658 +
91659 +/**************************************************************************//**
91660 + @Collection Debug Levels for Errors and Events
91661 +
91662 + The level description refers to errors only.
91663 + For events, classification is done by the user.
91664 +
91665 + The TRACE, INFO and WARNING levels are allowed only when using
91666 + the DBG macro, and are not allowed when using the error macros
91667 + (RETURN_ERROR or REPORT_ERROR).
91668 + @{
91669 +*//***************************************************************************/
91670 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
91671 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
91672 + configuration. */
91673 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
91674 + parameters may be successful. */
91675 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
91676 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
91677 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
91678 +
91679 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
91680 +
91681 +/* @} */
91682 +
91683 +
91684 +
91685 +#define NO_MSG ("")
91686 +
91687 +#ifndef DEBUG_GLOBAL_LEVEL
91688 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
91689 +#endif /* DEBUG_GLOBAL_LEVEL */
91690 +
91691 +#ifndef ERROR_GLOBAL_LEVEL
91692 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
91693 +#endif /* ERROR_GLOBAL_LEVEL */
91694 +
91695 +#ifndef EVENT_GLOBAL_LEVEL
91696 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
91697 +#endif /* EVENT_GLOBAL_LEVEL */
91698 +
91699 +#ifdef EVENT_LOCAL_LEVEL
91700 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
91701 +#else
91702 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
91703 +#endif /* EVENT_LOCAL_LEVEL */
91704 +
91705 +
91706 +#ifndef DEBUG_DYNAMIC_LEVEL
91707 +#define DEBUG_USING_STATIC_LEVEL
91708 +
91709 +#ifdef DEBUG_STATIC_LEVEL
91710 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
91711 +#else
91712 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
91713 +#endif /* DEBUG_STATIC_LEVEL */
91714 +
91715 +#else /* DEBUG_DYNAMIC_LEVEL */
91716 +#ifdef DEBUG_STATIC_LEVEL
91717 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
91718 +#else
91719 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
91720 +#endif /* DEBUG_STATIC_LEVEL */
91721 +#endif /* !DEBUG_DYNAMIC_LEVEL */
91722 +
91723 +
91724 +#ifndef ERROR_DYNAMIC_LEVEL
91725 +
91726 +#ifdef ERROR_STATIC_LEVEL
91727 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
91728 +#else
91729 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
91730 +#endif /* ERROR_STATIC_LEVEL */
91731 +
91732 +#else /* ERROR_DYNAMIC_LEVEL */
91733 +#ifdef ERROR_STATIC_LEVEL
91734 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
91735 +#else
91736 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
91737 +#endif /* ERROR_STATIC_LEVEL */
91738 +#endif /* !ERROR_DYNAMIC_LEVEL */
91739 +
91740 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
91741 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
91742 +
91743 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
91744 +/* No debug/error/event messages at all */
91745 +#define DBG(_level, _vmsg)
91746 +
91747 +#define REPORT_ERROR(_level, _err, _vmsg)
91748 +
91749 +#define RETURN_ERROR(_level, _err, _vmsg) \
91750 + return ERROR_CODE(_err)
91751 +
91752 +#if (REPORT_EVENTS > 0)
91753 +
91754 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
91755 + do { \
91756 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
91757 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
91758 + } \
91759 + } while (0)
91760 +
91761 +#else
91762 +
91763 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
91764 +
91765 +#endif /* (REPORT_EVENTS > 0) */
91766 +
91767 +
91768 +#else /* DEBUG_ERRORS > 0 */
91769 +
91770 +extern const char *dbgLevelStrings[];
91771 +extern const char *moduleStrings[];
91772 +#if (REPORT_EVENTS > 0)
91773 +extern const char *eventStrings[];
91774 +#endif /* (REPORT_EVENTS > 0) */
91775 +
91776 +char * ErrTypeStrings (e_ErrorType err);
91777 +
91778 +
91779 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
91780 +/* No need for DBG macro - debug level is higher anyway */
91781 +#define DBG(_level, _vmsg)
91782 +#else
91783 +#define DBG(_level, _vmsg) \
91784 + do { \
91785 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
91786 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
91787 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
91788 + moduleStrings[__ERR_MODULE__ >> 16], \
91789 + PRINT_FMT_PARAMS); \
91790 + XX_Print _vmsg; \
91791 + XX_Print("\r\n"); \
91792 + } \
91793 + } while (0)
91794 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
91795 +
91796 +
91797 +#define REPORT_ERROR(_level, _err, _vmsg) \
91798 + do { \
91799 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
91800 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
91801 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
91802 + moduleStrings[__ERR_MODULE__ >> 16], \
91803 + PRINT_FMT_PARAMS, \
91804 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
91805 + XX_Print _vmsg; \
91806 + XX_Print("\r\n"); \
91807 + } \
91808 + } while (0)
91809 +
91810 +
91811 +#define RETURN_ERROR(_level, _err, _vmsg) \
91812 + do { \
91813 + REPORT_ERROR(_level, (_err), _vmsg); \
91814 + return ERROR_CODE(_err); \
91815 + } while (0)
91816 +
91817 +
91818 +#if (REPORT_EVENTS > 0)
91819 +
91820 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
91821 + do { \
91822 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
91823 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
91824 + dbgLevelStrings[_ev##_LEVEL - 1], \
91825 + moduleStrings[__ERR_MODULE__ >> 16], \
91826 + PRINT_FMT_PARAMS, \
91827 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
91828 + (uint16_t)(_flg)); \
91829 + XX_Print _vmsg; \
91830 + XX_Print("\r\n"); \
91831 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
91832 + } \
91833 + } while (0)
91834 +
91835 +#else /* not REPORT_EVENTS */
91836 +
91837 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
91838 +
91839 +#endif /* (REPORT_EVENTS > 0) */
91840 +
91841 +#endif /* (DEBUG_ERRORS > 0) */
91842 +
91843 +
91844 +/**************************************************************************//**
91845 + @Function ASSERT_COND
91846 +
91847 + @Description Assertion macro.
91848 +
91849 + @Param[in] _cond - The condition being checked, in positive form;
91850 + Failure of the condition triggers the assert.
91851 +*//***************************************************************************/
91852 +#ifdef DISABLE_ASSERTIONS
91853 +#define ASSERT_COND(_cond)
91854 +#else
91855 +#define ASSERT_COND(_cond) \
91856 + do { \
91857 + if (!(_cond)) { \
91858 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
91859 + PRINT_FMT_PARAMS); \
91860 + XX_Exit(1); \
91861 + } \
91862 + } while (0)
91863 +#endif /* DISABLE_ASSERTIONS */
91864 +
91865 +
91866 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
91867 +
91868 +#define CHECK_INIT_PARAMETERS(handle, f_check)
91869 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
91870 +
91871 +#else
91872 +
91873 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
91874 + do { \
91875 + t_Error err = f_check(handle); \
91876 + if (err != E_OK) { \
91877 + RETURN_ERROR(MAJOR, err, NO_MSG); \
91878 + } \
91879 + } while (0)
91880 +
91881 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
91882 + do { \
91883 + t_Error err = f_check(handle); \
91884 + if (err != E_OK) { \
91885 + REPORT_ERROR(MAJOR, err, NO_MSG); \
91886 + return (retval); \
91887 + } \
91888 + } while (0)
91889 +
91890 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
91891 +
91892 +#ifdef DISABLE_SANITY_CHECKS
91893 +
91894 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
91895 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
91896 +#define SANITY_CHECK_RETURN(_cond, _err)
91897 +#define SANITY_CHECK_EXIT(_cond, _err)
91898 +
91899 +#else /* DISABLE_SANITY_CHECKS */
91900 +
91901 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
91902 + do { \
91903 + if (!(_cond)) { \
91904 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
91905 + } \
91906 + } while (0)
91907 +
91908 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
91909 + do { \
91910 + if (!(_cond)) { \
91911 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
91912 + return (retval); \
91913 + } \
91914 + } while (0)
91915 +
91916 +#define SANITY_CHECK_RETURN(_cond, _err) \
91917 + do { \
91918 + if (!(_cond)) { \
91919 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
91920 + return; \
91921 + } \
91922 + } while (0)
91923 +
91924 +#define SANITY_CHECK_EXIT(_cond, _err) \
91925 + do { \
91926 + if (!(_cond)) { \
91927 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
91928 + XX_Exit(1); \
91929 + } \
91930 + } while (0)
91931 +
91932 +#endif /* DISABLE_SANITY_CHECKS */
91933 +
91934 +/** @} */ /* end of Debug/error Utils group */
91935 +
91936 +/** @} */ /* end of General Utils group */
91937 +
91938 +#endif /* __ERROR_EXT_H */
91939 +
91940 +
91941 --- /dev/null
91942 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
91943 @@ -0,0 +1,358 @@
91944 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91945 + * All rights reserved.
91946 + *
91947 + * Redistribution and use in source and binary forms, with or without
91948 + * modification, are permitted provided that the following conditions are met:
91949 + * * Redistributions of source code must retain the above copyright
91950 + * notice, this list of conditions and the following disclaimer.
91951 + * * Redistributions in binary form must reproduce the above copyright
91952 + * notice, this list of conditions and the following disclaimer in the
91953 + * documentation and/or other materials provided with the distribution.
91954 + * * Neither the name of Freescale Semiconductor nor the
91955 + * names of its contributors may be used to endorse or promote products
91956 + * derived from this software without specific prior written permission.
91957 + *
91958 + *
91959 + * ALTERNATIVELY, this software may be distributed under the terms of the
91960 + * GNU General Public License ("GPL") as published by the Free Software
91961 + * Foundation, either version 2 of that License or (at your option) any
91962 + * later version.
91963 + *
91964 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91965 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91966 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91967 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91968 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91969 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91970 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91971 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91972 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91973 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91974 + */
91975 +
91976 +
91977 +/**************************************************************************//**
91978 +
91979 + @File list_ext.h
91980 +
91981 + @Description External prototypes for list.c
91982 +*//***************************************************************************/
91983 +
91984 +#ifndef __LIST_EXT_H
91985 +#define __LIST_EXT_H
91986 +
91987 +
91988 +#include "std_ext.h"
91989 +
91990 +
91991 +/**************************************************************************//**
91992 + @Group etc_id Utility Library Application Programming Interface
91993 +
91994 + @Description External routines.
91995 +
91996 + @{
91997 +*//***************************************************************************/
91998 +
91999 +/**************************************************************************//**
92000 + @Group list_id List
92001 +
92002 + @Description List module functions,definitions and enums.
92003 +
92004 + @{
92005 +*//***************************************************************************/
92006 +
92007 +/**************************************************************************//**
92008 + @Description List structure.
92009 +*//***************************************************************************/
92010 +typedef struct List
92011 +{
92012 + struct List *p_Next; /**< A pointer to the next list object */
92013 + struct List *p_Prev; /**< A pointer to the previous list object */
92014 +} t_List;
92015 +
92016 +
92017 +/**************************************************************************//**
92018 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
92019 +
92020 + @Description Macro to get first/last/next/previous entry in a list.
92021 +
92022 + @Param[in] p_List - A pointer to a list.
92023 +*//***************************************************************************/
92024 +#define LIST_FIRST(p_List) (p_List)->p_Next
92025 +#define LIST_LAST(p_List) (p_List)->p_Prev
92026 +#define LIST_NEXT LIST_FIRST
92027 +#define LIST_PREV LIST_LAST
92028 +
92029 +
92030 +/**************************************************************************//**
92031 + @Function LIST_INIT
92032 +
92033 + @Description Macro for initialization of a list struct.
92034 +
92035 + @Param[in] lst - The t_List object to initialize.
92036 +*//***************************************************************************/
92037 +#define LIST_INIT(lst) {&(lst), &(lst)}
92038 +
92039 +
92040 +/**************************************************************************//**
92041 + @Function LIST
92042 +
92043 + @Description Macro to declare of a list.
92044 +
92045 + @Param[in] listName - The list object name.
92046 +*//***************************************************************************/
92047 +#define LIST(listName) t_List listName = LIST_INIT(listName)
92048 +
92049 +
92050 +/**************************************************************************//**
92051 + @Function INIT_LIST
92052 +
92053 + @Description Macro to initialize a list pointer.
92054 +
92055 + @Param[in] p_List - The list pointer.
92056 +*//***************************************************************************/
92057 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
92058 +
92059 +
92060 +/**************************************************************************//**
92061 + @Function LIST_OBJECT
92062 +
92063 + @Description Macro to get the struct (object) for this entry.
92064 +
92065 + @Param[in] type - The type of the struct (object) this list is embedded in.
92066 + @Param[in] member - The name of the t_List object within the struct.
92067 +
92068 + @Return The structure pointer for this entry.
92069 +*//***************************************************************************/
92070 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
92071 +#define LIST_OBJECT(p_List, type, member) \
92072 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
92073 +
92074 +
92075 +/**************************************************************************//**
92076 + @Function LIST_FOR_EACH
92077 +
92078 + @Description Macro to iterate over a list.
92079 +
92080 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92081 + @Param[in] p_Head - A pointer to the head for your list pointer.
92082 +
92083 + @Cautions You can't delete items with this routine.
92084 + For deletion use LIST_FOR_EACH_SAFE().
92085 +*//***************************************************************************/
92086 +#define LIST_FOR_EACH(p_Pos, p_Head) \
92087 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
92088 +
92089 +
92090 +/**************************************************************************//**
92091 + @Function LIST_FOR_EACH_SAFE
92092 +
92093 + @Description Macro to iterate over a list safe against removal of list entry.
92094 +
92095 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92096 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
92097 + @Param[in] p_Head - A pointer to the head for your list pointer.
92098 +*//***************************************************************************/
92099 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
92100 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
92101 + p_Pos != (p_Head); \
92102 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
92103 +
92104 +
92105 +/**************************************************************************//**
92106 + @Function LIST_FOR_EACH_OBJECT_SAFE
92107 +
92108 + @Description Macro to iterate over list of given type safely.
92109 +
92110 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92111 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
92112 + @Param[in] type - The type of the struct this is embedded in.
92113 + @Param[in] p_Head - A pointer to the head for your list pointer.
92114 + @Param[in] member - The name of the list_struct within the struct.
92115 +
92116 + @Cautions You can't delete items with this routine.
92117 + For deletion use LIST_FOR_EACH_SAFE().
92118 +*//***************************************************************************/
92119 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
92120 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
92121 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
92122 + &p_Pos->member != (p_Head); \
92123 + p_Pos = p_Tmp, \
92124 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
92125 +
92126 +/**************************************************************************//**
92127 + @Function LIST_FOR_EACH_OBJECT
92128 +
92129 + @Description Macro to iterate over list of given type.
92130 +
92131 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92132 + @Param[in] type - The type of the struct this is embedded in.
92133 + @Param[in] p_Head - A pointer to the head for your list pointer.
92134 + @Param[in] member - The name of the list_struct within the struct.
92135 +
92136 + @Cautions You can't delete items with this routine.
92137 + For deletion use LIST_FOR_EACH_SAFE().
92138 +*//***************************************************************************/
92139 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
92140 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
92141 + &p_Pos->member != (p_Head); \
92142 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
92143 +
92144 +
92145 +/**************************************************************************//**
92146 + @Function LIST_Add
92147 +
92148 + @Description Add a new entry to a list.
92149 +
92150 + Insert a new entry after the specified head.
92151 + This is good for implementing stacks.
92152 +
92153 + @Param[in] p_New - A pointer to a new list entry to be added.
92154 + @Param[in] p_Head - A pointer to a list head to add it after.
92155 +
92156 + @Return none.
92157 +*//***************************************************************************/
92158 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
92159 +{
92160 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
92161 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
92162 + LIST_PREV(p_New) = p_Head;
92163 + LIST_NEXT(p_Head) = p_New;
92164 +}
92165 +
92166 +
92167 +/**************************************************************************//**
92168 + @Function LIST_AddToTail
92169 +
92170 + @Description Add a new entry to a list.
92171 +
92172 + Insert a new entry before the specified head.
92173 + This is useful for implementing queues.
92174 +
92175 + @Param[in] p_New - A pointer to a new list entry to be added.
92176 + @Param[in] p_Head - A pointer to a list head to add it before.
92177 +
92178 + @Return none.
92179 +*//***************************************************************************/
92180 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
92181 +{
92182 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
92183 + LIST_PREV(p_New) = LIST_PREV(p_Head);
92184 + LIST_NEXT(p_New) = p_Head;
92185 + LIST_PREV(p_Head) = p_New;
92186 +}
92187 +
92188 +
92189 +/**************************************************************************//**
92190 + @Function LIST_Del
92191 +
92192 + @Description Deletes entry from a list.
92193 +
92194 + @Param[in] p_Entry - A pointer to the element to delete from the list.
92195 +
92196 + @Return none.
92197 +
92198 + @Cautions LIST_IsEmpty() on entry does not return true after this,
92199 + the entry is in an undefined state.
92200 +*//***************************************************************************/
92201 +static __inline__ void LIST_Del(t_List *p_Entry)
92202 +{
92203 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
92204 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
92205 +}
92206 +
92207 +
92208 +/**************************************************************************//**
92209 + @Function LIST_DelAndInit
92210 +
92211 + @Description Deletes entry from list and reinitialize it.
92212 +
92213 + @Param[in] p_Entry - A pointer to the element to delete from the list.
92214 +
92215 + @Return none.
92216 +*//***************************************************************************/
92217 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
92218 +{
92219 + LIST_Del(p_Entry);
92220 + INIT_LIST(p_Entry);
92221 +}
92222 +
92223 +
92224 +/**************************************************************************//**
92225 + @Function LIST_Move
92226 +
92227 + @Description Delete from one list and add as another's head.
92228 +
92229 + @Param[in] p_Entry - A pointer to the list entry to move.
92230 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
92231 +
92232 + @Return none.
92233 +*//***************************************************************************/
92234 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
92235 +{
92236 + LIST_Del(p_Entry);
92237 + LIST_Add(p_Entry, p_Head);
92238 +}
92239 +
92240 +
92241 +/**************************************************************************//**
92242 + @Function LIST_MoveToTail
92243 +
92244 + @Description Delete from one list and add as another's tail.
92245 +
92246 + @Param[in] p_Entry - A pointer to the entry to move.
92247 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
92248 +
92249 + @Return none.
92250 +*//***************************************************************************/
92251 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
92252 +{
92253 + LIST_Del(p_Entry);
92254 + LIST_AddToTail(p_Entry, p_Head);
92255 +}
92256 +
92257 +
92258 +/**************************************************************************//**
92259 + @Function LIST_IsEmpty
92260 +
92261 + @Description Tests whether a list is empty.
92262 +
92263 + @Param[in] p_List - A pointer to the list to test.
92264 +
92265 + @Return 1 if the list is empty, 0 otherwise.
92266 +*//***************************************************************************/
92267 +static __inline__ int LIST_IsEmpty(t_List *p_List)
92268 +{
92269 + return (LIST_FIRST(p_List) == p_List);
92270 +}
92271 +
92272 +
92273 +/**************************************************************************//**
92274 + @Function LIST_Append
92275 +
92276 + @Description Join two lists.
92277 +
92278 + @Param[in] p_NewList - A pointer to the new list to add.
92279 + @Param[in] p_Head - A pointer to the place to add it in the first list.
92280 +
92281 + @Return none.
92282 +*//***************************************************************************/
92283 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
92284 +
92285 +
92286 +/**************************************************************************//**
92287 + @Function LIST_NumOfObjs
92288 +
92289 + @Description Counts number of objects in the list
92290 +
92291 + @Param[in] p_List - A pointer to the list which objects are to be counted.
92292 +
92293 + @Return Number of objects in the list.
92294 +*//***************************************************************************/
92295 +int LIST_NumOfObjs(t_List *p_List);
92296 +
92297 +/** @} */ /* end of list_id group */
92298 +/** @} */ /* end of etc_id group */
92299 +
92300 +
92301 +#endif /* __LIST_EXT_H */
92302 --- /dev/null
92303 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
92304 @@ -0,0 +1,318 @@
92305 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92306 + * All rights reserved.
92307 + *
92308 + * Redistribution and use in source and binary forms, with or without
92309 + * modification, are permitted provided that the following conditions are met:
92310 + * * Redistributions of source code must retain the above copyright
92311 + * notice, this list of conditions and the following disclaimer.
92312 + * * Redistributions in binary form must reproduce the above copyright
92313 + * notice, this list of conditions and the following disclaimer in the
92314 + * documentation and/or other materials provided with the distribution.
92315 + * * Neither the name of Freescale Semiconductor nor the
92316 + * names of its contributors may be used to endorse or promote products
92317 + * derived from this software without specific prior written permission.
92318 + *
92319 + *
92320 + * ALTERNATIVELY, this software may be distributed under the terms of the
92321 + * GNU General Public License ("GPL") as published by the Free Software
92322 + * Foundation, either version 2 of that License or (at your option) any
92323 + * later version.
92324 + *
92325 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92326 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92327 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92328 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92329 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92330 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92331 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92332 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92333 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92334 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92335 + */
92336 +
92337 +
92338 +/**************************************************************************//**
92339 +
92340 + @File mem_ext.h
92341 +
92342 + @Description External prototypes for the memory manager object
92343 +*//***************************************************************************/
92344 +
92345 +#ifndef __MEM_EXT_H
92346 +#define __MEM_EXT_H
92347 +
92348 +#include "std_ext.h"
92349 +#include "part_ext.h"
92350 +
92351 +
92352 +/**************************************************************************//**
92353 + @Group etc_id Utility Library Application Programming Interface
92354 +
92355 + @Description External routines.
92356 +
92357 + @{
92358 +*//***************************************************************************/
92359 +
92360 +/**************************************************************************//**
92361 + @Group mem_id Slab Memory Manager
92362 +
92363 + @Description Slab Memory Manager module functions, definitions and enums.
92364 +
92365 + @{
92366 +*//***************************************************************************/
92367 +
92368 +/* Each block is of the following structure:
92369 + *
92370 + *
92371 + * +-----------+----------+---------------------------+-----------+-----------+
92372 + * | Alignment | Prefix | Data | Postfix | Alignment |
92373 + * | field | field | field | field | Padding |
92374 + * | | | | | |
92375 + * +-----------+----------+---------------------------+-----------+-----------+
92376 + * and at the beginning of all bytes, an additional optional padding might reside
92377 + * to ensure that the first blocks data field is aligned as requested.
92378 + */
92379 +
92380 +
92381 +#define MEM_MAX_NAME_LENGTH 8
92382 +
92383 +/**************************************************************************//*
92384 + @Description Memory Segment structure
92385 +*//***************************************************************************/
92386 +
92387 +typedef struct
92388 +{
92389 + char name[MEM_MAX_NAME_LENGTH];
92390 + /* The segment's name */
92391 + uint8_t **p_Bases; /* Base addresses of the segments */
92392 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
92393 + t_Handle h_Spinlock;
92394 + uint16_t dataSize; /* Size of each data block */
92395 + uint16_t prefixSize; /* How many bytes to reserve before the data */
92396 + uint16_t postfixSize; /* How many bytes to reserve after the data */
92397 + uint16_t alignment; /* Requested alignment for the data field */
92398 + int allocOwner; /* Memory allocation owner */
92399 + uint32_t getFailures; /* Number of times get failed */
92400 + uint32_t num; /* Number of blocks in segment */
92401 + uint32_t current; /* Current block */
92402 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
92403 +#ifdef DEBUG_MEM_LEAKS
92404 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
92405 + uint32_t blockOffset;
92406 + uint32_t blockSize;
92407 +#endif /* DEBUG_MEM_LEAKS */
92408 +} t_MemorySegment;
92409 +
92410 +
92411 +
92412 +/**************************************************************************//**
92413 + @Function MEM_Init
92414 +
92415 + @Description Create a new memory segment.
92416 +
92417 + @Param[in] name - Name of memory partition.
92418 + @Param[in] p_Handle - Handle to new segment is returned through here.
92419 + @Param[in] num - Number of blocks in new segment.
92420 + @Param[in] dataSize - Size of blocks in segment.
92421 + @Param[in] prefixSize - How many bytes to allocate before the data.
92422 + @Param[in] postfixSize - How many bytes to allocate after the data.
92423 + @Param[in] alignment - Requested alignment for data field (in bytes).
92424 +
92425 + @Return E_OK - success, E_NO_MEMORY - out of memory.
92426 +*//***************************************************************************/
92427 +t_Error MEM_Init(char name[],
92428 + t_Handle *p_Handle,
92429 + uint32_t num,
92430 + uint16_t dataSize,
92431 + uint16_t prefixSize,
92432 + uint16_t postfixSize,
92433 + uint16_t alignment);
92434 +
92435 +/**************************************************************************//**
92436 + @Function MEM_InitSmart
92437 +
92438 + @Description Create a new memory segment.
92439 +
92440 + @Param[in] name - Name of memory partition.
92441 + @Param[in] p_Handle - Handle to new segment is returned through here.
92442 + @Param[in] num - Number of blocks in new segment.
92443 + @Param[in] dataSize - Size of blocks in segment.
92444 + @Param[in] prefixSize - How many bytes to allocate before the data.
92445 + @Param[in] postfixSize - How many bytes to allocate after the data.
92446 + @Param[in] alignment - Requested alignment for data field (in bytes).
92447 + @Param[in] memPartitionId - Memory partition ID for allocation.
92448 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
92449 + continuously or not.
92450 +
92451 + @Return E_OK - success, E_NO_MEMORY - out of memory.
92452 +*//***************************************************************************/
92453 +t_Error MEM_InitSmart(char name[],
92454 + t_Handle *p_Handle,
92455 + uint32_t num,
92456 + uint16_t dataSize,
92457 + uint16_t prefixSize,
92458 + uint16_t postfixSize,
92459 + uint16_t alignment,
92460 + uint8_t memPartitionId,
92461 + bool consecutiveMem);
92462 +
92463 +/**************************************************************************//**
92464 + @Function MEM_InitByAddress
92465 +
92466 + @Description Create a new memory segment with a specified base address.
92467 +
92468 + @Param[in] name - Name of memory partition.
92469 + @Param[in] p_Handle - Handle to new segment is returned through here.
92470 + @Param[in] num - Number of blocks in new segment.
92471 + @Param[in] dataSize - Size of blocks in segment.
92472 + @Param[in] prefixSize - How many bytes to allocate before the data.
92473 + @Param[in] postfixSize - How many bytes to allocate after the data.
92474 + @Param[in] alignment - Requested alignment for data field (in bytes).
92475 + @Param[in] address - The required base address.
92476 +
92477 + @Return E_OK - success, E_NO_MEMORY - out of memory.
92478 + *//***************************************************************************/
92479 +t_Error MEM_InitByAddress(char name[],
92480 + t_Handle *p_Handle,
92481 + uint32_t num,
92482 + uint16_t dataSize,
92483 + uint16_t prefixSize,
92484 + uint16_t postfixSize,
92485 + uint16_t alignment,
92486 + uint8_t *address);
92487 +
92488 +/**************************************************************************//**
92489 + @Function MEM_Free
92490 +
92491 + @Description Free a specific memory segment.
92492 +
92493 + @Param[in] h_Mem - Handle to memory segment.
92494 +
92495 + @Return None.
92496 +*//***************************************************************************/
92497 +void MEM_Free(t_Handle h_Mem);
92498 +
92499 +/**************************************************************************//**
92500 + @Function MEM_Get
92501 +
92502 + @Description Get a block of memory from a segment.
92503 +
92504 + @Param[in] h_Mem - Handle to memory segment.
92505 +
92506 + @Return Pointer to new memory block on success,0 otherwise.
92507 +*//***************************************************************************/
92508 +void * MEM_Get(t_Handle h_Mem);
92509 +
92510 +/**************************************************************************//**
92511 + @Function MEM_GetN
92512 +
92513 + @Description Get up to N blocks of memory from a segment.
92514 +
92515 + The blocks are assumed to be of a fixed size (one size per segment).
92516 +
92517 + @Param[in] h_Mem - Handle to memory segment.
92518 + @Param[in] num - Number of blocks to allocate.
92519 + @Param[out] array - Array of at least num pointers to which the addresses
92520 + of the allocated blocks are written.
92521 +
92522 + @Return The number of blocks actually allocated.
92523 +
92524 + @Cautions Interrupts are disabled for all of the allocation loop.
92525 + Although this loop is very short for each block (several machine
92526 + instructions), you should not allocate a very large number
92527 + of blocks via this routine.
92528 +*//***************************************************************************/
92529 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
92530 +
92531 +/**************************************************************************//**
92532 + @Function MEM_Put
92533 +
92534 + @Description Put a block of memory back to a segment.
92535 +
92536 + @Param[in] h_Mem - Handle to memory segment.
92537 + @Param[in] p_Block - The block to return.
92538 +
92539 + @Return Pointer to new memory block on success,0 otherwise.
92540 +*//***************************************************************************/
92541 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
92542 +
92543 +/**************************************************************************//**
92544 + @Function MEM_ComputePartitionSize
92545 +
92546 + @Description calculate a tight upper boundary of the size of a partition with
92547 + given attributes.
92548 +
92549 + The returned value is suitable if one wants to use MEM_InitByAddress().
92550 +
92551 + @Param[in] num - The number of blocks in the segment.
92552 + @Param[in] dataSize - Size of block to get.
92553 + @Param[in] prefixSize - The prefix size
92554 + @Param postfixSize - The postfix size
92555 + @Param[in] alignment - The requested alignment value (in bytes)
92556 +
92557 + @Return The memory block size a segment with the given attributes needs.
92558 +*//***************************************************************************/
92559 +uint32_t MEM_ComputePartitionSize(uint32_t num,
92560 + uint16_t dataSize,
92561 + uint16_t prefixSize,
92562 + uint16_t postfixSize,
92563 + uint16_t alignment);
92564 +
92565 +#ifdef DEBUG_MEM_LEAKS
92566 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
92567 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
92568 +#endif /* !(defined(__MWERKS__) && ... */
92569 +
92570 +/**************************************************************************//**
92571 + @Function MEM_CheckLeaks
92572 +
92573 + @Description Report MEM object leaks.
92574 +
92575 + This routine is automatically called by the MEM_Free() routine,
92576 + but it can also be invoked while the MEM object is alive.
92577 +
92578 + @Param[in] h_Mem - Handle to memory segment.
92579 +
92580 + @Return None.
92581 +*//***************************************************************************/
92582 +void MEM_CheckLeaks(t_Handle h_Mem);
92583 +
92584 +#else /* not DEBUG_MEM_LEAKS */
92585 +#define MEM_CheckLeaks(h_Mem)
92586 +#endif /* not DEBUG_MEM_LEAKS */
92587 +
92588 +/**************************************************************************//**
92589 + @Description Get base of MEM
92590 +*//***************************************************************************/
92591 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
92592 +
92593 +/**************************************************************************//**
92594 + @Description Get size of MEM block
92595 +*//***************************************************************************/
92596 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
92597 +
92598 +/**************************************************************************//**
92599 + @Description Get prefix size of MEM block
92600 +*//***************************************************************************/
92601 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
92602 +
92603 +/**************************************************************************//**
92604 + @Description Get postfix size of MEM block
92605 +*//***************************************************************************/
92606 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
92607 +
92608 +/**************************************************************************//**
92609 + @Description Get alignment of MEM block (in bytes)
92610 +*//***************************************************************************/
92611 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
92612 +
92613 +/**************************************************************************//**
92614 + @Description Get the number of blocks in the segment
92615 +*//***************************************************************************/
92616 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
92617 +
92618 +/** @} */ /* end of MEM group */
92619 +/** @} */ /* end of etc_id group */
92620 +
92621 +
92622 +#endif /* __MEM_EXT_H */
92623 --- /dev/null
92624 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
92625 @@ -0,0 +1,208 @@
92626 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92627 + * All rights reserved.
92628 + *
92629 + * Redistribution and use in source and binary forms, with or without
92630 + * modification, are permitted provided that the following conditions are met:
92631 + * * Redistributions of source code must retain the above copyright
92632 + * notice, this list of conditions and the following disclaimer.
92633 + * * Redistributions in binary form must reproduce the above copyright
92634 + * notice, this list of conditions and the following disclaimer in the
92635 + * documentation and/or other materials provided with the distribution.
92636 + * * Neither the name of Freescale Semiconductor nor the
92637 + * names of its contributors may be used to endorse or promote products
92638 + * derived from this software without specific prior written permission.
92639 + *
92640 + *
92641 + * ALTERNATIVELY, this software may be distributed under the terms of the
92642 + * GNU General Public License ("GPL") as published by the Free Software
92643 + * Foundation, either version 2 of that License or (at your option) any
92644 + * later version.
92645 + *
92646 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92647 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92648 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92649 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92650 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92651 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92652 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92653 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92654 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92655 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92656 + */
92657 +
92658 +
92659 +/**************************************************************************//**
92660 +
92661 + @File memcpy_ext.h
92662 +
92663 + @Description Efficient functions for copying and setting blocks of memory.
92664 +*//***************************************************************************/
92665 +
92666 +#ifndef __MEMCPY_EXT_H
92667 +#define __MEMCPY_EXT_H
92668 +
92669 +#include "std_ext.h"
92670 +
92671 +
92672 +/**************************************************************************//**
92673 + @Group etc_id Utility Library Application Programming Interface
92674 +
92675 + @Description External routines.
92676 +
92677 + @{
92678 +*//***************************************************************************/
92679 +
92680 +/**************************************************************************//**
92681 + @Group mem_cpy Memory Copy
92682 +
92683 + @Description Memory Copy module functions,definitions and enums.
92684 +
92685 + @{
92686 +*//***************************************************************************/
92687 +
92688 +/**************************************************************************//**
92689 + @Function MemCpy32
92690 +
92691 + @Description Copies one memory buffer into another one in 4-byte chunks!
92692 + Which should be more efficient than byte by byte.
92693 +
92694 + For large buffers (over 60 bytes) this function is about 4 times
92695 + more efficient than the trivial memory copy. For short buffers
92696 + it is reduced to the trivial copy and may be a bit worse.
92697 +
92698 + @Param[in] pDst - The address of the destination buffer.
92699 + @Param[in] pSrc - The address of the source buffer.
92700 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
92701 +
92702 + @Return pDst (the address of the destination buffer).
92703 +
92704 + @Cautions There is no parameter or boundary checking! It is up to the user
92705 + to supply non-null parameters as source & destination and size
92706 + that actually fits into the destination buffer.
92707 +*//***************************************************************************/
92708 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
92709 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
92710 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
92711 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
92712 +
92713 +/**************************************************************************//**
92714 + @Function MemCpy64
92715 +
92716 + @Description Copies one memory buffer into another one in 8-byte chunks!
92717 + Which should be more efficient than byte by byte.
92718 +
92719 + For large buffers (over 60 bytes) this function is about 8 times
92720 + more efficient than the trivial memory copy. For short buffers
92721 + it is reduced to the trivial copy and may be a bit worse.
92722 +
92723 + Some testing suggests that MemCpy32() preforms better than
92724 + MemCpy64() over small buffers. On average they break even at
92725 + 100 byte buffers. For buffers larger than that MemCpy64 is
92726 + superior.
92727 +
92728 + @Param[in] pDst - The address of the destination buffer.
92729 + @Param[in] pSrc - The address of the source buffer.
92730 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
92731 +
92732 + @Return pDst (the address of the destination buffer).
92733 +
92734 + @Cautions There is no parameter or boundary checking! It is up to the user
92735 + to supply non null parameters as source & destination and size
92736 + that actually fits into their buffer.
92737 +
92738 + Do not use under Linux.
92739 +*//***************************************************************************/
92740 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
92741 +
92742 +/**************************************************************************//**
92743 + @Function MemSet32
92744 +
92745 + @Description Sets all bytes of a memory buffer to a specific value, in
92746 + 4-byte chunks.
92747 +
92748 + @Param[in] pDst - The address of the destination buffer.
92749 + @Param[in] val - Value to set destination bytes to.
92750 + @Param[in] size - The number of bytes that will be set to val.
92751 +
92752 + @Return pDst (the address of the destination buffer).
92753 +
92754 + @Cautions There is no parameter or boundary checking! It is up to the user
92755 + to supply non null parameter as destination and size
92756 + that actually fits into the destination buffer.
92757 +*//***************************************************************************/
92758 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
92759 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
92760 +
92761 +/**************************************************************************//**
92762 + @Function MemSet64
92763 +
92764 + @Description Sets all bytes of a memory buffer to a specific value, in
92765 + 8-byte chunks.
92766 +
92767 + @Param[in] pDst - The address of the destination buffer.
92768 + @Param[in] val - Value to set destination bytes to.
92769 + @Param[in] size - The number of bytes that will be set to val.
92770 +
92771 + @Return pDst (the address of the destination buffer).
92772 +
92773 + @Cautions There is no parameter or boundary checking! It is up to the user
92774 + to supply non null parameter as destination and size
92775 + that actually fits into the destination buffer.
92776 +*//***************************************************************************/
92777 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
92778 +
92779 +/**************************************************************************//**
92780 + @Function MemDisp
92781 +
92782 + @Description Displays a block of memory in chunks of 32 bits.
92783 +
92784 + @Param[in] addr - The address of the memory to display.
92785 + @Param[in] size - The number of bytes that will be displayed.
92786 +
92787 + @Return None.
92788 +
92789 + @Cautions There is no parameter or boundary checking! It is up to the user
92790 + to supply non null parameter as destination and size
92791 + that actually fits into the destination buffer.
92792 +*//***************************************************************************/
92793 +void MemDisp(uint8_t *addr, int size);
92794 +
92795 +/**************************************************************************//**
92796 + @Function MemCpy8
92797 +
92798 + @Description Trivial copy one memory buffer into another byte by byte
92799 +
92800 + @Param[in] pDst - The address of the destination buffer.
92801 + @Param[in] pSrc - The address of the source buffer.
92802 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
92803 +
92804 + @Return pDst (the address of the destination buffer).
92805 +
92806 + @Cautions There is no parameter or boundary checking! It is up to the user
92807 + to supply non-null parameters as source & destination and size
92808 + that actually fits into the destination buffer.
92809 +*//***************************************************************************/
92810 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
92811 +
92812 +/**************************************************************************//**
92813 + @Function MemSet8
92814 +
92815 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
92816 +
92817 + @Param[in] pDst - The address of the destination buffer.
92818 + @Param[in] c - Value to set destination bytes to.
92819 + @Param[in] size - The number of bytes that will be set to val.
92820 +
92821 + @Return pDst (the address of the destination buffer).
92822 +
92823 + @Cautions There is no parameter or boundary checking! It is up to the user
92824 + to supply non null parameter as destination and size
92825 + that actually fits into the destination buffer.
92826 +*//***************************************************************************/
92827 +void * MemSet8(void* pDst, int c, uint32_t size);
92828 +
92829 +/** @} */ /* end of mem_cpy group */
92830 +/** @} */ /* end of etc_id group */
92831 +
92832 +
92833 +#endif /* __MEMCPY_EXT_H */
92834 --- /dev/null
92835 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
92836 @@ -0,0 +1,310 @@
92837 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92838 + * All rights reserved.
92839 + *
92840 + * Redistribution and use in source and binary forms, with or without
92841 + * modification, are permitted provided that the following conditions are met:
92842 + * * Redistributions of source code must retain the above copyright
92843 + * notice, this list of conditions and the following disclaimer.
92844 + * * Redistributions in binary form must reproduce the above copyright
92845 + * notice, this list of conditions and the following disclaimer in the
92846 + * documentation and/or other materials provided with the distribution.
92847 + * * Neither the name of Freescale Semiconductor nor the
92848 + * names of its contributors may be used to endorse or promote products
92849 + * derived from this software without specific prior written permission.
92850 + *
92851 + *
92852 + * ALTERNATIVELY, this software may be distributed under the terms of the
92853 + * GNU General Public License ("GPL") as published by the Free Software
92854 + * Foundation, either version 2 of that License or (at your option) any
92855 + * later version.
92856 + *
92857 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92858 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92859 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92860 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92861 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92862 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92863 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92864 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92865 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92866 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92867 + */
92868 +
92869 +
92870 +/**************************************************************************//**
92871 + @File mm_ext.h
92872 +
92873 + @Description Memory Manager Application Programming Interface
92874 +*//***************************************************************************/
92875 +#ifndef __MM_EXT
92876 +#define __MM_EXT
92877 +
92878 +#include "std_ext.h"
92879 +
92880 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
92881 + where maximum alignment defined as
92882 + MM_MAX_ALIGNMENT power of 2 */
92883 +
92884 +#define MM_MAX_NAME_LEN 32
92885 +
92886 +/**************************************************************************//**
92887 + @Group etc_id Utility Library Application Programming Interface
92888 +
92889 + @Description External routines.
92890 +
92891 + @{
92892 +*//***************************************************************************/
92893 +
92894 +/**************************************************************************//**
92895 + @Group mm_grp Flexible Memory Manager
92896 +
92897 + @Description Flexible Memory Manager module functions,definitions and enums.
92898 + (All of the following functions,definitions and enums can be found in mm_ext.h)
92899 +
92900 + @{
92901 +*//***************************************************************************/
92902 +
92903 +
92904 +/**************************************************************************//**
92905 + @Function MM_Init
92906 +
92907 + @Description Initializes a new MM object.
92908 +
92909 + It initializes a new memory block consisting of base address
92910 + and size of the available memory by calling to MemBlock_Init
92911 + routine. It is also initializes a new free block for each
92912 + by calling FreeBlock_Init routine, which is pointed to
92913 + the almost all memory started from the required alignment
92914 + from the base address and to the end of the memory.
92915 + The handle to the new MM object is returned via "MM"
92916 + argument (passed by reference).
92917 +
92918 + @Param[in] h_MM - Handle to the MM object.
92919 + @Param[in] base - Base address of the MM.
92920 + @Param[in] size - Size of the MM.
92921 +
92922 + @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.
92923 +*//***************************************************************************/
92924 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
92925 +
92926 +/**************************************************************************//**
92927 + @Function MM_Get
92928 +
92929 + @Description Allocates a block of memory according to the given size and the alignment.
92930 +
92931 + The Alignment argument tells from which
92932 + free list allocate a block of memory. 2^alignment indicates
92933 + the alignment that the base address of the allocated block
92934 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
92935 + are available for the alignment argument.
92936 + The routine passes through the specific free list of free
92937 + blocks and seeks for a first block that have anough memory
92938 + that is required (best fit).
92939 + After the block is found and data is allocated, it calls
92940 + the internal MM_CutFree routine to update all free lists
92941 + do not include a just allocated block. Of course, each
92942 + free list contains a free blocks with the same alignment.
92943 + It is also creates a busy block that holds
92944 + information about an allocated block.
92945 +
92946 + @Param[in] h_MM - Handle to the MM object.
92947 + @Param[in] size - Size of the MM.
92948 + @Param[in] alignment - Index as a power of two defines a required
92949 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
92950 + @Param[in] name - The name that specifies an allocated block.
92951 +
92952 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
92953 +*//***************************************************************************/
92954 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
92955 +
92956 +/**************************************************************************//**
92957 + @Function MM_GetBase
92958 +
92959 + @Description Gets the base address of the required MM objects.
92960 +
92961 + @Param[in] h_MM - Handle to the MM object.
92962 +
92963 + @Return base address of the block.
92964 +*//***************************************************************************/
92965 +uint64_t MM_GetBase(t_Handle h_MM);
92966 +
92967 +/**************************************************************************//**
92968 + @Function MM_GetForce
92969 +
92970 + @Description Force memory allocation.
92971 +
92972 + It means to allocate a block of memory of the given
92973 + size from the given base address.
92974 + The routine checks if the required block can be allocated
92975 + (that is it is free) and then, calls the internal MM_CutFree
92976 + routine to update all free lists do not include that block.
92977 +
92978 + @Param[in] h_MM - Handle to the MM object.
92979 + @Param[in] base - Base address of the MM.
92980 + @Param[in] size - Size of the MM.
92981 + @Param[in] name - Name that specifies an allocated block.
92982 +
92983 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
92984 +*//***************************************************************************/
92985 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
92986 +
92987 +/**************************************************************************//**
92988 + @Function MM_GetForceMin
92989 +
92990 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
92991 +
92992 + The Alignment argument tells from which
92993 + free list allocate a block of memory. 2^alignment indicates
92994 + the alignment that the base address of the allocated block
92995 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
92996 + are available for the alignment argument.
92997 + The minimum baser address forces the location of the block
92998 + to be from a given address onward.
92999 + The routine passes through the specific free list of free
93000 + blocks and seeks for the first base address equal or smaller
93001 + than the required minimum address and end address larger than
93002 + than the required base + its size - i.e. that may contain
93003 + the required block.
93004 + After the block is found and data is allocated, it calls
93005 + the internal MM_CutFree routine to update all free lists
93006 + do not include a just allocated block. Of course, each
93007 + free list contains a free blocks with the same alignment.
93008 + It is also creates a busy block that holds
93009 + information about an allocated block.
93010 +
93011 + @Param[in] h_MM - Handle to the MM object.
93012 + @Param[in] size - Size of the MM.
93013 + @Param[in] alignment - Index as a power of two defines a required
93014 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
93015 + @Param[in] min - The minimum base address of the block.
93016 + @Param[in] name - Name that specifies an allocated block.
93017 +
93018 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
93019 +*//***************************************************************************/
93020 +uint64_t MM_GetForceMin(t_Handle h_MM,
93021 + uint64_t size,
93022 + uint64_t alignment,
93023 + uint64_t min,
93024 + char *name);
93025 +
93026 +/**************************************************************************//**
93027 + @Function MM_Put
93028 +
93029 + @Description Puts a block of memory of the given base address back to the memory.
93030 +
93031 + It checks if there is a busy block with the
93032 + given base address. If not, it returns 0, that
93033 + means can't free a block. Otherwise, it gets parameters of
93034 + the busy block and after it updates lists of free blocks,
93035 + removes that busy block from the list by calling to MM_CutBusy
93036 + routine.
93037 + After that it calls to MM_AddFree routine to add a new free
93038 + block to the free lists.
93039 +
93040 + @Param[in] h_MM - Handle to the MM object.
93041 + @Param[in] base - Base address of the MM.
93042 +
93043 + @Return The size of bytes released, 0 if failed.
93044 +*//***************************************************************************/
93045 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
93046 +
93047 +/**************************************************************************//**
93048 + @Function MM_PutForce
93049 +
93050 + @Description Releases a block of memory of the required size from the required base address.
93051 +
93052 + First, it calls to MM_CutBusy routine
93053 + to cut a free block from the busy list. And then, calls to
93054 + MM_AddFree routine to add the free block to the free lists.
93055 +
93056 + @Param[in] h_MM - Handle to the MM object.
93057 + @Param[in] base - Base address of of a block to free.
93058 + @Param[in] size - Size of a block to free.
93059 +
93060 + @Return The number of bytes released, 0 on failure.
93061 +*//***************************************************************************/
93062 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
93063 +
93064 +/**************************************************************************//**
93065 + @Function MM_Add
93066 +
93067 + @Description Adds a new memory block for memory allocation.
93068 +
93069 + When a new memory block is initialized and added to the
93070 + memory list, it calls to MM_AddFree routine to add the
93071 + new free block to the free lists.
93072 +
93073 + @Param[in] h_MM - Handle to the MM object.
93074 + @Param[in] base - Base address of the memory block.
93075 + @Param[in] size - Size of the memory block.
93076 +
93077 + @Return E_OK on success, otherwise returns an error code.
93078 +*//***************************************************************************/
93079 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
93080 +
93081 +/**************************************************************************//**
93082 + @Function MM_Dump
93083 +
93084 + @Description Prints results of free and busy lists.
93085 +
93086 + @Param[in] h_MM - Handle to the MM object.
93087 +*//***************************************************************************/
93088 +void MM_Dump(t_Handle h_MM);
93089 +
93090 +/**************************************************************************//**
93091 + @Function MM_Free
93092 +
93093 + @Description Releases memory allocated for MM object.
93094 +
93095 + @Param[in] h_MM - Handle of the MM object.
93096 +*//***************************************************************************/
93097 +void MM_Free(t_Handle h_MM);
93098 +
93099 +/**************************************************************************//**
93100 + @Function MM_GetMemBlock
93101 +
93102 + @Description Returns base address of the memory block specified by the index.
93103 +
93104 + If index is 0, returns base address
93105 + of the first memory block, 1 - returns base address
93106 + of the second memory block, etc.
93107 + Note, those memory blocks are allocated by the
93108 + application before MM_Init or MM_Add and have to
93109 + be released by the application before or after invoking
93110 + the MM_Free routine.
93111 +
93112 + @Param[in] h_MM - Handle to the MM object.
93113 + @Param[in] index - Index of the memory block.
93114 +
93115 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
93116 +*//***************************************************************************/
93117 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
93118 +
93119 +/**************************************************************************//**
93120 + @Function MM_InRange
93121 +
93122 + @Description Checks if a specific address is in the memory range of the passed MM object.
93123 +
93124 + @Param[in] h_MM - Handle to the MM object.
93125 + @Param[in] addr - The address to be checked.
93126 +
93127 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
93128 +*//***************************************************************************/
93129 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
93130 +
93131 +/**************************************************************************//**
93132 + @Function MM_GetFreeMemSize
93133 +
93134 + @Description Returns the size (in bytes) of free memory.
93135 +
93136 + @Param[in] h_MM - Handle to the MM object.
93137 +
93138 + @Return Free memory size in bytes.
93139 +*//***************************************************************************/
93140 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
93141 +
93142 +
93143 +/** @} */ /* end of mm_grp group */
93144 +/** @} */ /* end of etc_id group */
93145 +
93146 +#endif /* __MM_EXT_H */
93147 --- /dev/null
93148 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
93149 @@ -0,0 +1,118 @@
93150 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
93151 + * All rights reserved.
93152 + *
93153 + * Redistribution and use in source and binary forms, with or without
93154 + * modification, are permitted provided that the following conditions are met:
93155 + * * Redistributions of source code must retain the above copyright
93156 + * notice, this list of conditions and the following disclaimer.
93157 + * * Redistributions in binary form must reproduce the above copyright
93158 + * notice, this list of conditions and the following disclaimer in the
93159 + * documentation and/or other materials provided with the distribution.
93160 + * * Neither the name of Freescale Semiconductor nor the
93161 + * names of its contributors may be used to endorse or promote products
93162 + * derived from this software without specific prior written permission.
93163 + *
93164 + *
93165 + * ALTERNATIVELY, this software may be distributed under the terms of the
93166 + * GNU General Public License ("GPL") as published by the Free Software
93167 + * Foundation, either version 2 of that License or (at your option) any
93168 + * later version.
93169 + *
93170 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93171 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93172 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93173 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93174 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93175 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93176 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93177 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93178 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93179 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93180 + */
93181 +
93182 +
93183 +/**************************************************************************//**
93184 + @File sprint_ext.h
93185 +
93186 + @Description Debug routines (externals).
93187 +
93188 +*//***************************************************************************/
93189 +
93190 +#ifndef __SPRINT_EXT_H
93191 +#define __SPRINT_EXT_H
93192 +
93193 +
93194 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
93195 +#include <linux/kernel.h>
93196 +
93197 +#elif defined(NCSW_VXWORKS)
93198 +#include "private/stdioP.h"
93199 +
93200 +#else
93201 +#include <stdio.h>
93202 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
93203 +
93204 +#include "std_ext.h"
93205 +
93206 +
93207 +/**************************************************************************//**
93208 + @Group etc_id Utility Library Application Programming Interface
93209 +
93210 + @Description External routines.
93211 +
93212 + @{
93213 +*//***************************************************************************/
93214 +
93215 +/**************************************************************************//**
93216 + @Group sprint_id Sprint
93217 +
93218 + @Description Sprint & Sscan module functions,definitions and enums.
93219 +
93220 + @{
93221 +*//***************************************************************************/
93222 +
93223 +/**************************************************************************//**
93224 + @Function Sprint
93225 +
93226 + @Description Format a string and place it in a buffer.
93227 +
93228 + @Param[in] buff - The buffer to place the result into.
93229 + @Param[in] str - The format string to use.
93230 + @Param[in] ... - Arguments for the format string.
93231 +
93232 + @Return Number of bytes formatted.
93233 +*//***************************************************************************/
93234 +int Sprint(char *buff, const char *str, ...);
93235 +
93236 +/**************************************************************************//**
93237 + @Function Snprint
93238 +
93239 + @Description Format a string and place it in a buffer.
93240 +
93241 + @Param[in] buf - The buffer to place the result into.
93242 + @Param[in] size - The size of the buffer, including the trailing null space.
93243 + @Param[in] fmt - The format string to use.
93244 + @Param[in] ... - Arguments for the format string.
93245 +
93246 + @Return Number of bytes formatted.
93247 +*//***************************************************************************/
93248 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
93249 +
93250 +/**************************************************************************//**
93251 + @Function Sscan
93252 +
93253 + @Description Unformat a buffer into a list of arguments.
93254 +
93255 + @Param[in] buf - input buffer.
93256 + @Param[in] fmt - formatting of buffer.
93257 + @Param[out] ... - resulting arguments.
93258 +
93259 + @Return Number of bytes unformatted.
93260 +*//***************************************************************************/
93261 +int Sscan(const char * buf, const char * fmt, ...);
93262 +
93263 +/** @} */ /* end of sprint_id group */
93264 +/** @} */ /* end of etc_id group */
93265 +
93266 +
93267 +#endif /* __SPRINT_EXT_H */
93268 --- /dev/null
93269 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
93270 @@ -0,0 +1,37 @@
93271 +/*
93272 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93273 + *
93274 + * Redistribution and use in source and binary forms, with or without
93275 + * modification, are permitted provided that the following conditions are met:
93276 + * * Redistributions of source code must retain the above copyright
93277 + * notice, this list of conditions and the following disclaimer.
93278 + * * Redistributions in binary form must reproduce the above copyright
93279 + * notice, this list of conditions and the following disclaimer in the
93280 + * documentation and/or other materials provided with the distribution.
93281 + * * Neither the name of Freescale Semiconductor nor the
93282 + * names of its contributors may be used to endorse or promote products
93283 + * derived from this software without specific prior written permission.
93284 + *
93285 + *
93286 + * ALTERNATIVELY, this software may be distributed under the terms of the
93287 + * GNU General Public License ("GPL") as published by the Free Software
93288 + * Foundation, either version 2 of that License or (at your option) any
93289 + * later version.
93290 + *
93291 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93292 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93293 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93294 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93295 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93296 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93297 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93298 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93299 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93300 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93301 + */
93302 +
93303 +#ifndef FL_E500_MACROS_H
93304 +#define FL_E500_MACROS_H
93305 +
93306 +#endif /* FL_E500_MACROS_H */
93307 +
93308 --- /dev/null
93309 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
93310 @@ -0,0 +1,52 @@
93311 +/*
93312 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93313 + *
93314 + * Redistribution and use in source and binary forms, with or without
93315 + * modification, are permitted provided that the following conditions are met:
93316 + * * Redistributions of source code must retain the above copyright
93317 + * notice, this list of conditions and the following disclaimer.
93318 + * * Redistributions in binary form must reproduce the above copyright
93319 + * notice, this list of conditions and the following disclaimer in the
93320 + * documentation and/or other materials provided with the distribution.
93321 + * * Neither the name of Freescale Semiconductor nor the
93322 + * names of its contributors may be used to endorse or promote products
93323 + * derived from this software without specific prior written permission.
93324 + *
93325 + *
93326 + * ALTERNATIVELY, this software may be distributed under the terms of the
93327 + * GNU General Public License ("GPL") as published by the Free Software
93328 + * Foundation, either version 2 of that License or (at your option) any
93329 + * later version.
93330 + *
93331 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93332 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93333 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93334 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93335 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93336 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93337 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93338 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93339 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93340 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93341 + */
93342 +
93343 +#ifndef __GENERAL_H
93344 +#define __GENERAL_H
93345 +
93346 +#include "std_ext.h"
93347 +#if !defined(NCSW_LINUX)
93348 +#include "errno.h"
93349 +#endif
93350 +
93351 +
93352 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
93353 +
93354 +#ifndef CONFIG_FMAN_ARM
93355 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
93356 +#define ioread32be(addr) GET_UINT32(*addr)
93357 +#endif
93358 +
93359 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
93360 +
93361 +
93362 +#endif /* __GENERAL_H */
93363 --- /dev/null
93364 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
93365 @@ -0,0 +1,78 @@
93366 +/*
93367 + * Copyright 2008-2013 Freescale Semiconductor Inc.
93368 + *
93369 + * Redistribution and use in source and binary forms, with or without
93370 + * modification, are permitted provided that the following conditions are met:
93371 + * * Redistributions of source code must retain the above copyright
93372 + * notice, this list of conditions and the following disclaimer.
93373 + * * Redistributions in binary form must reproduce the above copyright
93374 + * notice, this list of conditions and the following disclaimer in the
93375 + * documentation and/or other materials provided with the distribution.
93376 + * * Neither the name of Freescale Semiconductor nor the
93377 + * names of its contributors may be used to endorse or promote products
93378 + * derived from this software without specific prior written permission.
93379 + *
93380 + *
93381 + * ALTERNATIVELY, this software may be distributed under the terms of the
93382 + * GNU General Public License ("GPL") as published by the Free Software
93383 + * Foundation, either version 2 of that License or (at your option) any
93384 + * later version.
93385 + *
93386 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93387 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93388 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93389 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93390 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93391 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93392 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93393 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93394 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93395 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93396 + */
93397 +
93398 +
93399 +#ifndef __FMAN_COMMON_H
93400 +#define __FMAN_COMMON_H
93401 +
93402 +/**************************************************************************//**
93403 + @Description NIA Description
93404 +*//***************************************************************************/
93405 +#define NIA_ORDER_RESTOR 0x00800000
93406 +#define NIA_ENG_FM_CTL 0x00000000
93407 +#define NIA_ENG_PRS 0x00440000
93408 +#define NIA_ENG_KG 0x00480000
93409 +#define NIA_ENG_PLCR 0x004C0000
93410 +#define NIA_ENG_BMI 0x00500000
93411 +#define NIA_ENG_QMI_ENQ 0x00540000
93412 +#define NIA_ENG_QMI_DEQ 0x00580000
93413 +#define NIA_ENG_MASK 0x007C0000
93414 +
93415 +#define NIA_FM_CTL_AC_CC 0x00000006
93416 +#define NIA_FM_CTL_AC_HC 0x0000000C
93417 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
93418 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
93419 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
93420 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
93421 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
93422 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
93423 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
93424 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
93425 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
93426 +
93427 +
93428 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
93429 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
93430 +#define NIA_BMI_AC_RELEASE 0x000000C0
93431 +#define NIA_BMI_AC_DISCARD 0x000000C1
93432 +#define NIA_BMI_AC_TX 0x00000274
93433 +#define NIA_BMI_AC_FETCH 0x00000208
93434 +#define NIA_BMI_AC_MASK 0x000003FF
93435 +
93436 +#define NIA_KG_DIRECT 0x00000100
93437 +#define NIA_KG_CC_EN 0x00000200
93438 +#define NIA_PLCR_ABSOLUTE 0x00008000
93439 +
93440 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
93441 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
93442 +
93443 +#endif /* __FMAN_COMMON_H */
93444 --- /dev/null
93445 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
93446 @@ -0,0 +1,273 @@
93447 +/*
93448 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93449 + *
93450 + * Redistribution and use in source and binary forms, with or without
93451 + * modification, are permitted provided that the following conditions are met:
93452 + * * Redistributions of source code must retain the above copyright
93453 + * notice, this list of conditions and the following disclaimer.
93454 + * * Redistributions in binary form must reproduce the above copyright
93455 + * notice, this list of conditions and the following disclaimer in the
93456 + * documentation and/or other materials provided with the distribution.
93457 + * * Neither the name of Freescale Semiconductor nor the
93458 + * names of its contributors may be used to endorse or promote products
93459 + * derived from this software without specific prior written permission.
93460 + *
93461 + *
93462 + * ALTERNATIVELY, this software may be distributed under the terms of the
93463 + * GNU General Public License ("GPL") as published by the Free Software
93464 + * Foundation, either version 2 of that License or (at your option) any
93465 + * later version.
93466 + *
93467 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93468 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93469 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93470 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93471 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93472 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93473 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93474 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93475 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93476 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93477 + */
93478 +
93479 +#ifndef __FSL_ENET_H
93480 +#define __FSL_ENET_H
93481 +
93482 +/**
93483 + @Description Ethernet MAC-PHY Interface
93484 +*/
93485 +
93486 +enum enet_interface {
93487 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
93488 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
93489 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
93490 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
93491 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
93492 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
93493 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
93494 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
93495 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
93496 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
93497 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
93498 +};
93499 +
93500 +/**
93501 + @Description Ethernet Speed (nominal data rate)
93502 +*/
93503 +enum enet_speed {
93504 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
93505 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
93506 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
93507 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
93508 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
93509 +};
93510 +
93511 +enum mac_type {
93512 + E_MAC_DTSEC,
93513 + E_MAC_TGEC,
93514 + E_MAC_MEMAC
93515 +};
93516 +
93517 +/**************************************************************************//**
93518 + @Description Enum for inter-module interrupts registration
93519 +*//***************************************************************************/
93520 +enum fman_event_modules {
93521 + E_FMAN_MOD_PRS, /**< Parser event */
93522 + E_FMAN_MOD_KG, /**< Keygen event */
93523 + E_FMAN_MOD_PLCR, /**< Policer event */
93524 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
93525 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
93526 + E_FMAN_MOD_TMR, /**< Timer event */
93527 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
93528 + E_FMAN_MOD_MACSEC,
93529 + E_FMAN_MOD_DUMMY_LAST
93530 +};
93531 +
93532 +/**************************************************************************//**
93533 + @Description Enum for interrupts types
93534 +*//***************************************************************************/
93535 +enum fman_intr_type {
93536 + E_FMAN_INTR_TYPE_ERR,
93537 + E_FMAN_INTR_TYPE_NORMAL
93538 +};
93539 +
93540 +/**************************************************************************//**
93541 + @Description enum for defining MAC types
93542 +*//***************************************************************************/
93543 +enum fman_mac_type {
93544 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
93545 + E_FMAN_MAC_1G /**< 1G MAC */
93546 +};
93547 +
93548 +enum fman_mac_exceptions {
93549 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
93550 + /**< 10GEC MDIO scan event interrupt */
93551 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
93552 + /**< 10GEC MDIO command completion interrupt */
93553 + E_FMAN_MAC_EX_10G_REM_FAULT,
93554 + /**< 10GEC, mEMAC Remote fault interrupt */
93555 + E_FMAN_MAC_EX_10G_LOC_FAULT,
93556 + /**< 10GEC, mEMAC Local fault interrupt */
93557 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
93558 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
93559 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
93560 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
93561 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
93562 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
93563 + E_FMAN_MAC_EX_10G_TX_ER,
93564 + /**< 10GEC Transmit frame error interrupt */
93565 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
93566 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
93567 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
93568 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
93569 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
93570 + /**< 10GEC Receive jabber frame interrupt */
93571 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
93572 + /**< 10GEC Receive oversized frame interrupt */
93573 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
93574 + /**< 10GEC Receive runt frame interrupt */
93575 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
93576 + /**< 10GEC Receive fragment frame interrupt */
93577 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
93578 + /**< 10GEC Receive payload length error interrupt */
93579 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
93580 + /**< 10GEC Receive CRC error interrupt */
93581 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
93582 + /**< 10GEC Receive alignment error interrupt */
93583 + E_FMAN_MAC_EX_1G_BAB_RX,
93584 + /**< dTSEC Babbling receive error */
93585 + E_FMAN_MAC_EX_1G_RX_CTL,
93586 + /**< dTSEC Receive control (pause frame) interrupt */
93587 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
93588 + /**< dTSEC Graceful transmit stop complete */
93589 + E_FMAN_MAC_EX_1G_BAB_TX,
93590 + /**< dTSEC Babbling transmit error */
93591 + E_FMAN_MAC_EX_1G_TX_CTL,
93592 + /**< dTSEC Transmit control (pause frame) interrupt */
93593 + E_FMAN_MAC_EX_1G_TX_ERR,
93594 + /**< dTSEC Transmit error */
93595 + E_FMAN_MAC_EX_1G_LATE_COL,
93596 + /**< dTSEC Late collision */
93597 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
93598 + /**< dTSEC Collision retry limit */
93599 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
93600 + /**< dTSEC Transmit FIFO underrun */
93601 + E_FMAN_MAC_EX_1G_MAG_PCKT,
93602 + /**< dTSEC Magic Packet detection */
93603 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
93604 + /**< dTSEC MII management read completion */
93605 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
93606 + /**< dTSEC MII management write completion */
93607 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
93608 + /**< dTSEC Graceful receive stop complete */
93609 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
93610 + /**< dTSEC Internal data error on transmit */
93611 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
93612 + /**< dTSEC Internal data error on receive */
93613 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
93614 + /**< dTSEC Time-Stamp Receive Error */
93615 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
93616 + /**< dTSEC MIB counter overflow */
93617 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
93618 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
93619 + not supported on T4240/B4860 rev1 chips */
93620 +};
93621 +
93622 +#define ENET_IF_SGMII_BASEX 0x80000000
93623 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
93624 + and phy or backplane;
93625 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
93626 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
93627 + 10Mbps, 100Mbps or 1000Mbps */
93628 +
93629 +enum enet_mode {
93630 + E_ENET_MODE_INVALID = 0,
93631 + /**< Invalid Ethernet mode */
93632 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
93633 + /**< 10 Mbps MII */
93634 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
93635 + /**< 100 Mbps MII */
93636 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
93637 + /**< 10 Mbps RMII */
93638 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
93639 + /**< 100 Mbps RMII */
93640 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
93641 + /**< 10 Mbps SMII */
93642 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
93643 + /**< 100 Mbps SMII */
93644 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
93645 + /**< 1000 Mbps GMII */
93646 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
93647 + /**< 10 Mbps RGMII */
93648 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
93649 + /**< 100 Mbps RGMII */
93650 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
93651 + /**< 1000 Mbps RGMII */
93652 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
93653 + /**< 1000 Mbps TBI */
93654 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
93655 + /**< 1000 Mbps RTBI */
93656 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
93657 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
93658 + SGMII phy according to Cisco SGMII specification */
93659 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
93660 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
93661 + SGMII phy according to Cisco SGMII specification */
93662 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
93663 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
93664 + SGMII phy according to Cisco SGMII specification */
93665 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
93666 + | E_ENET_SPEED_10),
93667 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
93668 + MAC and SGMII phy or backplane */
93669 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
93670 + | E_ENET_SPEED_100),
93671 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
93672 + MAC and SGMII phy or backplane */
93673 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
93674 + | E_ENET_SPEED_1000),
93675 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
93676 + MAC and SGMII phy or backplane */
93677 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
93678 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
93679 + QSGMII phy according to Cisco QSGMII specification */
93680 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
93681 + | E_ENET_SPEED_1000),
93682 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
93683 + MAC and QSGMII phy or backplane */
93684 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
93685 + /**< 10000 Mbps XGMII */
93686 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
93687 + /**< 10000 Mbps XFI */
93688 +};
93689 +
93690 +enum fmam_mac_statistics_level {
93691 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
93692 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
93693 + Optimized for performance */
93694 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
93695 + optimized for performance */
93696 +};
93697 +
93698 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
93699 + | (_speed))
93700 +
93701 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
93702 + ((mode) & 0x0FFF0000)
93703 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
93704 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
93705 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
93706 + ((uint64_t)(_enet_addr)[1] << 32) | \
93707 + ((uint64_t)(_enet_addr)[2] << 24) | \
93708 + ((uint64_t)(_enet_addr)[3] << 16) | \
93709 + ((uint64_t)(_enet_addr)[4] << 8) | \
93710 + ((uint64_t)(_enet_addr)[5]))
93711 +
93712 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
93713 + do { \
93714 + int i; \
93715 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
93716 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
93717 + } while (0)
93718 +
93719 +#endif /* __FSL_ENET_H */
93720 --- /dev/null
93721 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
93722 @@ -0,0 +1,825 @@
93723 +/*
93724 + * Copyright 2013 Freescale Semiconductor Inc.
93725 + *
93726 + * Redistribution and use in source and binary forms, with or without
93727 + * modification, are permitted provided that the following conditions are met:
93728 + * * Redistributions of source code must retain the above copyright
93729 + * notice, this list of conditions and the following disclaimer.
93730 + * * Redistributions in binary form must reproduce the above copyright
93731 + * notice, this list of conditions and the following disclaimer in the
93732 + * documentation and/or other materials provided with the distribution.
93733 + * * Neither the name of Freescale Semiconductor nor the
93734 + * names of its contributors may be used to endorse or promote products
93735 + * derived from this software without specific prior written permission.
93736 + *
93737 + *
93738 + * ALTERNATIVELY, this software may be distributed under the terms of the
93739 + * GNU General Public License ("GPL") as published by the Free Software
93740 + * Foundation, either version 2 of that License or (at your option) any
93741 + * later version.
93742 + *
93743 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93744 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93745 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93746 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93747 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93748 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93749 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93750 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93751 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93752 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93753 + */
93754 +
93755 +#ifndef __FSL_FMAN_H
93756 +#define __FSL_FMAN_H
93757 +
93758 +#include "common/general.h"
93759 +
93760 +struct fman_ext_pool_params {
93761 + uint8_t id; /**< External buffer pool id */
93762 + uint16_t size; /**< External buffer pool buffer size */
93763 +};
93764 +
93765 +struct fman_ext_pools {
93766 + uint8_t num_pools_used; /**< Number of pools use by this port */
93767 + struct fman_ext_pool_params *ext_buf_pool;
93768 + /**< Parameters for each port */
93769 +};
93770 +
93771 +struct fman_backup_bm_pools {
93772 + uint8_t num_backup_pools; /**< Number of BM backup pools -
93773 + must be smaller than the total number
93774 + of pools defined for the specified
93775 + port.*/
93776 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
93777 + specifying which pools should be used
93778 + only as backup. Pool id's specified
93779 + here must be a subset of the pools
93780 + used by the specified port.*/
93781 +};
93782 +
93783 +/**************************************************************************//**
93784 + @Description A structure for defining BM pool depletion criteria
93785 +*//***************************************************************************/
93786 +struct fman_buf_pool_depletion {
93787 + bool buf_pool_depletion_enabled;
93788 + bool pools_grp_mode_enable; /**< select mode in which pause frames
93789 + will be sent after a number of pools
93790 + (all together!) are depleted */
93791 + uint8_t num_pools; /**< the number of depleted pools that
93792 + will invoke pause frames transmission.
93793 + */
93794 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
93795 + considered for depletion (Note - this
93796 + pool must be used by this port!). */
93797 + bool single_pool_mode_enable; /**< select mode in which pause frames
93798 + will be sent after a single-pool
93799 + is depleted; */
93800 + bool *pools_to_consider_for_single_mode;
93801 + /**< For each pool, TRUE if it should be
93802 + considered for depletion (Note - this
93803 + pool must be used by this port!) */
93804 + bool has_pfc_priorities;
93805 + bool *pfc_priorities_en; /**< This field is used by the MAC as
93806 + the Priority Enable Vector in the PFC
93807 + frame which is transmitted */
93808 +};
93809 +
93810 +/**************************************************************************//**
93811 + @Description Enum for defining port DMA swap mode
93812 +*//***************************************************************************/
93813 +enum fman_dma_swap_option {
93814 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
93815 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
93816 + in PowerPc Little Endian mode. */
93817 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
93818 + in Big Endian mode */
93819 +};
93820 +
93821 +/**************************************************************************//**
93822 + @Description Enum for defining port DMA cache attributes
93823 +*//***************************************************************************/
93824 +enum fman_dma_cache_option {
93825 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
93826 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
93827 +};
93828 +
93829 +typedef struct t_FmPrsResult fm_prs_result_t;
93830 +typedef enum e_EnetMode enet_mode_t;
93831 +typedef t_Handle handle_t;
93832 +
93833 +struct fman_revision_info {
93834 + uint8_t majorRev; /**< Major revision */
93835 + uint8_t minorRev; /**< Minor revision */
93836 +};
93837 +
93838 +/* sizes */
93839 +#define CAPWAP_FRAG_EXTRA_SPACE 32
93840 +#define OFFSET_UNITS 16
93841 +#define MAX_INT_OFFSET 240
93842 +#define MAX_IC_SIZE 256
93843 +#define MAX_EXT_OFFSET 496
93844 +#define MAX_EXT_BUFFER_OFFSET 511
93845 +
93846 +/**************************************************************************
93847 + @Description Memory Mapped Registers
93848 +***************************************************************************/
93849 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
93850 +
93851 +struct fman_fpm_regs {
93852 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
93853 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
93854 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
93855 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
93856 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
93857 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
93858 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
93859 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
93860 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
93861 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
93862 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
93863 + uint32_t res0050[4]; /**< res 0x50-0x5f */
93864 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
93865 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
93866 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
93867 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
93868 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
93869 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
93870 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
93871 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
93872 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
93873 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
93874 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
93875 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
93876 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
93877 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
93878 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
93879 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
93880 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
93881 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
93882 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
93883 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
93884 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
93885 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
93886 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
93887 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
93888 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
93889 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
93890 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
93891 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
93892 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
93893 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
93894 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
93895 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
93896 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
93897 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
93898 + uint32_t res0600[0x400 - 384];
93899 +};
93900 +
93901 +struct fman_bmi_regs {
93902 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
93903 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
93904 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
93905 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
93906 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
93907 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
93908 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
93909 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
93910 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
93911 + uint32_t res0060[12]; /**<0x60 - 0x8f */
93912 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
93913 + uint32_t res009c; /**< 0x9c */
93914 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
93915 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
93916 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
93917 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
93918 + uint32_t res0200; /**< 0x200 */
93919 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
93920 + uint32_t res0300; /**< 0x300 */
93921 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
93922 +};
93923 +
93924 +struct fman_qmi_regs {
93925 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
93926 + uint32_t res0004; /**< 0x04 */
93927 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
93928 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
93929 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
93930 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
93931 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
93932 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
93933 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
93934 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
93935 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
93936 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
93937 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
93938 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
93939 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
93940 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
93941 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
93942 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
93943 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
93944 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
93945 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
93946 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
93947 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
93948 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
93949 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
93950 + uint32_t res007c; /**< 0x7c */
93951 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
93952 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
93953 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
93954 + struct {
93955 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
93956 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
93957 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
93958 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
93959 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
93960 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
93961 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
93962 + uint32_t res001c; /**< 0x1c */
93963 + } dbg_traps[3]; /**< 0x90 - 0xef */
93964 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
93965 +};
93966 +
93967 +struct fman_dma_regs {
93968 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
93969 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
93970 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
93971 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
93972 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
93973 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
93974 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
93975 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
93976 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
93977 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
93978 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
93979 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
93980 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
93981 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
93982 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
93983 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
93984 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
93985 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
93986 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
93987 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
93988 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
93989 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
93990 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
93991 + uint32_t res005c; /**< 0x5c */
93992 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
93993 + uint32_t res00e0[0x400 - 56];
93994 +};
93995 +
93996 +struct fman_rg {
93997 + struct fman_fpm_regs *fpm_rg;
93998 + struct fman_dma_regs *dma_rg;
93999 + struct fman_bmi_regs *bmi_rg;
94000 + struct fman_qmi_regs *qmi_rg;
94001 +};
94002 +
94003 +enum fman_dma_cache_override {
94004 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
94005 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
94006 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
94007 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
94008 +};
94009 +
94010 +enum fman_dma_aid_mode {
94011 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
94012 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
94013 +};
94014 +
94015 +enum fman_dma_dbg_cnt_mode {
94016 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
94017 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
94018 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
94019 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
94020 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
94021 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
94022 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
94023 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
94024 +};
94025 +
94026 +enum fman_dma_emergency_level {
94027 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
94028 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
94029 +};
94030 +
94031 +enum fman_catastrophic_err {
94032 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
94033 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
94034 +};
94035 +
94036 +enum fman_dma_err {
94037 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
94038 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
94039 +};
94040 +
94041 +struct fman_cfg {
94042 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
94043 + bool en_counters;
94044 + uint8_t disp_limit_tsh;
94045 + uint8_t prs_disp_tsh;
94046 + uint8_t plcr_disp_tsh;
94047 + uint8_t kg_disp_tsh;
94048 + uint8_t bmi_disp_tsh;
94049 + uint8_t qmi_enq_disp_tsh;
94050 + uint8_t qmi_deq_disp_tsh;
94051 + uint8_t fm_ctl1_disp_tsh;
94052 + uint8_t fm_ctl2_disp_tsh;
94053 + enum fman_dma_cache_override dma_cache_override;
94054 + enum fman_dma_aid_mode dma_aid_mode;
94055 + bool dma_aid_override;
94056 + uint8_t dma_axi_dbg_num_of_beats;
94057 + uint8_t dma_cam_num_of_entries;
94058 + uint32_t dma_watchdog;
94059 + uint8_t dma_comm_qtsh_asrt_emer;
94060 + uint8_t dma_write_buf_tsh_asrt_emer;
94061 + uint8_t dma_read_buf_tsh_asrt_emer;
94062 + uint8_t dma_comm_qtsh_clr_emer;
94063 + uint8_t dma_write_buf_tsh_clr_emer;
94064 + uint8_t dma_read_buf_tsh_clr_emer;
94065 + uint32_t dma_sos_emergency;
94066 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
94067 + bool dma_stop_on_bus_error;
94068 + bool dma_en_emergency;
94069 + uint32_t dma_emergency_bus_select;
94070 + enum fman_dma_emergency_level dma_emergency_level;
94071 + bool dma_en_emergency_smoother;
94072 + uint32_t dma_emergency_switch_counter;
94073 + bool halt_on_external_activ;
94074 + bool halt_on_unrecov_ecc_err;
94075 + enum fman_catastrophic_err catastrophic_err;
94076 + enum fman_dma_err dma_err;
94077 + bool en_muram_test_mode;
94078 + bool en_iram_test_mode;
94079 + bool external_ecc_rams_enable;
94080 + uint16_t tnum_aging_period;
94081 + uint32_t exceptions;
94082 + uint16_t clk_freq;
94083 + bool pedantic_dma;
94084 + uint32_t cam_base_addr;
94085 + uint32_t fifo_base_addr;
94086 + uint32_t total_fifo_size;
94087 + uint8_t total_num_of_tasks;
94088 + bool qmi_deq_option_support;
94089 + uint32_t qmi_def_tnums_thresh;
94090 + bool fman_partition_array;
94091 + uint8_t num_of_fman_ctrl_evnt_regs;
94092 +};
94093 +
94094 +/**************************************************************************//**
94095 + @Description Exceptions
94096 +*//***************************************************************************/
94097 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
94098 +#define FMAN_EX_DMA_READ_ECC 0x40000000
94099 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
94100 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
94101 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
94102 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
94103 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
94104 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
94105 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
94106 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
94107 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
94108 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
94109 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
94110 +#define FMAN_EX_IRAM_ECC 0x00040000
94111 +#define FMAN_EX_NURAM_ECC 0x00020000
94112 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
94113 +
94114 +enum fman_exceptions {
94115 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
94116 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
94117 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
94118 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
94119 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
94120 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
94121 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
94122 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
94123 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
94124 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
94125 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
94126 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
94127 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
94128 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
94129 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
94130 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
94131 +};
94132 +
94133 +enum fman_counters {
94134 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
94135 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
94136 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
94137 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
94138 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
94139 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
94140 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
94141 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
94142 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
94143 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
94144 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
94145 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
94146 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
94147 +};
94148 +
94149 +#define FPM_PRT_FM_CTL1 0x00000001
94150 +#define FPM_PRT_FM_CTL2 0x00000002
94151 +
94152 +/**************************************************************************//**
94153 + @Description DMA definitions
94154 +*//***************************************************************************/
94155 +
94156 +/* masks */
94157 +#define DMA_MODE_AID_OR 0x20000000
94158 +#define DMA_MODE_SBER 0x10000000
94159 +#define DMA_MODE_BER 0x00200000
94160 +#define DMA_MODE_EB 0x00100000
94161 +#define DMA_MODE_ECC 0x00000020
94162 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
94163 +#define DMA_MODE_SECURE_PROT 0x00000800
94164 +#define DMA_MODE_EMER_READ 0x00080000
94165 +#define DMA_MODE_EMER_WRITE 0x00040000
94166 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
94167 +#define DMA_MODE_CEN_MASK 0x0000E000
94168 +#define DMA_MODE_DBG_MASK 0x00000380
94169 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
94170 +
94171 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
94172 +
94173 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
94174 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
94175 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
94176 +
94177 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
94178 +#define DMA_LOW_LIODN_MASK 0x00000FFF
94179 +
94180 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
94181 +#define DMA_STATUS_BUS_ERR 0x08000000
94182 +#define DMA_STATUS_READ_ECC 0x04000000
94183 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
94184 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
94185 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
94186 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
94187 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
94188 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
94189 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
94190 +
94191 +#define FM_LIODN_BASE_MASK 0x00000FFF
94192 +
94193 +/* shifts */
94194 +#define DMA_MODE_CACHE_OR_SHIFT 30
94195 +#define DMA_MODE_BUS_PRI_SHIFT 16
94196 +#define DMA_MODE_AXI_DBG_SHIFT 24
94197 +#define DMA_MODE_CEN_SHIFT 13
94198 +#define DMA_MODE_BUS_PROT_SHIFT 10
94199 +#define DMA_MODE_DBG_SHIFT 7
94200 +#define DMA_MODE_EMER_LVL_SHIFT 6
94201 +#define DMA_MODE_AID_MODE_SHIFT 4
94202 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
94203 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
94204 +
94205 +#define DMA_THRESH_COMMQ_SHIFT 24
94206 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
94207 +
94208 +#define DMA_LIODN_SHIFT 16
94209 +
94210 +#define DMA_TRANSFER_PORTID_SHIFT 24
94211 +#define DMA_TRANSFER_TNUM_SHIFT 16
94212 +
94213 +/* sizes */
94214 +#define DMA_MAX_WATCHDOG 0xffffffff
94215 +
94216 +/* others */
94217 +#define DMA_CAM_SIZEOF_ENTRY 0x40
94218 +#define DMA_CAM_ALIGN 0x1000
94219 +#define DMA_CAM_UNITS 8
94220 +
94221 +/**************************************************************************//**
94222 + @Description General defines
94223 +*//***************************************************************************/
94224 +
94225 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
94226 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
94227 +
94228 +/**************************************************************************//**
94229 + @Description FPM defines
94230 +*//***************************************************************************/
94231 +
94232 +/* masks */
94233 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
94234 +#define FPM_EV_MASK_STALL 0x40000000
94235 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
94236 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
94237 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
94238 +#define FPM_EV_MASK_STALL_EN 0x00004000
94239 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
94240 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
94241 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
94242 +
94243 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
94244 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
94245 +#define FPM_RAM_MURAM_ECC 0x00008000
94246 +#define FPM_RAM_IRAM_ECC 0x00004000
94247 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
94248 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
94249 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
94250 +
94251 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
94252 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
94253 +
94254 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
94255 +#define FPM_REV1_MINOR_MASK 0x000000FF
94256 +
94257 +#define FPM_REV2_INTEG_MASK 0x00FF0000
94258 +#define FPM_REV2_ERR_MASK 0x0000FF00
94259 +#define FPM_REV2_CFG_MASK 0x000000FF
94260 +
94261 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
94262 +#define FPM_TS_CTL_EN 0x80000000
94263 +
94264 +#define FPM_PRC_REALSE_STALLED 0x00800000
94265 +
94266 +#define FPM_PS_STALLED 0x00800000
94267 +#define FPM_PS_FM_CTL1_SEL 0x80000000
94268 +#define FPM_PS_FM_CTL2_SEL 0x40000000
94269 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
94270 +
94271 +#define FPM_RSTC_FM_RESET 0x80000000
94272 +#define FPM_RSTC_10G0_RESET 0x04000000
94273 +#define FPM_RSTC_1G0_RESET 0x40000000
94274 +#define FPM_RSTC_1G1_RESET 0x20000000
94275 +#define FPM_RSTC_1G2_RESET 0x10000000
94276 +#define FPM_RSTC_1G3_RESET 0x08000000
94277 +#define FPM_RSTC_1G4_RESET 0x02000000
94278 +
94279 +
94280 +#define FPM_DISP_LIMIT_MASK 0x1F000000
94281 +#define FPM_THR1_PRS_MASK 0xFF000000
94282 +#define FPM_THR1_KG_MASK 0x00FF0000
94283 +#define FPM_THR1_PLCR_MASK 0x0000FF00
94284 +#define FPM_THR1_BMI_MASK 0x000000FF
94285 +
94286 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
94287 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
94288 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
94289 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
94290 +
94291 +/* shifts */
94292 +#define FPM_DISP_LIMIT_SHIFT 24
94293 +
94294 +#define FPM_THR1_PRS_SHIFT 24
94295 +#define FPM_THR1_KG_SHIFT 16
94296 +#define FPM_THR1_PLCR_SHIFT 8
94297 +#define FPM_THR1_BMI_SHIFT 0
94298 +
94299 +#define FPM_THR2_QMI_ENQ_SHIFT 24
94300 +#define FPM_THR2_QMI_DEQ_SHIFT 0
94301 +#define FPM_THR2_FM_CTL1_SHIFT 16
94302 +#define FPM_THR2_FM_CTL2_SHIFT 8
94303 +
94304 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
94305 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
94306 +
94307 +#define FPM_REV1_MAJOR_SHIFT 8
94308 +#define FPM_REV1_MINOR_SHIFT 0
94309 +
94310 +#define FPM_REV2_INTEG_SHIFT 16
94311 +#define FPM_REV2_ERR_SHIFT 8
94312 +#define FPM_REV2_CFG_SHIFT 0
94313 +
94314 +#define FPM_TS_INT_SHIFT 16
94315 +
94316 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
94317 +
94318 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
94319 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
94320 +
94321 +#define FPM_DISP_LIMIT_SHIFT 24
94322 +
94323 +/* Interrupts defines */
94324 +#define FPM_EVENT_FM_CTL_0 0x00008000
94325 +#define FPM_EVENT_FM_CTL 0x0000FF00
94326 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
94327 +
94328 +/* others */
94329 +#define FPM_MAX_DISP_LIMIT 31
94330 +#define FPM_RSTC_FM_RESET 0x80000000
94331 +#define FPM_RSTC_1G0_RESET 0x40000000
94332 +#define FPM_RSTC_1G1_RESET 0x20000000
94333 +#define FPM_RSTC_1G2_RESET 0x10000000
94334 +#define FPM_RSTC_1G3_RESET 0x08000000
94335 +#define FPM_RSTC_10G0_RESET 0x04000000
94336 +#define FPM_RSTC_1G4_RESET 0x02000000
94337 +#define FPM_RSTC_1G5_RESET 0x01000000
94338 +#define FPM_RSTC_1G6_RESET 0x00800000
94339 +#define FPM_RSTC_1G7_RESET 0x00400000
94340 +#define FPM_RSTC_10G1_RESET 0x00200000
94341 +/**************************************************************************//**
94342 + @Description BMI defines
94343 +*//***************************************************************************/
94344 +/* masks */
94345 +#define BMI_INIT_START 0x80000000
94346 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
94347 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
94348 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
94349 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
94350 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
94351 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
94352 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
94353 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
94354 +#define BMI_FIFO_SIZE_MASK 0x000003FF
94355 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
94356 +#define BMI_CFG2_DMAS_MASK 0x0000003F
94357 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
94358 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
94359 +
94360 +/* shifts */
94361 +#define BMI_CFG2_TASKS_SHIFT 16
94362 +#define BMI_CFG2_DMAS_SHIFT 0
94363 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
94364 +#define BMI_FIFO_SIZE_SHIFT 0
94365 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
94366 +#define BMI_NUM_OF_TASKS_SHIFT 24
94367 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
94368 +#define BMI_NUM_OF_DMAS_SHIFT 8
94369 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
94370 +
94371 +/* others */
94372 +#define BMI_FIFO_ALIGN 0x100
94373 +#define FMAN_BMI_FIFO_UNITS 0x100
94374 +
94375 +
94376 +/**************************************************************************//**
94377 + @Description QMI defines
94378 +*//***************************************************************************/
94379 +/* masks */
94380 +#define QMI_CFG_ENQ_EN 0x80000000
94381 +#define QMI_CFG_DEQ_EN 0x40000000
94382 +#define QMI_CFG_EN_COUNTERS 0x10000000
94383 +#define QMI_CFG_SOFT_RESET 0x01000000
94384 +#define QMI_CFG_DEQ_MASK 0x0000003F
94385 +#define QMI_CFG_ENQ_MASK 0x00003F00
94386 +
94387 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
94388 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
94389 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
94390 +
94391 +/* shifts */
94392 +#define QMI_CFG_ENQ_SHIFT 8
94393 +#define QMI_TAPC_TAP 22
94394 +
94395 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
94396 +
94397 +/**************************************************************************//**
94398 + @Description IRAM defines
94399 +*//***************************************************************************/
94400 +/* masks */
94401 +#define IRAM_IADD_AIE 0x80000000
94402 +#define IRAM_READY 0x80000000
94403 +
94404 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
94405 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
94406 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
94407 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
94408 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
94409 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
94410 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
94411 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
94412 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
94413 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
94414 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
94415 + uint8_t event_reg_id);
94416 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
94417 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
94418 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
94419 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
94420 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
94421 + uint8_t port_id);
94422 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
94423 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
94424 + uint8_t port_id);
94425 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
94426 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
94427 + uint8_t port_id);
94428 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
94429 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
94430 + uint8_t reg_id);
94431 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
94432 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
94433 + uint8_t *minor);
94434 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
94435 + enum fman_counters reg_name);
94436 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
94437 +
94438 +
94439 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
94440 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
94441 + uint32_t enable_events);
94442 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
94443 + uint8_t port_id,
94444 + uint8_t num_fman_ctrls,
94445 + uint32_t or_fman_ctrl);
94446 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
94447 + uint8_t port_id,
94448 + bool independent_mode,
94449 + bool is_rx_port);
94450 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
94451 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
94452 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
94453 + uint8_t port_id,
94454 + uint16_t liodn_base,
94455 + uint16_t liodn_offset);
94456 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
94457 + uint8_t port_id,
94458 + uint32_t size_of_fifo,
94459 + uint32_t extra_size_of_fifo);
94460 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
94461 + uint8_t port_id,
94462 + uint8_t num_of_tasks,
94463 + uint8_t num_of_extra_tasks);
94464 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
94465 + uint8_t port_id,
94466 + uint8_t num_of_open_dmas,
94467 + uint8_t num_of_extra_open_dmas,
94468 + uint8_t total_num_of_dmas);
94469 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
94470 +int fman_set_exception(struct fman_rg *fman_rg,
94471 + enum fman_exceptions exception,
94472 + bool enable);
94473 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
94474 + bool enable);
94475 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
94476 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
94477 + uint32_t congestion_group_id,
94478 + uint8_t piority_bit_map,
94479 + uint32_t reg_num);
94480 +
94481 +
94482 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
94483 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
94484 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
94485 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
94486 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
94487 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
94488 +void fman_free_resources(struct fman_rg *fman_rg);
94489 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
94490 +void fman_reset(struct fman_fpm_regs *fpm_rg);
94491 +void fman_resume(struct fman_fpm_regs *fpm_rg);
94492 +
94493 +
94494 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
94495 + uint8_t count1ubit,
94496 + uint16_t fm_clk_freq);
94497 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
94498 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
94499 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
94500 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
94501 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
94502 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
94503 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
94504 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
94505 +int fman_modify_counter(struct fman_rg *fman_rg,
94506 + enum fman_counters reg_name,
94507 + uint32_t val);
94508 +void fman_force_intr(struct fman_rg *fman_rg,
94509 + enum fman_exceptions exception);
94510 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
94511 + uint8_t port_id,
94512 + uint8_t base_storage_profile,
94513 + uint8_t log2_num_of_profiles);
94514 +
94515 +/**************************************************************************//**
94516 + @Description default values
94517 +*//***************************************************************************/
94518 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
94519 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
94520 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
94521 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
94522 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
94523 +#define DEFAULT_AID_OVERRIDE FALSE
94524 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
94525 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
94526 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
94527 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
94528 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
94529 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
94530 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
94531 +#define DEFAULT_DMA_SOS_EMERGENCY 0
94532 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
94533 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
94534 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
94535 +#define DEFAULT_DISP_LIMIT 0
94536 +#define DEFAULT_PRS_DISP_TH 16
94537 +#define DEFAULT_PLCR_DISP_TH 16
94538 +#define DEFAULT_KG_DISP_TH 16
94539 +#define DEFAULT_BMI_DISP_TH 16
94540 +#define DEFAULT_QMI_ENQ_DISP_TH 16
94541 +#define DEFAULT_QMI_DEQ_DISP_TH 16
94542 +#define DEFAULT_FM_CTL1_DISP_TH 16
94543 +#define DEFAULT_FM_CTL2_DISP_TH 16
94544 +#define DEFAULT_TNUM_AGING_PERIOD 4
94545 +
94546 +
94547 +#endif /* __FSL_FMAN_H */
94548 --- /dev/null
94549 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
94550 @@ -0,0 +1,1096 @@
94551 +/*
94552 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94553 + *
94554 + * Redistribution and use in source and binary forms, with or without
94555 + * modification, are permitted provided that the following conditions are met:
94556 + * * Redistributions of source code must retain the above copyright
94557 + * notice, this list of conditions and the following disclaimer.
94558 + * * Redistributions in binary form must reproduce the above copyright
94559 + * notice, this list of conditions and the following disclaimer in the
94560 + * documentation and/or other materials provided with the distribution.
94561 + * * Neither the name of Freescale Semiconductor nor the
94562 + * names of its contributors may be used to endorse or promote products
94563 + * derived from this software without specific prior written permission.
94564 + *
94565 + *
94566 + * ALTERNATIVELY, this software may be distributed under the terms of the
94567 + * GNU General Public License ("GPL") as published by the Free Software
94568 + * Foundation, either version 2 of that License or (at your option) any
94569 + * later version.
94570 + *
94571 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94572 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94573 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94574 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94575 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94576 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94577 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94578 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94579 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94580 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94581 + */
94582 +
94583 +#ifndef __FSL_FMAN_DTSEC_H
94584 +#define __FSL_FMAN_DTSEC_H
94585 +
94586 +#include "common/general.h"
94587 +#include "fsl_enet.h"
94588 +
94589 +/**
94590 + * DOC: dTSEC Init sequence
94591 + *
94592 + * To prepare dTSEC block for transfer use the following call sequence:
94593 + *
94594 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
94595 + * use is to obtain the default dTSEC configuration parameters.
94596 + *
94597 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
94598 + * to customize the dTSEC behavior.
94599 + *
94600 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
94601 + * dTSEC is initialized while both Tx and Rx are disabled.
94602 + *
94603 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
94604 + * This is used by dTSEC to match against received packets.
94605 + *
94606 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
94607 + * after the PHY establishes the link.
94608 + *
94609 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
94610 + * reception.
94611 + */
94612 +
94613 +/**
94614 + * DOC: dTSEC Graceful stop
94615 + *
94616 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
94617 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
94618 + * but return before this stop is complete. To query for graceful stop
94619 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
94620 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
94621 + * enable graceful stop interrupts.
94622 + *
94623 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
94624 + * fman_dtsec_start_rx().
94625 + */
94626 +
94627 +/**
94628 + * DOC: dTSEC interrupt handling
94629 + *
94630 + * This code does not provide an interrupt handler for dTSEC. Instead this
94631 + * handler should be implemented and registered to the operating system by the
94632 + * caller. Some primitives for accessing the event status and mask registers
94633 + * are provided.
94634 + *
94635 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
94636 + */
94637 +
94638 +/**
94639 + * DOC: dTSEC Events
94640 + *
94641 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
94642 + * event register at any time to check for pending interrupts. If an event
94643 + * occurs and its corresponding enable bit is set in the interrupt mask
94644 + * register, the event also causes a hardware interrupt at the PIC.
94645 + *
94646 + * To poll for event status use the fman_dtsec_get_event() function.
94647 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
94648 + * fman_dtsec_disable_interrupt() functions.
94649 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
94650 + * serviced event bit.
94651 + *
94652 + * The following events may be signaled by dTSEC hardware:
94653 + *
94654 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
94655 + * a frame was received with length in excess of the MAC's maximum frame length
94656 + * register.
94657 + *
94658 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
94659 + * control frame was received while Rx pause frame handling is enabled.
94660 + * Also see fman_dtsec_handle_rx_pause().
94661 + *
94662 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
94663 + * counters has exceeded the size of its register.
94664 + *
94665 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
94666 + * complete. The transmitter is in a stopped state, in which only pause frames
94667 + * can be transmitted.
94668 + * Also see fman_dtsec_stop_tx().
94669 + *
94670 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
94671 + * has exceeded the value in the MAC's Maximum Frame Length register.
94672 + *
94673 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
94674 + * indicates that a control frame was transmitted.
94675 + *
94676 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
94677 + * occurred on the transmitted channel. This bit is set whenever any transmit
94678 + * error occurs which causes the dTSEC to discard all or part of a frame
94679 + * (LC, CRL, XFUN).
94680 + *
94681 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
94682 + * occurred beyond the collision window (slot time) in half-duplex mode.
94683 + * The frame is truncated with a bad CRC and the remainder of the frame
94684 + * is discarded.
94685 + *
94686 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
94687 + * of successive transmission collisions has exceeded the MAC's half-duplex
94688 + * register's retransmission maximum count. The frame is discarded without
94689 + * being transmitted and transmission of the next frame commences. This only
94690 + * occurs while in half-duplex mode.
94691 + * The number of retransmit attempts can be set in
94692 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
94693 + *
94694 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
94695 + * transmit FIFO became empty before the complete frame was transmitted.
94696 + * The frame is truncated with a bad CRC and the remainder of the frame is
94697 + * discarded.
94698 + *
94699 + * %DTSEC_IEVENT_MAG - TBD
94700 + *
94701 + * %DTSEC_IEVENT_MMRD - MII management read completion.
94702 + *
94703 + * %DTSEC_IEVENT_MMWR - MII management write completion.
94704 + *
94705 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
94706 + * know if the system has completed the stop and it is safe to write to receive
94707 + * registers (status, control or configuration registers) that are used by the
94708 + * system during normal operation.
94709 + *
94710 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
94711 + * that the dTSEC has detected a parity error on its stored transmit data, which
94712 + * is likely to compromise the validity of recently transferred frames.
94713 + *
94714 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
94715 + * the dTSEC has detected a parity error on its stored receive data, which is
94716 + * likely to compromise the validity of recently transferred frames.
94717 + */
94718 +/* Interrupt Mask Register (IMASK) */
94719 +#define DTSEC_IMASK_BREN 0x80000000
94720 +#define DTSEC_IMASK_RXCEN 0x40000000
94721 +#define DTSEC_IMASK_MSROEN 0x04000000
94722 +#define DTSEC_IMASK_GTSCEN 0x02000000
94723 +#define DTSEC_IMASK_BTEN 0x01000000
94724 +#define DTSEC_IMASK_TXCEN 0x00800000
94725 +#define DTSEC_IMASK_TXEEN 0x00400000
94726 +#define DTSEC_IMASK_LCEN 0x00040000
94727 +#define DTSEC_IMASK_CRLEN 0x00020000
94728 +#define DTSEC_IMASK_XFUNEN 0x00010000
94729 +#define DTSEC_IMASK_ABRTEN 0x00008000
94730 +#define DTSEC_IMASK_IFERREN 0x00004000
94731 +#define DTSEC_IMASK_MAGEN 0x00000800
94732 +#define DTSEC_IMASK_MMRDEN 0x00000400
94733 +#define DTSEC_IMASK_MMWREN 0x00000200
94734 +#define DTSEC_IMASK_GRSCEN 0x00000100
94735 +#define DTSEC_IMASK_TDPEEN 0x00000002
94736 +#define DTSEC_IMASK_RDPEEN 0x00000001
94737 +
94738 +#define DTSEC_EVENTS_MASK \
94739 + ((uint32_t)(DTSEC_IMASK_BREN | \
94740 + DTSEC_IMASK_RXCEN | \
94741 + DTSEC_IMASK_BTEN | \
94742 + DTSEC_IMASK_TXCEN | \
94743 + DTSEC_IMASK_TXEEN | \
94744 + DTSEC_IMASK_ABRTEN | \
94745 + DTSEC_IMASK_LCEN | \
94746 + DTSEC_IMASK_CRLEN | \
94747 + DTSEC_IMASK_XFUNEN | \
94748 + DTSEC_IMASK_IFERREN | \
94749 + DTSEC_IMASK_MAGEN | \
94750 + DTSEC_IMASK_TDPEEN | \
94751 + DTSEC_IMASK_RDPEEN))
94752 +
94753 +/* dtsec timestamp event bits */
94754 +#define TMR_PEMASK_TSREEN 0x00010000
94755 +#define TMR_PEVENT_TSRE 0x00010000
94756 +
94757 +/* Group address bit indication */
94758 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
94759 +/* size in bytes of L2 address */
94760 +#define MAC_ADDRLEN 6
94761 +
94762 +#define DEFAULT_HALFDUP_ON FALSE
94763 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
94764 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
94765 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
94766 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
94767 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
94768 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
94769 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
94770 +#define DEFAULT_RX_DROP_BCAST FALSE
94771 +#define DEFAULT_RX_SHORT_FRM TRUE
94772 +#define DEFAULT_RX_LEN_CHECK FALSE
94773 +#define DEFAULT_TX_PAD_CRC TRUE
94774 +#define DEFAULT_TX_CRC FALSE
94775 +#define DEFAULT_RX_CTRL_ACC FALSE
94776 +#define DEFAULT_TX_PAUSE_TIME 0xf000
94777 +#define DEFAULT_TBIPA 5
94778 +#define DEFAULT_RX_PREPEND 0
94779 +#define DEFAULT_PTP_TSU_EN TRUE
94780 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
94781 +#define DEFAULT_PREAMBLE_LEN 7
94782 +#define DEFAULT_RX_PREAMBLE FALSE
94783 +#define DEFAULT_TX_PREAMBLE FALSE
94784 +#define DEFAULT_LOOPBACK FALSE
94785 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
94786 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
94787 +#define DEFAULT_RX_FLOW TRUE
94788 +#define DEFAULT_TX_FLOW TRUE
94789 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
94790 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
94791 +#define DEFAULT_RX_PROMISC FALSE
94792 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
94793 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
94794 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
94795 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
94796 +#define DEFAULT_MAXIMUM_FRAME 0x600
94797 +#define DEFAULT_TBI_PHY_ADDR 5
94798 +#define DEFAULT_WAKE_ON_LAN FALSE
94799 +
94800 +/* register related defines (bits, field offsets..) */
94801 +#define DTSEC_ID1_ID 0xffff0000
94802 +#define DTSEC_ID1_REV_MJ 0x0000FF00
94803 +#define DTSEC_ID1_REV_MN 0x000000ff
94804 +
94805 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
94806 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
94807 +
94808 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
94809 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
94810 +#define DTSEC_ECNTRL_STEN 0x00001000
94811 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
94812 +#define DTSEC_ECNTRL_GMIIM 0x00000040
94813 +#define DTSEC_ECNTRL_TBIM 0x00000020
94814 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
94815 +#define DTSEC_ECNTRL_RPM 0x00000010
94816 +#define DTSEC_ECNTRL_R100M 0x00000008
94817 +#define DTSEC_ECNTRL_RMM 0x00000004
94818 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
94819 +
94820 +#define DTSEC_TCTRL_THDF 0x00000800
94821 +#define DTSEC_TCTRL_TTSE 0x00000040
94822 +#define DTSEC_TCTRL_GTS 0x00000020
94823 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
94824 +
94825 +/* PTV offsets */
94826 +#define PTV_PTE_OFST 16
94827 +
94828 +#define RCTRL_CFA 0x00008000
94829 +#define RCTRL_GHTX 0x00000400
94830 +#define RCTRL_RTSE 0x00000040
94831 +#define RCTRL_GRS 0x00000020
94832 +#define RCTRL_BC_REJ 0x00000010
94833 +#define RCTRL_MPROM 0x00000008
94834 +#define RCTRL_RSF 0x00000004
94835 +#define RCTRL_UPROM 0x00000001
94836 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
94837 +
94838 +#define TMR_CTL_ESFDP 0x00000800
94839 +#define TMR_CTL_ESFDE 0x00000400
94840 +
94841 +#define MACCFG1_SOFT_RESET 0x80000000
94842 +#define MACCFG1_LOOPBACK 0x00000100
94843 +#define MACCFG1_RX_FLOW 0x00000020
94844 +#define MACCFG1_TX_FLOW 0x00000010
94845 +#define MACCFG1_TX_EN 0x00000001
94846 +#define MACCFG1_RX_EN 0x00000004
94847 +#define MACCFG1_RESET_RxMC 0x00080000
94848 +#define MACCFG1_RESET_TxMC 0x00040000
94849 +#define MACCFG1_RESET_RxFUN 0x00020000
94850 +#define MACCFG1_RESET_TxFUN 0x00010000
94851 +
94852 +#define MACCFG2_NIBBLE_MODE 0x00000100
94853 +#define MACCFG2_BYTE_MODE 0x00000200
94854 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
94855 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
94856 +#define MACCFG2_LENGTH_CHECK 0x00000010
94857 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
94858 +#define MACCFG2_PAD_CRC_EN 0x00000004
94859 +#define MACCFG2_CRC_EN 0x00000002
94860 +#define MACCFG2_FULL_DUPLEX 0x00000001
94861 +
94862 +#define PREAMBLE_LENGTH_SHIFT 12
94863 +
94864 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
94865 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
94866 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
94867 +
94868 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
94869 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
94870 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
94871 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
94872 +
94873 +#define HAFDUP_ALT_BEB 0x00080000
94874 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
94875 +#define HAFDUP_NO_BACKOFF 0x00020000
94876 +#define HAFDUP_EXCESS_DEFER 0x00010000
94877 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
94878 +
94879 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
94880 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
94881 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
94882 +
94883 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
94884 +
94885 +/* CAR1/2 bits */
94886 +#define DTSEC_CAR1_TR64 0x80000000
94887 +#define DTSEC_CAR1_TR127 0x40000000
94888 +#define DTSEC_CAR1_TR255 0x20000000
94889 +#define DTSEC_CAR1_TR511 0x10000000
94890 +#define DTSEC_CAR1_TRK1 0x08000000
94891 +#define DTSEC_CAR1_TRMAX 0x04000000
94892 +#define DTSEC_CAR1_TRMGV 0x02000000
94893 +
94894 +#define DTSEC_CAR1_RBYT 0x00010000
94895 +#define DTSEC_CAR1_RPKT 0x00008000
94896 +#define DTSEC_CAR1_RFCS 0x00004000
94897 +#define DTSEC_CAR1_RMCA 0x00002000
94898 +#define DTSEC_CAR1_RBCA 0x00001000
94899 +#define DTSEC_CAR1_RXCF 0x00000800
94900 +#define DTSEC_CAR1_RXPF 0x00000400
94901 +#define DTSEC_CAR1_RXUO 0x00000200
94902 +#define DTSEC_CAR1_RALN 0x00000100
94903 +#define DTSEC_CAR1_RFLR 0x00000080
94904 +#define DTSEC_CAR1_RCDE 0x00000040
94905 +#define DTSEC_CAR1_RCSE 0x00000020
94906 +#define DTSEC_CAR1_RUND 0x00000010
94907 +#define DTSEC_CAR1_ROVR 0x00000008
94908 +#define DTSEC_CAR1_RFRG 0x00000004
94909 +#define DTSEC_CAR1_RJBR 0x00000002
94910 +#define DTSEC_CAR1_RDRP 0x00000001
94911 +
94912 +#define DTSEC_CAR2_TJBR 0x00080000
94913 +#define DTSEC_CAR2_TFCS 0x00040000
94914 +#define DTSEC_CAR2_TXCF 0x00020000
94915 +#define DTSEC_CAR2_TOVR 0x00010000
94916 +#define DTSEC_CAR2_TUND 0x00008000
94917 +#define DTSEC_CAR2_TFRG 0x00004000
94918 +#define DTSEC_CAR2_TBYT 0x00002000
94919 +#define DTSEC_CAR2_TPKT 0x00001000
94920 +#define DTSEC_CAR2_TMCA 0x00000800
94921 +#define DTSEC_CAR2_TBCA 0x00000400
94922 +#define DTSEC_CAR2_TXPF 0x00000200
94923 +#define DTSEC_CAR2_TDFR 0x00000100
94924 +#define DTSEC_CAR2_TEDF 0x00000080
94925 +#define DTSEC_CAR2_TSCL 0x00000040
94926 +#define DTSEC_CAR2_TMCL 0x00000020
94927 +#define DTSEC_CAR2_TLCL 0x00000010
94928 +#define DTSEC_CAR2_TXCL 0x00000008
94929 +#define DTSEC_CAR2_TNCL 0x00000004
94930 +#define DTSEC_CAR2_TDRP 0x00000001
94931 +
94932 +#define CAM1_ERRORS_ONLY \
94933 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
94934 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
94935 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
94936 + | DTSEC_CAR1_RDRP)
94937 +
94938 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
94939 +
94940 +/*
94941 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
94942 + * (or Ethernet) statistics.
94943 + */
94944 +#define CAM1_MIB_GRP_1 \
94945 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
94946 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
94947 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
94948 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
94949 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
94950 +
94951 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
94952 +
94953 +/* memory map */
94954 +
94955 +struct dtsec_regs {
94956 + /* dTSEC General Control and Status Registers */
94957 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
94958 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
94959 + uint32_t ievent; /* 0x008 Interrupt event register */
94960 + uint32_t imask; /* 0x00C Interrupt mask register */
94961 + uint32_t reserved0010[1];
94962 + uint32_t ecntrl; /* 0x014 E control register */
94963 + uint32_t ptv; /* 0x018 Pause time value register */
94964 + uint32_t tbipa; /* 0x01C TBI PHY address register */
94965 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
94966 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
94967 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
94968 + uint32_t reserved002c[5];
94969 + uint32_t tctrl; /* 0x040 Transmit control register */
94970 + uint32_t reserved0044[3];
94971 + uint32_t rctrl; /* 0x050 Receive control register */
94972 + uint32_t reserved0054[11];
94973 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
94974 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
94975 + uint32_t reserved00c0[16];
94976 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
94977 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
94978 + uint32_t ipgifg; /* 0x108 IPG/IFG */
94979 + uint32_t hafdup; /* 0x10C Half-duplex */
94980 + uint32_t maxfrm; /* 0x110 Maximum frame */
94981 + uint32_t reserved0114[10];
94982 + uint32_t ifstat; /* 0x13C Interface status */
94983 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
94984 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
94985 + struct {
94986 + uint32_t exact_match1; /* octets 1-4 */
94987 + uint32_t exact_match2; /* octets 5-6 */
94988 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
94989 + uint32_t reserved01c0[16];
94990 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
94991 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
94992 + * counter */
94993 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
94994 + * counter */
94995 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
94996 + * counter */
94997 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
94998 + * counter */
94999 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
95000 + * counter */
95001 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
95002 + * VLAN frame count */
95003 + uint32_t rbyt; /* 0x21C receive byte counter */
95004 + uint32_t rpkt; /* 0x220 receive packet counter */
95005 + uint32_t rfcs; /* 0x224 receive FCS error counter */
95006 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
95007 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
95008 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
95009 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
95010 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
95011 + uint32_t raln; /* 0x23C receive alignment error counter */
95012 + uint32_t rflr; /* 0x240 receive frame length error counter */
95013 + uint32_t rcde; /* 0x244 receive code error counter */
95014 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
95015 + uint32_t rund; /* 0x24C receive undersize packet counter */
95016 + uint32_t rovr; /* 0x250 receive oversize packet counter */
95017 + uint32_t rfrg; /* 0x254 receive fragments counter */
95018 + uint32_t rjbr; /* 0x258 receive jabber counter */
95019 + uint32_t rdrp; /* 0x25C receive drop */
95020 + uint32_t tbyt; /* 0x260 transmit byte counter */
95021 + uint32_t tpkt; /* 0x264 transmit packet counter */
95022 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
95023 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
95024 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
95025 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
95026 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
95027 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
95028 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
95029 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
95030 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
95031 + uint32_t tncl; /* 0x28C transmit total collision counter */
95032 + uint32_t reserved0290[1];
95033 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
95034 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
95035 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
95036 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
95037 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
95038 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
95039 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
95040 + uint32_t car1; /* 0x2B0 carry register one register* */
95041 + uint32_t car2; /* 0x2B4 carry register two register* */
95042 + uint32_t cam1; /* 0x2B8 carry register one mask register */
95043 + uint32_t cam2; /* 0x2BC carry register two mask register */
95044 + uint32_t reserved02c0[848];
95045 +};
95046 +
95047 +/**
95048 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
95049 + *
95050 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
95051 + * good or bad frame, of any type, transmitted or received, which
95052 + * is 64 bytes in length.
95053 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
95054 + * each good or bad frame of any type, transmitted or received,
95055 + * which is 65-127 bytes in length.
95056 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
95057 + * for each good or bad frame, of any type, transmitted or
95058 + * received, which is 128-255 bytes in length.
95059 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
95060 + * for each good or bad frame, of any type, transmitted or
95061 + * received, which is 256-511 bytes in length.
95062 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
95063 + * for each good or bad frame, of any type, transmitted or
95064 + * received, which is 512-1023 bytes in length.
95065 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
95066 + * for each good or bad frame, of any type, transmitted or
95067 + * received, which is 1024-1518 bytes in length.
95068 + * @rfrg: Receive fragments count. Increments for each received frame
95069 + * which is less than 64 bytes in length and contains an invalid
95070 + * FCS. This includes integral and non-integral lengths.
95071 + * @rjbr: Receive jabber count. Increments for received frames which
95072 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
95073 + * invalid FCS. This includes alignment errors.
95074 + * @rdrp: Receive dropped packets count. Increments for received frames
95075 + * which are streamed to system but are later dropped due to lack
95076 + * of system resources. Does not increment for frames rejected due
95077 + * to address filtering.
95078 + * @raln: Receive alignment error count. Increments for each received
95079 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
95080 + * an invalid FCS and is not an integral number of bytes.
95081 + * @rund: Receive undersize packet count. Increments each time a frame is
95082 + * received which is less than 64 bytes in length and contains a
95083 + * valid FCS and is otherwise well formed. This count does not
95084 + * include range length errors.
95085 + * @rovr: Receive oversize packet count. Increments each time a frame is
95086 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
95087 + * contains a valid FCS and is otherwise well formed.
95088 + * @rbyt: Receive byte count. Increments by the byte count of frames
95089 + * received, including those in bad packets, excluding preamble and
95090 + * SFD but including FCS bytes.
95091 + * @rpkt: Receive packet count. Increments for each received frame
95092 + * (including bad packets, all unicast, broadcast, and multicast
95093 + * packets).
95094 + * @rmca: Receive multicast packet count. Increments for each multicast
95095 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
95096 + * 1522 (VLAN), excluding broadcast frames. This count does not
95097 + * include range/length errors.
95098 + * @rbca: Receive broadcast packet count. Increments for each broadcast
95099 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
95100 + * 1522 (VLAN), excluding multicast frames. Does not include
95101 + * range/length errors.
95102 + * @tdrp: Transmit drop frame count. Increments each time a memory error
95103 + * or an underrun has occurred.
95104 + * @tncl: Transmit total collision counter. Increments by the number of
95105 + * collisions experienced during the transmission of a frame. Does
95106 + * not increment for aborted frames.
95107 + *
95108 + * The structure contains a group of dTSEC HW specific counters relating to the
95109 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
95110 + * is counting only the carry events of the corresponding HW counters.
95111 + *
95112 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
95113 + * and SFD but including FCS bytes.
95114 + */
95115 +struct dtsec_mib_grp_1_counters {
95116 + uint64_t rdrp;
95117 + uint64_t tdrp;
95118 + uint64_t rbyt;
95119 + uint64_t rpkt;
95120 + uint64_t rbca;
95121 + uint64_t rmca;
95122 + uint64_t raln;
95123 + uint64_t rund;
95124 + uint64_t rovr;
95125 + uint64_t rfrg;
95126 + uint64_t rjbr;
95127 + uint64_t tncl;
95128 + uint64_t tr64;
95129 + uint64_t tr127;
95130 + uint64_t tr255;
95131 + uint64_t tr511;
95132 + uint64_t tr1k;
95133 + uint64_t trmax;
95134 +};
95135 +
95136 +enum dtsec_stat_counters {
95137 + E_DTSEC_STAT_TR64,
95138 + E_DTSEC_STAT_TR127,
95139 + E_DTSEC_STAT_TR255,
95140 + E_DTSEC_STAT_TR511,
95141 + E_DTSEC_STAT_TR1K,
95142 + E_DTSEC_STAT_TRMAX,
95143 + E_DTSEC_STAT_TRMGV,
95144 + E_DTSEC_STAT_RBYT,
95145 + E_DTSEC_STAT_RPKT,
95146 + E_DTSEC_STAT_RMCA,
95147 + E_DTSEC_STAT_RBCA,
95148 + E_DTSEC_STAT_RXPF,
95149 + E_DTSEC_STAT_RALN,
95150 + E_DTSEC_STAT_RFLR,
95151 + E_DTSEC_STAT_RCDE,
95152 + E_DTSEC_STAT_RCSE,
95153 + E_DTSEC_STAT_RUND,
95154 + E_DTSEC_STAT_ROVR,
95155 + E_DTSEC_STAT_RFRG,
95156 + E_DTSEC_STAT_RJBR,
95157 + E_DTSEC_STAT_RDRP,
95158 + E_DTSEC_STAT_TFCS,
95159 + E_DTSEC_STAT_TBYT,
95160 + E_DTSEC_STAT_TPKT,
95161 + E_DTSEC_STAT_TMCA,
95162 + E_DTSEC_STAT_TBCA,
95163 + E_DTSEC_STAT_TXPF,
95164 + E_DTSEC_STAT_TNCL,
95165 + E_DTSEC_STAT_TDRP
95166 +};
95167 +
95168 +enum dtsec_stat_level {
95169 + /* No statistics */
95170 + E_MAC_STAT_NONE = 0,
95171 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
95172 + E_MAC_STAT_MIB_GRP1,
95173 + /* Only error counters are available. Optimized for performance */
95174 + E_MAC_STAT_PARTIAL,
95175 + /* All counters available. Not optimized for performance */
95176 + E_MAC_STAT_FULL
95177 +};
95178 +
95179 +
95180 +/**
95181 + * struct dtsec_cfg - dTSEC configuration
95182 + *
95183 + * @halfdup_on: Transmit half-duplex flow control, under software
95184 + * control for 10/100-Mbps half-duplex media. If set,
95185 + * back pressure is applied to media by raising carrier.
95186 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
95187 + * If this is exceeded dTSEC aborts transmission due to
95188 + * excessive collisions. The standard specifies the
95189 + * attempt limit to be 15.
95190 + * @halfdup_coll_window:The number of bytes of the frame during which
95191 + * collisions may occur. The default value of 55
95192 + * corresponds to the frame byte at the end of the
95193 + * standard 512-bit slot time window. If collisions are
95194 + * detected after this byte, the late collision event is
95195 + * asserted and transmission of current frame is aborted.
95196 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
95197 + * will be discarded by dTSEC.
95198 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
95199 + * of length 14..63 bytes.
95200 + * @rx_len_check: Length check for received frames. If set, the MAC
95201 + * checks the frame's length field on receive to ensure it
95202 + * matches the actual data field length. This only works
95203 + * for received frames with length field less than 1500.
95204 + * No check is performed for larger frames.
95205 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
95206 + * transmitted short frames and appends a CRC to every
95207 + * frame regardless of padding requirement.
95208 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
95209 + * to all frames. If frames presented to the MAC have a
95210 + * valid length and contain a valid CRC, @tx_crc should be
95211 + * reset.
95212 + * This field is ignored if @tx_pad_crc is set.
95213 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
95214 + * standard control frame behavior, and all Ethernet frames
95215 + * that have an ethertype of 0x8808 are treated as normal
95216 + * Ethernet frames and passed up to the packet interface on
95217 + * a DA match. Received pause control frames are passed to
95218 + * the packet interface only if Rx flow control is also
95219 + * disabled. See fman_dtsec_handle_rx_pause() function.
95220 + * @tx_pause_time: Transmit pause time value. This pause value is used as
95221 + * part of the pause frame to be sent when a transmit pause
95222 + * frame is initiated. If set to 0 this disables
95223 + * transmission of pause frames.
95224 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
95225 + * received Ethernet 7-byte preamble and passes it to the
95226 + * packet interface at the start of each received frame.
95227 + * This field should be reset for internal MAC loop-back
95228 + * mode.
95229 + * @tx_preamble: User defined preamble enable for transmitted frames.
95230 + * If set, a user-defined preamble must passed to the MAC
95231 + * and it is transmitted instead of the standard preamble.
95232 + * @preamble_len: Length, in bytes, of the preamble field preceding each
95233 + * Ethernet start-of-frame delimiter byte. The default
95234 + * value of 0x7 should be used in order to guarantee
95235 + * reliable operation with IEEE 802.3 compliant hardware.
95236 + * @rx_prepend: Packet alignment padding length. The specified number
95237 + * of bytes (1-31) of zero padding are inserted before the
95238 + * start of each received frame. For Ethernet, where
95239 + * optional preamble extraction is enabled, the padding
95240 + * appears before the preamble, otherwise the padding
95241 + * precedes the layer 2 header.
95242 + *
95243 + * This structure contains basic dTSEC configuration and must be passed to
95244 + * fman_dtsec_init() function. A default set of configuration values can be
95245 + * obtained by calling fman_dtsec_defconfig().
95246 + */
95247 +struct dtsec_cfg {
95248 + bool halfdup_on;
95249 + bool halfdup_alt_backoff_en;
95250 + bool halfdup_excess_defer;
95251 + bool halfdup_no_backoff;
95252 + bool halfdup_bp_no_backoff;
95253 + uint8_t halfdup_alt_backoff_val;
95254 + uint16_t halfdup_retransmit;
95255 + uint16_t halfdup_coll_window;
95256 + bool rx_drop_bcast;
95257 + bool rx_short_frm;
95258 + bool rx_len_check;
95259 + bool tx_pad_crc;
95260 + bool tx_crc;
95261 + bool rx_ctrl_acc;
95262 + unsigned short tx_pause_time;
95263 + unsigned short tbipa;
95264 + bool ptp_tsu_en;
95265 + bool ptp_exception_en;
95266 + bool rx_preamble;
95267 + bool tx_preamble;
95268 + unsigned char preamble_len;
95269 + unsigned char rx_prepend;
95270 + bool loopback;
95271 + bool rx_time_stamp_en;
95272 + bool tx_time_stamp_en;
95273 + bool rx_flow;
95274 + bool tx_flow;
95275 + bool rx_group_hash_exd;
95276 + bool rx_promisc;
95277 + uint8_t tbi_phy_addr;
95278 + uint16_t tx_pause_time_extd;
95279 + uint16_t maximum_frame;
95280 + uint32_t non_back_to_back_ipg1;
95281 + uint32_t non_back_to_back_ipg2;
95282 + uint32_t min_ifg_enforcement;
95283 + uint32_t back_to_back_ipg;
95284 + bool wake_on_lan;
95285 +};
95286 +
95287 +
95288 +/**
95289 + * fman_dtsec_defconfig() - Get default dTSEC configuration
95290 + * @cfg: pointer to configuration structure.
95291 + *
95292 + * Call this function to obtain a default set of configuration values for
95293 + * initializing dTSEC. The user can overwrite any of the values before calling
95294 + * fman_dtsec_init(), if specific configuration needs to be applied.
95295 + */
95296 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
95297 +
95298 +/**
95299 + * fman_dtsec_init() - Init dTSEC hardware block
95300 + * @regs: Pointer to dTSEC register block
95301 + * @cfg: dTSEC configuration data
95302 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
95303 + * @iface_speed: 1G or 10G
95304 + * @macaddr: MAC station address to be assigned to the device
95305 + * @fm_rev_maj: major rev number
95306 + * @fm_rev_min: minor rev number
95307 + * @exceptions_mask: initial exceptions mask
95308 + *
95309 + * This function initializes dTSEC and applies basic configuration.
95310 + *
95311 + * dTSEC initialization sequence:
95312 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
95313 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
95314 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
95315 + *
95316 + * Returns: 0 if successful, an error code otherwise.
95317 + */
95318 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
95319 + enum enet_interface iface_mode,
95320 + enum enet_speed iface_speed,
95321 + uint8_t *macaddr, uint8_t fm_rev_maj,
95322 + uint8_t fm_rev_min,
95323 + uint32_t exception_mask);
95324 +
95325 +/**
95326 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
95327 + * @regs: Pointer to dTSEC register block
95328 + * @apply_rx: enable rx side
95329 + * @apply_tx: enable tx side
95330 + *
95331 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
95332 + */
95333 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
95334 +
95335 +/**
95336 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
95337 + * @regs: Pointer to dTSEC register block
95338 + * @apply_rx: disable rx side
95339 + * @apply_tx: disable tx side
95340 + *
95341 + * This function disables Tx and Rx in dTSEC.
95342 + */
95343 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
95344 +
95345 +/**
95346 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
95347 + * @regs: Pointer to dTSEC register block
95348 + *
95349 + * Returns dtsec_id content
95350 + *
95351 + * Call this function to obtain the dTSEC hardware version.
95352 + */
95353 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
95354 +
95355 +/**
95356 + * fman_dtsec_set_mac_address() - Set MAC station address
95357 + * @regs: Pointer to dTSEC register block
95358 + * @macaddr: MAC address array
95359 + *
95360 + * This function sets MAC station address. To enable unicast reception call
95361 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
95362 + * match the destination address of received unicast frames against this
95363 + * address.
95364 + */
95365 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
95366 +
95367 +/**
95368 + * fman_dtsec_get_mac_address() - Query MAC station address
95369 + * @regs: Pointer to dTSEC register block
95370 + * @macaddr: MAC address array
95371 + */
95372 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
95373 +
95374 +/**
95375 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
95376 + * @regs: Pointer to dTSEC register block
95377 + * @enable: Enable unicast promiscuous mode
95378 + *
95379 + * Use this function to enable/disable dTSEC L2 address filtering. If the
95380 + * address filtering is disabled all unicast packets are accepted.
95381 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
95382 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
95383 + * multicast addresses.
95384 + */
95385 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
95386 +
95387 +/**
95388 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
95389 + * (magic packet support)
95390 + * @regs: Pointer to dTSEC register block
95391 + * @en: Enable Wake On Lan support in dTSEC
95392 + *
95393 + */
95394 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
95395 +
95396 +/**
95397 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
95398 + * @regs: Pointer to dTSEC register block
95399 + * @iface_mode: dTSEC interface mode
95400 + * @speed: Link speed
95401 + * @full_dx: True for full-duplex, false for half-duplex.
95402 + *
95403 + * This function configures the MAC to function and the desired rates. Use it
95404 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
95405 + * changes (for instance following PHY auto-negociation).
95406 + *
95407 + * Returns: 0 if successful, an error code otherwise.
95408 + */
95409 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
95410 + enum enet_interface iface_mode,
95411 + enum enet_speed speed, bool full_dx);
95412 +
95413 +/**
95414 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
95415 + * @regs: Pointer to dTSEC register block
95416 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
95417 + *
95418 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
95419 + * so that the associated TBI PHY (i.e. the link) may be initialized.
95420 + *
95421 + * Returns: 0 if successful, an error code otherwise.
95422 + */
95423 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
95424 + uint8_t addr);
95425 +
95426 +/**
95427 + * fman_dtsec_set_max_frame_len() - Set max frame length
95428 + * @regs: Pointer to dTSEC register block
95429 + * @length: Max frame length.
95430 + *
95431 + * Sets maximum frame length for received and transmitted frames. Frames that
95432 + * exceeds this length are truncated.
95433 + */
95434 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
95435 +
95436 +/**
95437 + * fman_dtsec_get_max_frame_len() - Query max frame length
95438 + * @regs: Pointer to dTSEC register block
95439 + *
95440 + * Returns: the current value of the maximum frame length.
95441 + */
95442 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
95443 +
95444 +/**
95445 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
95446 + * @regs: Pointer to dTSEC register block
95447 + * @en: Enable pause frame handling in dTSEC
95448 + *
95449 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
95450 + * if dTSEC is set in half-duplex mode.
95451 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
95452 + * frames will be transferred to the packet interface just like regular Ethernet
95453 + * frames.
95454 + */
95455 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
95456 +
95457 +/**
95458 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
95459 + * @regs: Pointer to dTSEC register block
95460 + * @time: Time value included in pause frames
95461 + *
95462 + * Call this function to set the time value used in transmitted pause frames.
95463 + * If time is 0, transmission of pause frames is disabled
95464 + */
95465 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
95466 +
95467 +/**
95468 + * fman_dtsec_ack_event() - Acknowledge handled events
95469 + * @regs: Pointer to dTSEC register block
95470 + * @ev_mask: Events to acknowledge
95471 + *
95472 + * After handling events signaled by dTSEC in either polling or interrupt mode,
95473 + * call this function to reset the associated status bits in dTSEC event
95474 + * register.
95475 + */
95476 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
95477 +
95478 +/**
95479 + * fman_dtsec_get_event() - Returns currently asserted events
95480 + * @regs: Pointer to dTSEC register block
95481 + * @ev_mask: Mask of relevant events
95482 + *
95483 + * Call this function to obtain a bit-mask of events that are currently asserted
95484 + * in dTSEC, taken from IEVENT register.
95485 + *
95486 + * Returns: a bit-mask of events asserted in dTSEC.
95487 + */
95488 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
95489 +
95490 +/**
95491 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
95492 + * @regs: Pointer to dTSEC register block
95493 + *
95494 + * Call this function to obtain a bit-mask of enabled interrupts
95495 + * in dTSEC, taken from IMASK register.
95496 + *
95497 + * Returns: a bit-mask of enabled interrupts in dTSEC.
95498 + */
95499 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
95500 +
95501 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
95502 + uint8_t paddr_num);
95503 +
95504 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
95505 + uint64_t addr,
95506 + uint8_t paddr_num);
95507 +
95508 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
95509 +
95510 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
95511 +
95512 +/**
95513 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
95514 + * @regs: Pointer to dTSEC register block
95515 + * @ev_mask: Mask of relevant events
95516 + *
95517 + * Call this function to disable interrupts in dTSEC for the specified events.
95518 + * To enable interrupts use fman_dtsec_enable_interrupt().
95519 + */
95520 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
95521 +
95522 +/**
95523 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
95524 + * @regs: Pointer to dTSEC register block
95525 + * @ev_mask: Mask of relevant events
95526 + *
95527 + * Call this function to enable interrupts in dTSEC for the specified events.
95528 + * To disable interrupts use fman_dtsec_disable_interrupt().
95529 + */
95530 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
95531 +
95532 +/**
95533 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
95534 + * @regs: Pointer to dTSEC register block
95535 + * @en: true to enable timestamps, false to disable them
95536 + *
95537 + * Call this function to enable/disable dTSEC timestamps. This affects both
95538 + * Tx and Rx.
95539 + */
95540 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
95541 +
95542 +/**
95543 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
95544 + * @regs: Pointer to dTSEC register block
95545 + * @bucket: Bucket index
95546 + * @enable: true/false to enable/disable this bucket
95547 + *
95548 + * This function enables or disables the specified bucket. Enabling a bucket
95549 + * associated with an address configures dTSEC to accept received packets
95550 + * with that destination address.
95551 + * Multiple addresses may be associated with the same bucket. Disabling a
95552 + * bucket will affect all addresses associated with that bucket. A bucket that
95553 + * is enabled requires further filtering and verification in the upper layers
95554 + *
95555 + */
95556 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
95557 +
95558 +/**
95559 + * dtsec_set_hash_table() - insert a crc code into thr filter table
95560 + * @regs: Pointer to dTSEC register block
95561 + * @crc: crc to insert
95562 + * @mcast: true is this is a multicast address
95563 + * @ghtx: true if we are in ghtx mode
95564 + *
95565 + * This function inserts a crc code into the filter table.
95566 + */
95567 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
95568 + bool mcast, bool ghtx);
95569 +
95570 +/**
95571 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
95572 + * @regs: Pointer to dTSEC register block
95573 + * @mcast: Reset multicast entries
95574 + * @ucast: Reset unicast entries
95575 + *
95576 + * Resets all entries in L2 address filter table. After calling this function
95577 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
95578 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
95579 + * @ucast argument is ignored.
95580 + * This does not affect the primary nor the 15 additional addresses configured
95581 + * using dtsec_set_address() or dtsec_set_match_address().
95582 + */
95583 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
95584 + bool ucast);
95585 +
95586 +/**
95587 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
95588 + * @regs: Pointer to dTSEC register block
95589 + * @enable: Enable multicast promiscuous mode
95590 + *
95591 + * Call this to enable/disable L2 address filtering for multicast packets.
95592 + */
95593 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
95594 +
95595 +/* statistics APIs */
95596 +
95597 +/**
95598 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
95599 + * @regs: Pointer to dTSEC register block
95600 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
95601 + * to specify all the existing counters.
95602 + * If set to _none_, it disables all the counters.
95603 + *
95604 + * Enables the MIB statistics hw counters and sets up the carry interrupt
95605 + * masks for the counters corresponding to the @level input parameter.
95606 + *
95607 + * Returns: error if invalid @level value given.
95608 + */
95609 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
95610 + enum dtsec_stat_level level);
95611 +
95612 +/**
95613 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
95614 + * @regs: Pointer to dTSEC register block
95615 + */
95616 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
95617 +
95618 +/**
95619 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
95620 + * @regs: Pointer to dTSEC register block
95621 + * @car1: car1 register value
95622 + * @car2: car2 register value
95623 + *
95624 + * When set, the carry bits signal that an overflow occurred on the
95625 + * corresponding counters.
95626 + * Note that the carry bits (CAR1-2 registers) will assert the
95627 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
95628 + *
95629 + * Returns: true if overflow occurred, otherwise - false
95630 + */
95631 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
95632 + uint32_t *car1, uint32_t *car2);
95633 +
95634 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
95635 +
95636 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
95637 + enum dtsec_stat_counters reg_name);
95638 +
95639 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
95640 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
95641 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
95642 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
95643 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
95644 +
95645 +
95646 +#endif /* __FSL_FMAN_DTSEC_H */
95647 --- /dev/null
95648 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
95649 @@ -0,0 +1,107 @@
95650 +/*
95651 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95652 + *
95653 + * Redistribution and use in source and binary forms, with or without
95654 + * modification, are permitted provided that the following conditions are met:
95655 + * * Redistributions of source code must retain the above copyright
95656 + * notice, this list of conditions and the following disclaimer.
95657 + * * Redistributions in binary form must reproduce the above copyright
95658 + * notice, this list of conditions and the following disclaimer in the
95659 + * documentation and/or other materials provided with the distribution.
95660 + * * Neither the name of Freescale Semiconductor nor the
95661 + * names of its contributors may be used to endorse or promote products
95662 + * derived from this software without specific prior written permission.
95663 + *
95664 + *
95665 + * ALTERNATIVELY, this software may be distributed under the terms of the
95666 + * GNU General Public License ("GPL") as published by the Free Software
95667 + * Foundation, either version 2 of that License or (at your option) any
95668 + * later version.
95669 + *
95670 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95671 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95672 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95673 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95674 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95675 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95676 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95677 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95678 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95679 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95680 + */
95681 +
95682 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
95683 +#define __FSL_FMAN_DTSEC_MII_ACC_H
95684 +
95685 +#include "common/general.h"
95686 +
95687 +
95688 +/* MII Management Configuration Register */
95689 +#define MIIMCFG_RESET_MGMT 0x80000000
95690 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
95691 +#define MIIMCFG_MGNTCLK_SHIFT 0
95692 +
95693 +/* MII Management Command Register */
95694 +#define MIIMCOM_SCAN_CYCLE 0x00000002
95695 +#define MIIMCOM_READ_CYCLE 0x00000001
95696 +
95697 +/* MII Management Address Register */
95698 +#define MIIMADD_PHY_ADDR_SHIFT 8
95699 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
95700 +
95701 +#define MIIMADD_REG_ADDR_SHIFT 0
95702 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
95703 +
95704 +/* MII Management Indicator Register */
95705 +#define MIIMIND_BUSY 0x00000001
95706 +
95707 +
95708 +/* PHY Control Register */
95709 +#define PHY_CR_PHY_RESET 0x8000
95710 +#define PHY_CR_LOOPBACK 0x4000
95711 +#define PHY_CR_SPEED0 0x2000
95712 +#define PHY_CR_ANE 0x1000
95713 +#define PHY_CR_RESET_AN 0x0200
95714 +#define PHY_CR_FULLDUPLEX 0x0100
95715 +#define PHY_CR_SPEED1 0x0040
95716 +
95717 +#define PHY_TBICON_SRESET 0x8000
95718 +#define PHY_TBICON_SPEED2 0x0020
95719 +#define PHY_TBICON_CLK_SEL 0x0020
95720 +#define PHY_TBIANA_SGMII 0x4001
95721 +#define PHY_TBIANA_1000X 0x01a0
95722 +/* register map */
95723 +
95724 +/* MII Configuration Control Memory Map Registers */
95725 +struct dtsec_mii_reg {
95726 + uint32_t reserved1[72];
95727 + uint32_t miimcfg; /* MII Mgmt:configuration */
95728 + uint32_t miimcom; /* MII Mgmt:command */
95729 + uint32_t miimadd; /* MII Mgmt:address */
95730 + uint32_t miimcon; /* MII Mgmt:control 3 */
95731 + uint32_t miimstat; /* MII Mgmt:status */
95732 + uint32_t miimind; /* MII Mgmt:indicators */
95733 +};
95734 +
95735 +/* dTSEC MII API */
95736 +
95737 +/* functions to access the mii registers for phy configuration.
95738 + * this functionality may not be available for all dtsecs in the system.
95739 + * consult the reference manual for details */
95740 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
95741 +/* frequency is in MHz.
95742 + * note that dtsec clock is 1/2 of fman clock */
95743 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
95744 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
95745 + uint8_t addr,
95746 + uint8_t reg,
95747 + uint16_t data,
95748 + uint16_t dtsec_freq);
95749 +
95750 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
95751 + uint8_t addr,
95752 + uint8_t reg,
95753 + uint16_t *data,
95754 + uint16_t dtsec_freq);
95755 +
95756 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
95757 --- /dev/null
95758 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
95759 @@ -0,0 +1,514 @@
95760 +/*
95761 + * Copyright 2008-2012 Freescale Semiconductor Inc.
95762 + *
95763 + * Redistribution and use in source and binary forms, with or without
95764 + * modification, are permitted provided that the following conditions are met:
95765 + * * Redistributions of source code must retain the above copyright
95766 + * notice, this list of conditions and the following disclaimer.
95767 + * * Redistributions in binary form must reproduce the above copyright
95768 + * notice, this list of conditions and the following disclaimer in the
95769 + * documentation and/or other materials provided with the distribution.
95770 + * * Neither the name of Freescale Semiconductor nor the
95771 + * names of its contributors may be used to endorse or promote products
95772 + * derived from this software without specific prior written permission.
95773 + *
95774 + *
95775 + * ALTERNATIVELY, this software may be distributed under the terms of the
95776 + * GNU General Public License ("GPL") as published by the Free Software
95777 + * Foundation, either version 2 of that License or (at your option) any
95778 + * later version.
95779 + *
95780 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95781 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95782 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95783 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95784 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95785 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95786 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95787 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95788 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95789 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95790 + */
95791 +
95792 +#ifndef __FSL_FMAN_KG_H
95793 +#define __FSL_FMAN_KG_H
95794 +
95795 +#include "common/general.h"
95796 +
95797 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
95798 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
95799 +/**< Total num of masks allowed on KG extractions */
95800 +#define FM_KG_EXTRACT_MASKS_NUM 4
95801 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
95802 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
95803 +
95804 +struct fman_kg_regs {
95805 + uint32_t fmkg_gcr;
95806 + uint32_t res004;
95807 + uint32_t res008;
95808 + uint32_t fmkg_eer;
95809 + uint32_t fmkg_eeer;
95810 + uint32_t res014;
95811 + uint32_t res018;
95812 + uint32_t fmkg_seer;
95813 + uint32_t fmkg_seeer;
95814 + uint32_t fmkg_gsr;
95815 + uint32_t fmkg_tpc;
95816 + uint32_t fmkg_serc;
95817 + uint32_t res030[4];
95818 + uint32_t fmkg_fdor;
95819 + uint32_t fmkg_gdv0r;
95820 + uint32_t fmkg_gdv1r;
95821 + uint32_t res04c[6];
95822 + uint32_t fmkg_feer;
95823 + uint32_t res068[38];
95824 + uint32_t fmkg_indirect[63];
95825 + uint32_t fmkg_ar;
95826 +};
95827 +
95828 +struct fman_kg_scheme_regs {
95829 + uint32_t kgse_mode; /**< MODE */
95830 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
95831 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
95832 + uint32_t kgse_bmch; /**< Bit Mask Command High */
95833 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
95834 + uint32_t kgse_fqb; /**< Frame Queue Base */
95835 + uint32_t kgse_hc; /**< Hash Command */
95836 + uint32_t kgse_ppc; /**< Policer Profile Command */
95837 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
95838 + /**< Generic Extract Command */
95839 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
95840 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
95841 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
95842 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
95843 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
95844 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
95845 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
95846 +};
95847 +
95848 +struct fman_kg_pe_regs{
95849 + uint32_t fmkg_pe_sp;
95850 + uint32_t fmkg_pe_cpp;
95851 +};
95852 +
95853 +struct fman_kg_cp_regs {
95854 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
95855 +};
95856 +
95857 +
95858 +#define FM_KG_KGAR_GO 0x80000000
95859 +#define FM_KG_KGAR_READ 0x40000000
95860 +#define FM_KG_KGAR_WRITE 0x00000000
95861 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
95862 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
95863 +
95864 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
95865 +#define KG_SCH_PP_NO_GEN 0x10000000
95866 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
95867 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
95868 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
95869 +#define KG_SCH_BITMASK_MASK 0x000000FF
95870 +#define KG_SCH_GEN_VALID 0x80000000
95871 +#define KG_SCH_GEN_MASK 0x00FF0000
95872 +#define FM_PCD_KG_KGAR_ERR 0x20000000
95873 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
95874 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
95875 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
95876 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
95877 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
95878 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
95879 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
95880 +
95881 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
95882 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
95883 +
95884 +/* ECC capture register */
95885 +#define KG_FMKG_SERC_CAP 0x80000000
95886 +#define KG_FMKG_SERC_CET 0x40000000
95887 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
95888 +#define KG_FMKG_SERC_CNT_SHIFT 16
95889 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
95890 +
95891 +/* Masks */
95892 +#define FM_KG_KGGCR_EN 0x80000000
95893 +#define KG_SCH_GEN_VALID 0x80000000
95894 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
95895 +#define KG_ERR_TYPE_DOUBLE 0x40000000
95896 +#define KG_ERR_ADDR_MASK 0x00000FFF
95897 +#define KG_SCH_MODE_EN 0x80000000
95898 +
95899 +/* shifts */
95900 +#define FM_KG_KGAR_NUM_SHIFT 16
95901 +#define FM_KG_PE_CPP_MASK_SHIFT 16
95902 +#define FM_KG_KGAR_WSEL_SHIFT 8
95903 +
95904 +#define FM_KG_SCH_GEN_HT_INVALID 0
95905 +
95906 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
95907 +
95908 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
95909 +switch (i) \
95910 +{ \
95911 + case 0: (shift) = 26; break; \
95912 + case 1: (shift) = 20; break; \
95913 + case 2: (shift) = 10; break; \
95914 + case 3: (shift) = 4; break; \
95915 + default: (shift) = 0; \
95916 +}
95917 +
95918 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
95919 +switch (i) \
95920 +{ \
95921 + case 0: (shift) = 16; break; \
95922 + case 1: (shift) = 0; break; \
95923 + case 2: (shift) = 28; break; \
95924 + case 3: (shift) = 24; break; \
95925 + default: (shift) = 0; \
95926 +}
95927 +
95928 +#define KG_GET_MASK_SHIFT(shift, i) \
95929 +switch (i) \
95930 +{ \
95931 + case 0: shift = 24; break; \
95932 + case 1: shift = 16; break; \
95933 + case 2: shift = 8; break; \
95934 + case 3: shift = 0; break; \
95935 + default: shift = 0; \
95936 +}
95937 +
95938 +/* Port entry CPP register */
95939 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
95940 +
95941 +/* Scheme registers */
95942 +#define FMAN_KG_SCH_MODE_EN 0x80000000
95943 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
95944 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
95945 +
95946 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
95947 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
95948 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
95949 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
95950 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
95951 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
95952 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
95953 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
95954 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
95955 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
95956 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
95957 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
95958 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
95959 +
95960 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
95961 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
95962 +#define FMAN_KG_SCH_GEN_OR 0x00008000
95963 +
95964 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
95965 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
95966 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
95967 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
95968 +
95969 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
95970 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
95971 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
95972 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
95973 +
95974 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
95975 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
95976 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
95977 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
95978 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
95979 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
95980 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
95981 +
95982 +enum fman_kg_gen_extract_src {
95983 + E_FMAN_KG_GEN_EXTRACT_ETH,
95984 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
95985 + E_FMAN_KG_GEN_EXTRACT_SNAP,
95986 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
95987 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
95988 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
95989 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
95990 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
95991 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
95992 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
95993 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
95994 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
95995 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
95996 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
95997 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
95998 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
95999 + E_FMAN_KG_GEN_EXTRACT_GRE,
96000 + E_FMAN_KG_GEN_EXTRACT_TCP,
96001 + E_FMAN_KG_GEN_EXTRACT_UDP,
96002 + E_FMAN_KG_GEN_EXTRACT_SCTP,
96003 + E_FMAN_KG_GEN_EXTRACT_DCCP,
96004 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
96005 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
96006 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
96007 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
96008 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
96009 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
96010 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
96011 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
96012 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
96013 +};
96014 +
96015 +struct fman_kg_ex_ecc_attr
96016 +{
96017 + bool valid;
96018 + bool double_ecc;
96019 + uint16_t addr;
96020 + uint8_t single_ecc_count;
96021 +};
96022 +
96023 +enum fman_kg_def_select
96024 +{
96025 + E_FMAN_KG_DEF_GLOBAL_0,
96026 + E_FMAN_KG_DEF_GLOBAL_1,
96027 + E_FMAN_KG_DEF_SCHEME_0,
96028 + E_FMAN_KG_DEF_SCHEME_1
96029 +};
96030 +
96031 +struct fman_kg_extract_def
96032 +{
96033 + enum fman_kg_def_select mac_addr;
96034 + enum fman_kg_def_select vlan_tci;
96035 + enum fman_kg_def_select etype;
96036 + enum fman_kg_def_select ppp_sid;
96037 + enum fman_kg_def_select ppp_pid;
96038 + enum fman_kg_def_select mpls;
96039 + enum fman_kg_def_select ip_addr;
96040 + enum fman_kg_def_select ptype;
96041 + enum fman_kg_def_select ip_tos_tc;
96042 + enum fman_kg_def_select ipv6_fl;
96043 + enum fman_kg_def_select ipsec_spi;
96044 + enum fman_kg_def_select l4_port;
96045 + enum fman_kg_def_select tcp_flg;
96046 +};
96047 +
96048 +enum fman_kg_gen_extract_type
96049 +{
96050 + E_FMAN_KG_HASH_EXTRACT,
96051 + E_FMAN_KG_OR_EXTRACT
96052 +};
96053 +
96054 +struct fman_kg_gen_extract_params
96055 +{
96056 + /* Hash or Or-ed extract */
96057 + enum fman_kg_gen_extract_type type;
96058 + enum fman_kg_gen_extract_src src;
96059 + bool no_validation;
96060 + /* Extraction offset from the header location specified above */
96061 + uint8_t offset;
96062 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
96063 + * hash result shift for FMAN_KG_OR_EXTRACT */
96064 + uint8_t extract;
96065 + uint8_t mask;
96066 + /* Default value to use when header specified
96067 + * by fman_kg_gen_extract_src doesn't present */
96068 + enum fman_kg_def_select def_val;
96069 +};
96070 +
96071 +struct fman_kg_extract_mask
96072 +{
96073 + /**< Indication if mask is on known field extraction or
96074 + * on general extraction; TRUE for known field */
96075 + bool is_known;
96076 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
96077 + * generic register index for generic extracts mask */
96078 + uint32_t field_or_gen_idx;
96079 + /**< Byte offset from start of the extracted data specified
96080 + * by field_or_gen_idx */
96081 + uint8_t offset;
96082 + /**< Byte mask (selected bits will be used) */
96083 + uint8_t mask;
96084 +};
96085 +
96086 +struct fman_kg_extract_params
96087 +{
96088 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
96089 + uint32_t known_fields;
96090 + struct fman_kg_extract_def known_fields_def;
96091 + /* Number of entries in gen_extract */
96092 + uint8_t gen_extract_num;
96093 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
96094 + /* Number of entries in masks */
96095 + uint8_t masks_num;
96096 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
96097 + uint32_t def_scheme_0;
96098 + uint32_t def_scheme_1;
96099 +};
96100 +
96101 +struct fman_kg_hash_params
96102 +{
96103 + bool use_hash;
96104 + uint8_t shift_r;
96105 + uint32_t mask; /**< 24-bit mask */
96106 + bool sym; /**< Symmetric hash for src and dest pairs */
96107 +};
96108 +
96109 +struct fman_kg_pp_params
96110 +{
96111 + uint8_t base;
96112 + uint8_t shift;
96113 + uint8_t mask;
96114 + bool bypass_pp_gen;
96115 +};
96116 +
96117 +struct fman_kg_cc_params
96118 +{
96119 + uint8_t base_offset;
96120 + uint32_t qlcv_bits_sel;
96121 +};
96122 +
96123 +enum fman_pcd_engine
96124 +{
96125 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
96126 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
96127 + E_FMAN_PCD_KG, /**< Keygen indicated */
96128 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
96129 + E_FMAN_PCD_PLCR, /**< Policer indicated */
96130 + E_FMAN_PCD_PRS /**< Parser indicated */
96131 +};
96132 +
96133 +struct fman_kg_cls_plan_params
96134 +{
96135 + uint8_t entries_mask;
96136 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
96137 +};
96138 +
96139 +struct fman_kg_scheme_params
96140 +{
96141 + uint32_t match_vector;
96142 + struct fman_kg_extract_params extract_params;
96143 + struct fman_kg_hash_params hash_params;
96144 + uint32_t base_fqid;
96145 + /* What we do w/features supported per FM version ?? */
96146 + bool bypass_fqid_gen;
96147 + struct fman_kg_pp_params policer_params;
96148 + struct fman_kg_cc_params cc_params;
96149 + bool update_counter;
96150 + /**< counter_value: Set scheme counter to the specified value;
96151 + * relevant only when update_counter = TRUE. */
96152 + uint32_t counter_value;
96153 + enum fman_pcd_engine next_engine;
96154 + /**< Next engine action code */
96155 + uint32_t next_engine_action;
96156 +};
96157 +
96158 +
96159 +
96160 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
96161 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
96162 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
96163 +void fman_kg_get_event(struct fman_kg_regs *regs,
96164 + uint32_t *event,
96165 + uint32_t *scheme_idx);
96166 +void fman_kg_init(struct fman_kg_regs *regs,
96167 + uint32_t exceptions,
96168 + uint32_t dflt_nia);
96169 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
96170 +void fman_kg_enable(struct fman_kg_regs *regs);
96171 +void fman_kg_disable(struct fman_kg_regs *regs);
96172 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
96173 + uint8_t hwport_id,
96174 + uint32_t bind_cls_plans);
96175 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
96176 + uint8_t grp_mask,
96177 + uint32_t *bind_cls_plans);
96178 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
96179 + uint8_t hwport_id,
96180 + uint32_t schemes);
96181 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
96182 + uint8_t grp_id,
96183 + uint8_t entries_mask,
96184 + uint8_t hwport_id,
96185 + struct fman_kg_cp_regs *cls_plan_regs);
96186 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
96187 + struct fman_kg_cp_regs *cls_plan_regs);
96188 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
96189 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
96190 + uint8_t scheme_id,
96191 + uint8_t hwport_id,
96192 + uint32_t counter);
96193 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
96194 + uint8_t scheme_id,
96195 + uint8_t hwport_id,
96196 + uint32_t *counter);
96197 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
96198 + uint8_t scheme_id,
96199 + uint8_t hwport_id);
96200 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
96201 + uint8_t scheme_id,
96202 + uint8_t hwport_id,
96203 + struct fman_kg_scheme_regs *scheme_regs,
96204 + bool update_counter);
96205 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
96206 + struct fman_kg_scheme_regs *scheme_regs);
96207 +void fman_kg_get_capture(struct fman_kg_regs *regs,
96208 + struct fman_kg_ex_ecc_attr *ecc_attr,
96209 + bool clear);
96210 +void fman_kg_get_exception(struct fman_kg_regs *regs,
96211 + uint32_t *events,
96212 + uint32_t *scheme_ids,
96213 + bool clear);
96214 +void fman_kg_set_exception(struct fman_kg_regs *regs,
96215 + uint32_t exception,
96216 + bool enable);
96217 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
96218 + uint8_t def_id,
96219 + uint32_t val);
96220 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
96221 +
96222 +
96223 +
96224 +/**************************************************************************//**
96225 + @Description NIA Description
96226 +*//***************************************************************************/
96227 +#define KG_NIA_ORDER_RESTOR 0x00800000
96228 +#define KG_NIA_ENG_FM_CTL 0x00000000
96229 +#define KG_NIA_ENG_PRS 0x00440000
96230 +#define KG_NIA_ENG_KG 0x00480000
96231 +#define KG_NIA_ENG_PLCR 0x004C0000
96232 +#define KG_NIA_ENG_BMI 0x00500000
96233 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
96234 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
96235 +#define KG_NIA_ENG_MASK 0x007C0000
96236 +
96237 +#define KG_NIA_AC_MASK 0x0003FFFF
96238 +
96239 +#define KG_NIA_INVALID 0xFFFFFFFF
96240 +
96241 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
96242 + uint32_t next_engine_action)
96243 +{
96244 + uint32_t nia;
96245 +
96246 + if (next_engine_action & ~KG_NIA_AC_MASK)
96247 + return KG_NIA_INVALID;
96248 +
96249 + switch (next_engine) {
96250 + case E_FMAN_PCD_DONE:
96251 + nia = KG_NIA_ENG_BMI | next_engine_action;
96252 + break;
96253 +
96254 + case E_FMAN_PCD_KG:
96255 + nia = KG_NIA_ENG_KG | next_engine_action;
96256 + break;
96257 +
96258 + case E_FMAN_PCD_CC:
96259 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
96260 + break;
96261 +
96262 + case E_FMAN_PCD_PLCR:
96263 + nia = KG_NIA_ENG_PLCR | next_engine_action;
96264 + break;
96265 +
96266 + default:
96267 + nia = KG_NIA_INVALID;
96268 + }
96269 +
96270 + return nia;
96271 +}
96272 +
96273 +#endif /* __FSL_FMAN_KG_H */
96274 --- /dev/null
96275 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
96276 @@ -0,0 +1,434 @@
96277 +/*
96278 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96279 + *
96280 + * Redistribution and use in source and binary forms, with or without
96281 + * modification, are permitted provided that the following conditions are met:
96282 + * * Redistributions of source code must retain the above copyright
96283 + * notice, this list of conditions and the following disclaimer.
96284 + * * Redistributions in binary form must reproduce the above copyright
96285 + * notice, this list of conditions and the following disclaimer in the
96286 + * documentation and/or other materials provided with the distribution.
96287 + * * Neither the name of Freescale Semiconductor nor the
96288 + * names of its contributors may be used to endorse or promote products
96289 + * derived from this software without specific prior written permission.
96290 + *
96291 + *
96292 + * ALTERNATIVELY, this software may be distributed under the terms of the
96293 + * GNU General Public License ("GPL") as published by the Free Software
96294 + * Foundation, either version 2 of that License or (at your option) any
96295 + * later version.
96296 + *
96297 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96298 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96299 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96300 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96301 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96302 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96303 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96304 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96305 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96306 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96307 + */
96308 +
96309 +
96310 +#ifndef __FSL_FMAN_MEMAC_H
96311 +#define __FSL_FMAN_MEMAC_H
96312 +
96313 +#include "common/general.h"
96314 +#include "fsl_enet.h"
96315 +
96316 +
96317 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
96318 +
96319 +/* Control and Configuration Register (COMMAND_CONFIG) */
96320 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
96321 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
96322 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
96323 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
96324 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
96325 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
96326 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
96327 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
96328 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
96329 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
96330 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
96331 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
96332 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
96333 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
96334 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
96335 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
96336 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
96337 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
96338 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
96339 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
96340 +
96341 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
96342 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
96343 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
96344 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
96345 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
96346 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
96347 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
96348 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
96349 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
96350 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
96351 +
96352 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
96353 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
96354 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
96355 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
96356 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
96357 +
96358 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
96359 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
96360 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
96361 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
96362 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
96363 +
96364 +/* Interface Mode Register (IF_MODE) */
96365 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
96366 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
96367 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
96368 +#define IF_MODE_RGMII 0x00000004
96369 +#define IF_MODE_RGMII_AUTO 0x00008000
96370 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
96371 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
96372 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
96373 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
96374 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
96375 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
96376 +
96377 +/* Hash table Control Register (HASHTABLE_CTRL) */
96378 +#define HASH_CTRL_MCAST_SHIFT 26
96379 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
96380 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
96381 +
96382 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
96383 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
96384 +
96385 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96386 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
96387 +
96388 +/* Statistics Configuration Register (STATN_CONFIG) */
96389 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
96390 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
96391 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
96392 +
96393 +/* Interrupt Mask Register (IMASK) */
96394 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
96395 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
96396 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
96397 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
96398 +
96399 +#define MEMAC_ALL_ERRS_IMASK \
96400 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
96401 + MEMAC_IMASK_TECC_ER | \
96402 + MEMAC_IMASK_RECC_ER | \
96403 + MEMAC_IMASK_MGI))
96404 +
96405 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
96406 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
96407 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
96408 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
96409 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
96410 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
96411 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
96412 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
96413 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
96414 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
96415 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
96416 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
96417 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
96418 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
96419 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
96420 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
96421 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
96422 +
96423 +enum memac_counters {
96424 + E_MEMAC_COUNTER_R64,
96425 + E_MEMAC_COUNTER_T64,
96426 + E_MEMAC_COUNTER_R127,
96427 + E_MEMAC_COUNTER_T127,
96428 + E_MEMAC_COUNTER_R255,
96429 + E_MEMAC_COUNTER_T255,
96430 + E_MEMAC_COUNTER_R511,
96431 + E_MEMAC_COUNTER_T511,
96432 + E_MEMAC_COUNTER_R1023,
96433 + E_MEMAC_COUNTER_T1023,
96434 + E_MEMAC_COUNTER_R1518,
96435 + E_MEMAC_COUNTER_T1518,
96436 + E_MEMAC_COUNTER_R1519X,
96437 + E_MEMAC_COUNTER_T1519X,
96438 + E_MEMAC_COUNTER_RFRG,
96439 + E_MEMAC_COUNTER_RJBR,
96440 + E_MEMAC_COUNTER_RDRP,
96441 + E_MEMAC_COUNTER_RALN,
96442 + E_MEMAC_COUNTER_TUND,
96443 + E_MEMAC_COUNTER_ROVR,
96444 + E_MEMAC_COUNTER_RXPF,
96445 + E_MEMAC_COUNTER_TXPF,
96446 + E_MEMAC_COUNTER_ROCT,
96447 + E_MEMAC_COUNTER_RMCA,
96448 + E_MEMAC_COUNTER_RBCA,
96449 + E_MEMAC_COUNTER_RPKT,
96450 + E_MEMAC_COUNTER_RUCA,
96451 + E_MEMAC_COUNTER_RERR,
96452 + E_MEMAC_COUNTER_TOCT,
96453 + E_MEMAC_COUNTER_TMCA,
96454 + E_MEMAC_COUNTER_TBCA,
96455 + E_MEMAC_COUNTER_TUCA,
96456 + E_MEMAC_COUNTER_TERR
96457 +};
96458 +
96459 +#define DEFAULT_PAUSE_QUANTA 0xf000
96460 +#define DEFAULT_FRAME_LENGTH 0x600
96461 +#define DEFAULT_TX_IPG_LENGTH 12
96462 +
96463 +/*
96464 + * memory map
96465 + */
96466 +
96467 +struct mac_addr {
96468 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
96469 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
96470 +};
96471 +
96472 +struct memac_regs {
96473 + /* General Control and Status */
96474 + uint32_t res0000[2];
96475 + uint32_t command_config; /* 0x008 Ctrl and cfg */
96476 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
96477 + uint32_t maxfrm; /* 0x014 Max frame length */
96478 + uint32_t res0018[1];
96479 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
96480 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
96481 + uint32_t res0024[2];
96482 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
96483 + uint32_t res0030[4];
96484 + uint32_t ievent; /* 0x040 Interrupt event */
96485 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
96486 + uint32_t res0048;
96487 + uint32_t imask; /* 0x04C Interrupt mask */
96488 + uint32_t res0050;
96489 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
96490 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
96491 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
96492 + uint32_t res0078[2];
96493 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
96494 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
96495 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
96496 + uint32_t res00c0[8];
96497 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
96498 + uint32_t res00e4[7];
96499 + /* Rx Statistics Counter */
96500 + uint32_t reoct_l;
96501 + uint32_t reoct_u;
96502 + uint32_t roct_l;
96503 + uint32_t roct_u;
96504 + uint32_t raln_l;
96505 + uint32_t raln_u;
96506 + uint32_t rxpf_l;
96507 + uint32_t rxpf_u;
96508 + uint32_t rfrm_l;
96509 + uint32_t rfrm_u;
96510 + uint32_t rfcs_l;
96511 + uint32_t rfcs_u;
96512 + uint32_t rvlan_l;
96513 + uint32_t rvlan_u;
96514 + uint32_t rerr_l;
96515 + uint32_t rerr_u;
96516 + uint32_t ruca_l;
96517 + uint32_t ruca_u;
96518 + uint32_t rmca_l;
96519 + uint32_t rmca_u;
96520 + uint32_t rbca_l;
96521 + uint32_t rbca_u;
96522 + uint32_t rdrp_l;
96523 + uint32_t rdrp_u;
96524 + uint32_t rpkt_l;
96525 + uint32_t rpkt_u;
96526 + uint32_t rund_l;
96527 + uint32_t rund_u;
96528 + uint32_t r64_l;
96529 + uint32_t r64_u;
96530 + uint32_t r127_l;
96531 + uint32_t r127_u;
96532 + uint32_t r255_l;
96533 + uint32_t r255_u;
96534 + uint32_t r511_l;
96535 + uint32_t r511_u;
96536 + uint32_t r1023_l;
96537 + uint32_t r1023_u;
96538 + uint32_t r1518_l;
96539 + uint32_t r1518_u;
96540 + uint32_t r1519x_l;
96541 + uint32_t r1519x_u;
96542 + uint32_t rovr_l;
96543 + uint32_t rovr_u;
96544 + uint32_t rjbr_l;
96545 + uint32_t rjbr_u;
96546 + uint32_t rfrg_l;
96547 + uint32_t rfrg_u;
96548 + uint32_t rcnp_l;
96549 + uint32_t rcnp_u;
96550 + uint32_t rdrntp_l;
96551 + uint32_t rdrntp_u;
96552 + uint32_t res01d0[12];
96553 + /* Tx Statistics Counter */
96554 + uint32_t teoct_l;
96555 + uint32_t teoct_u;
96556 + uint32_t toct_l;
96557 + uint32_t toct_u;
96558 + uint32_t res0210[2];
96559 + uint32_t txpf_l;
96560 + uint32_t txpf_u;
96561 + uint32_t tfrm_l;
96562 + uint32_t tfrm_u;
96563 + uint32_t tfcs_l;
96564 + uint32_t tfcs_u;
96565 + uint32_t tvlan_l;
96566 + uint32_t tvlan_u;
96567 + uint32_t terr_l;
96568 + uint32_t terr_u;
96569 + uint32_t tuca_l;
96570 + uint32_t tuca_u;
96571 + uint32_t tmca_l;
96572 + uint32_t tmca_u;
96573 + uint32_t tbca_l;
96574 + uint32_t tbca_u;
96575 + uint32_t res0258[2];
96576 + uint32_t tpkt_l;
96577 + uint32_t tpkt_u;
96578 + uint32_t tund_l;
96579 + uint32_t tund_u;
96580 + uint32_t t64_l;
96581 + uint32_t t64_u;
96582 + uint32_t t127_l;
96583 + uint32_t t127_u;
96584 + uint32_t t255_l;
96585 + uint32_t t255_u;
96586 + uint32_t t511_l;
96587 + uint32_t t511_u;
96588 + uint32_t t1023_l;
96589 + uint32_t t1023_u;
96590 + uint32_t t1518_l;
96591 + uint32_t t1518_u;
96592 + uint32_t t1519x_l;
96593 + uint32_t t1519x_u;
96594 + uint32_t res02a8[6];
96595 + uint32_t tcnp_l;
96596 + uint32_t tcnp_u;
96597 + uint32_t res02c8[14];
96598 + /* Line Interface Control */
96599 + uint32_t if_mode; /* 0x300 Interface Mode Control */
96600 + uint32_t if_status; /* 0x304 Interface Status */
96601 + uint32_t res0308[14];
96602 + /* HiGig/2 */
96603 + uint32_t hg_config; /* 0x340 Control and cfg */
96604 + uint32_t res0344[3];
96605 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
96606 + uint32_t res0354[3];
96607 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
96608 + uint32_t res0364[3];
96609 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
96610 + uint32_t hg_fifos_status; /* 0x374 fifos status */
96611 + uint32_t rhm; /* 0x378 rx messages counter */
96612 + uint32_t thm; /* 0x37C tx messages counter */
96613 +};
96614 +
96615 +struct memac_cfg {
96616 + bool reset_on_init;
96617 + bool rx_error_discard;
96618 + bool pause_ignore;
96619 + bool pause_forward_enable;
96620 + bool no_length_check_enable;
96621 + bool cmd_frame_enable;
96622 + bool send_idle_enable;
96623 + bool wan_mode_enable;
96624 + bool promiscuous_mode_enable;
96625 + bool tx_addr_ins_enable;
96626 + bool loopback_enable;
96627 + bool lgth_check_nostdr;
96628 + bool time_stamp_enable;
96629 + bool pad_enable;
96630 + bool phy_tx_ena_on;
96631 + bool rx_sfd_any;
96632 + bool rx_pbl_fwd;
96633 + bool tx_pbl_fwd;
96634 + bool debug_mode;
96635 + bool wake_on_lan;
96636 + uint16_t max_frame_length;
96637 + uint16_t pause_quanta;
96638 + uint32_t tx_ipg_length;
96639 +};
96640 +
96641 +
96642 +/**
96643 + * fman_memac_defconfig() - Get default MEMAC configuration
96644 + * @cfg: pointer to configuration structure.
96645 + *
96646 + * Call this function to obtain a default set of configuration values for
96647 + * initializing MEMAC. The user can overwrite any of the values before calling
96648 + * fman_memac_init(), if specific configuration needs to be applied.
96649 + */
96650 +void fman_memac_defconfig(struct memac_cfg *cfg);
96651 +
96652 +int fman_memac_init(struct memac_regs *regs,
96653 + struct memac_cfg *cfg,
96654 + enum enet_interface enet_interface,
96655 + enum enet_speed enet_speed,
96656 + bool slow_10g_if,
96657 + uint32_t exceptions);
96658 +
96659 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
96660 +
96661 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
96662 +
96663 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
96664 +
96665 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
96666 + uint8_t *adr,
96667 + uint8_t paddr_num);
96668 +
96669 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
96670 + uint8_t paddr_num);
96671 +
96672 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
96673 + enum memac_counters reg_name);
96674 +
96675 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
96676 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
96677 +
96678 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
96679 +
96680 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
96681 + bool enable);
96682 +
96683 +void fman_memac_reset_stat(struct memac_regs *regs);
96684 +
96685 +void fman_memac_reset(struct memac_regs *regs);
96686 +
96687 +void fman_memac_reset_filter_table(struct memac_regs *regs);
96688 +
96689 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
96690 +
96691 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
96692 +
96693 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
96694 + bool enable);
96695 +
96696 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
96697 +
96698 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
96699 +
96700 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
96701 +
96702 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
96703 +
96704 +void fman_memac_adjust_link(struct memac_regs *regs,
96705 + enum enet_interface iface_mode,
96706 + enum enet_speed speed, bool full_dx);
96707 +
96708 +
96709 +
96710 +#endif /*__FSL_FMAN_MEMAC_H*/
96711 --- /dev/null
96712 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
96713 @@ -0,0 +1,78 @@
96714 +/*
96715 + * Copyright 2008-2013 Freescale Semiconductor Inc.
96716 + *
96717 + * Redistribution and use in source and binary forms, with or without
96718 + * modification, are permitted provided that the following conditions are met:
96719 + * * Redistributions of source code must retain the above copyright
96720 + * notice, this list of conditions and the following disclaimer.
96721 + * * Redistributions in binary form must reproduce the above copyright
96722 + * notice, this list of conditions and the following disclaimer in the
96723 + * documentation and/or other materials provided with the distribution.
96724 + * * Neither the name of Freescale Semiconductor nor the
96725 + * names of its contributors may be used to endorse or promote products
96726 + * derived from this software without specific prior written permission.
96727 + *
96728 + *
96729 + * ALTERNATIVELY, this software may be distributed under the terms of the
96730 + * GNU General Public License ("GPL") as published by the Free Software
96731 + * Foundation, either version 2 of that License or (at your option) any
96732 + * later version.
96733 + *
96734 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96735 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96736 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96737 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96738 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96739 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96740 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96741 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96742 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96743 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96744 + */
96745 +
96746 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
96747 +#define __FSL_FMAN_MEMAC_MII_ACC_H
96748 +
96749 +#include "common/general.h"
96750 +#include "fsl_enet.h"
96751 +/* MII Management Registers */
96752 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
96753 +#define MDIO_CFG_CLK_DIV_SHIFT 7
96754 +#define MDIO_CFG_HOLD_MASK 0x0000001c
96755 +#define MDIO_CFG_ENC45 0x00000040
96756 +#define MDIO_CFG_READ_ERR 0x00000002
96757 +#define MDIO_CFG_BSY 0x00000001
96758 +
96759 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
96760 +#define MDIO_CTL_READ 0x00008000
96761 +
96762 +#define MDIO_DATA_BSY 0x80000000
96763 +
96764 +/*MEMAC Internal PHY Registers - SGMII */
96765 +#define PHY_SGMII_CR_PHY_RESET 0x8000
96766 +#define PHY_SGMII_CR_RESET_AN 0x0200
96767 +#define PHY_SGMII_CR_DEF_VAL 0x1140
96768 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
96769 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
96770 +#define PHY_SGMII_IF_MODE_AN 0x0002
96771 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
96772 +#define PHY_SGMII_IF_MODE_1000X 0x0000
96773 +
96774 +/*----------------------------------------------------*/
96775 +/* MII Configuration Control Memory Map Registers */
96776 +/*----------------------------------------------------*/
96777 +struct memac_mii_access_mem_map {
96778 + uint32_t mdio_cfg; /* 0x030 */
96779 + uint32_t mdio_ctrl; /* 0x034 */
96780 + uint32_t mdio_data; /* 0x038 */
96781 + uint32_t mdio_addr; /* 0x03c */
96782 +};
96783 +
96784 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
96785 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
96786 + enum enet_speed enet_speed);
96787 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
96788 + uint8_t phy_addr, uint8_t reg, uint16_t data,
96789 + enum enet_speed enet_speed);
96790 +
96791 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
96792 --- /dev/null
96793 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
96794 @@ -0,0 +1,593 @@
96795 +/*
96796 + * Copyright 2008-2013 Freescale Semiconductor Inc.
96797 + *
96798 + * Redistribution and use in source and binary forms, with or without
96799 + * modification, are permitted provided that the following conditions are met:
96800 + * * Redistributions of source code must retain the above copyright
96801 + * notice, this list of conditions and the following disclaimer.
96802 + * * Redistributions in binary form must reproduce the above copyright
96803 + * notice, this list of conditions and the following disclaimer in the
96804 + * documentation and/or other materials provided with the distribution.
96805 + * * Neither the name of Freescale Semiconductor nor the
96806 + * names of its contributors may be used to endorse or promote products
96807 + * derived from this software without specific prior written permission.
96808 + *
96809 + *
96810 + * ALTERNATIVELY, this software may be distributed under the terms of the
96811 + * GNU General Public License ("GPL") as published by the Free Software
96812 + * Foundation, either version 2 of that License or (at your option) any
96813 + * later version.
96814 + *
96815 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96816 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96817 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96818 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96819 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96820 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96821 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96822 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96823 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96824 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96825 + */
96826 +
96827 +#ifndef __FSL_FMAN_PORT_H
96828 +#define __FSL_FMAN_PORT_H
96829 +
96830 +#include "fsl_fman_sp.h"
96831 +
96832 +/** @Collection Registers bit fields */
96833 +
96834 +/** @Description BMI defines */
96835 +#define BMI_EBD_EN 0x80000000
96836 +
96837 +#define BMI_PORT_CFG_EN 0x80000000
96838 +#define BMI_PORT_CFG_FDOVR 0x02000000
96839 +#define BMI_PORT_CFG_IM 0x01000000
96840 +
96841 +#define BMI_PORT_STATUS_BSY 0x80000000
96842 +
96843 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
96844 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
96845 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
96846 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
96847 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
96848 +
96849 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
96850 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
96851 +
96852 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
96853 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
96854 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
96855 +
96856 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
96857 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
96858 +
96859 +#define BMI_INT_BUF_MARG_SHIFT 28
96860 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
96861 +
96862 +#define BMI_CMD_MR_LEAC 0x00200000
96863 +#define BMI_CMD_MR_SLEAC 0x00100000
96864 +#define BMI_CMD_MR_MA 0x00080000
96865 +#define BMI_CMD_MR_DEAS 0x00040000
96866 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
96867 + BMI_CMD_MR_SLEAC | \
96868 + BMI_CMD_MR_MA | \
96869 + BMI_CMD_MR_DEAS)
96870 +#define BMI_CMD_TX_MR_DEF 0
96871 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
96872 + BMI_CMD_MR_MA)
96873 +
96874 +#define BMI_CMD_ATTR_ORDER 0x80000000
96875 +#define BMI_CMD_ATTR_SYNC 0x02000000
96876 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
96877 +
96878 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
96879 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
96880 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
96881 +
96882 +#define BMI_COUNTERS_EN 0x80000000
96883 +
96884 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
96885 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
96886 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
96887 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
96888 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
96889 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96890 +
96891 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
96892 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
96893 +
96894 +#define MAX_PERFORMANCE_TASK_COMP 64
96895 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
96896 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
96897 +#define MAX_PERFORMANCE_DMA_COMP 16
96898 +#define MAX_PERFORMANCE_FIFO_COMP 1024
96899 +
96900 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
96901 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
96902 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
96903 +
96904 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
96905 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
96906 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
96907 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
96908 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
96909 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
96910 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
96911 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
96912 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
96913 +
96914 +/** @Description QMI defines */
96915 +#define QMI_PORT_CFG_EN 0x80000000
96916 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
96917 +
96918 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
96919 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
96920 +
96921 +#define QMI_DEQ_CFG_PRI 0x80000000
96922 +#define QMI_DEQ_CFG_TYPE1 0x10000000
96923 +#define QMI_DEQ_CFG_TYPE2 0x20000000
96924 +#define QMI_DEQ_CFG_TYPE3 0x30000000
96925 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
96926 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
96927 +#define QMI_DEQ_CFG_SP_MASK 0xf
96928 +#define QMI_DEQ_CFG_SP_SHIFT 20
96929 +
96930 +
96931 +/** @Description General port defines */
96932 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
96933 + (((fm_rev_maj) == 4) ? 4 : 8)
96934 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
96935 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
96936 +#define FMAN_PORT_CG_MAP_NUM 8
96937 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
96938 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
96939 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
96940 +
96941 +
96942 +/** @Collection FM Port Register Map */
96943 +
96944 +/** @Description BMI Rx port register map */
96945 +struct fman_port_rx_bmi_regs {
96946 + uint32_t fmbm_rcfg; /**< Rx Configuration */
96947 + uint32_t fmbm_rst; /**< Rx Status */
96948 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
96949 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
96950 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
96951 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
96952 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
96953 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
96954 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
96955 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
96956 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
96957 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
96958 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
96959 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
96960 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
96961 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
96962 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
96963 + /**< Rx Parse Results Array Init*/
96964 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
96965 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
96966 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
96967 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
96968 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
96969 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
96970 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
96971 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
96972 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
96973 + /**< Buffer Manager pool Information-*/
96974 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
96975 + /**< Allocate Counter-*/
96976 + uint32_t reserved0130[8];
96977 + /**< 0x130/0x140 - 0x15F reserved -*/
96978 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
96979 + /**< Congestion Group Map*/
96980 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
96981 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
96982 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
96983 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
96984 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
96985 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
96986 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
96987 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
96988 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
96989 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
96990 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
96991 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
96992 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
96993 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
96994 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
96995 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
96996 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
96997 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
96998 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
96999 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
97000 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
97001 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
97002 +};
97003 +
97004 +/** @Description BMI Tx port register map */
97005 +struct fman_port_tx_bmi_regs {
97006 + uint32_t fmbm_tcfg; /**< Tx Configuration */
97007 + uint32_t fmbm_tst; /**< Tx Status */
97008 + uint32_t fmbm_tda; /**< Tx DMA attributes */
97009 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
97010 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
97011 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
97012 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
97013 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
97014 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
97015 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
97016 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
97017 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
97018 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
97019 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
97020 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
97021 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
97022 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
97023 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
97024 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
97025 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
97026 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
97027 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
97028 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
97029 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
97030 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
97031 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
97032 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
97033 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
97034 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
97035 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
97036 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
97037 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
97038 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
97039 +};
97040 +
97041 +/** @Description BMI O/H port register map */
97042 +struct fman_port_oh_bmi_regs {
97043 + uint32_t fmbm_ocfg; /**< O/H Configuration */
97044 + uint32_t fmbm_ost; /**< O/H Status */
97045 + uint32_t fmbm_oda; /**< O/H DMA attributes */
97046 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
97047 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
97048 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
97049 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
97050 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
97051 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
97052 + uint32_t fmbm_opp; /**< O/H Policer Profile */
97053 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
97054 + uint32_t fmbm_oim; /**< O/H Internal margins*/
97055 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
97056 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
97057 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
97058 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
97059 + /**< O/H Parse Results Array Initialization */
97060 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
97061 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
97062 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
97063 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
97064 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
97065 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
97066 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
97067 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
97068 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
97069 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
97070 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
97071 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
97072 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
97073 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
97074 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
97075 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
97076 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
97077 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
97078 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
97079 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
97080 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
97081 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
97082 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
97083 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
97084 + uint32_t fmbm_opc; /**< O/H Performance Counters */
97085 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
97086 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
97087 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
97088 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
97089 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
97090 +};
97091 +
97092 +/** @Description BMI port register map */
97093 +union fman_port_bmi_regs {
97094 + struct fman_port_rx_bmi_regs rx;
97095 + struct fman_port_tx_bmi_regs tx;
97096 + struct fman_port_oh_bmi_regs oh;
97097 +};
97098 +
97099 +/** @Description QMI port register map */
97100 +struct fman_port_qmi_regs {
97101 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
97102 + uint32_t fmqm_pns; /**< PortID n Status Register */
97103 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
97104 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
97105 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
97106 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
97107 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
97108 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
97109 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
97110 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
97111 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
97112 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
97113 +};
97114 +
97115 +
97116 +enum fman_port_dma_swap {
97117 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
97118 + E_FMAN_PORT_DMA_SWAP_LE,
97119 + /**< The transferred data should be swapped in PPC Little Endian mode */
97120 + E_FMAN_PORT_DMA_SWAP_BE
97121 + /**< The transferred data should be swapped in Big Endian mode */
97122 +};
97123 +
97124 +/* Default port color */
97125 +enum fman_port_color {
97126 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
97127 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
97128 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
97129 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
97130 +};
97131 +
97132 +/* QMI dequeue from the SP channel - types */
97133 +enum fman_port_deq_type {
97134 + E_FMAN_PORT_DEQ_BY_PRI,
97135 + /**< Priority precedence and Intra-Class scheduling */
97136 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
97137 + /**< Active FQ precedence and Intra-Class scheduling */
97138 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
97139 + /**< Active FQ precedence and override Intra-Class scheduling */
97140 +};
97141 +
97142 +/* QMI dequeue prefetch modes */
97143 +enum fman_port_deq_prefetch {
97144 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
97145 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
97146 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
97147 +};
97148 +
97149 +/* Parameters for defining performance counters behavior */
97150 +struct fman_port_perf_cnt_params {
97151 + uint8_t task_val; /**< Task compare value */
97152 + uint8_t queue_val;
97153 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
97154 + uint8_t dma_val; /**< Dma compare value */
97155 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
97156 +};
97157 +
97158 +/** @Description FM Port configuration structure, used at init */
97159 +struct fman_port_cfg {
97160 + struct fman_port_perf_cnt_params perf_cnt_params;
97161 + /* BMI parameters */
97162 + enum fman_port_dma_swap dma_swap_data;
97163 + bool dma_ic_stash_on;
97164 + bool dma_header_stash_on;
97165 + bool dma_sg_stash_on;
97166 + bool dma_write_optimize;
97167 + uint16_t ic_ext_offset;
97168 + uint8_t ic_int_offset;
97169 + uint16_t ic_size;
97170 + enum fman_port_color color;
97171 + bool sync_req;
97172 + bool discard_override;
97173 + uint8_t checksum_bytes_ignore;
97174 + uint8_t rx_cut_end_bytes;
97175 + uint32_t rx_pri_elevation;
97176 + uint32_t rx_fifo_thr;
97177 + uint8_t rx_fd_bits;
97178 + uint8_t int_buf_start_margin;
97179 + uint16_t ext_buf_start_margin;
97180 + uint16_t ext_buf_end_margin;
97181 + uint32_t tx_fifo_min_level;
97182 + uint32_t tx_fifo_low_comf_level;
97183 + uint8_t tx_fifo_deq_pipeline_depth;
97184 + bool stats_counters_enable;
97185 + bool perf_counters_enable;
97186 + /* QMI parameters */
97187 + bool deq_high_pri;
97188 + enum fman_port_deq_type deq_type;
97189 + enum fman_port_deq_prefetch deq_prefetch_opt;
97190 + uint16_t deq_byte_cnt;
97191 + bool queue_counters_enable;
97192 + bool no_scatter_gather;
97193 + int errata_A006675;
97194 + int errata_A006320;
97195 + int excessive_threshold_register;
97196 + int fmbm_rebm_has_sgd;
97197 + int fmbm_tfne_has_features;
97198 + int qmi_deq_options_support;
97199 +};
97200 +
97201 +enum fman_port_type {
97202 + E_FMAN_PORT_TYPE_OP = 0,
97203 + /**< Offline parsing port, shares id-s with
97204 + * host command, so must have exclusive id-s */
97205 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
97206 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
97207 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
97208 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
97209 + E_FMAN_PORT_TYPE_DUMMY,
97210 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
97211 + /**< Host command port, shares id-s with
97212 + * offline parsing ports, so must have exclusive id-s */
97213 +};
97214 +
97215 +struct fman_port_params {
97216 + uint32_t discard_mask;
97217 + uint32_t err_mask;
97218 + uint32_t dflt_fqid;
97219 + uint32_t err_fqid;
97220 + uint8_t deq_sp;
97221 + bool dont_release_buf;
97222 +};
97223 +
97224 +/* Port context - used by most API functions */
97225 +struct fman_port {
97226 + enum fman_port_type type;
97227 + uint8_t fm_rev_maj;
97228 + uint8_t fm_rev_min;
97229 + union fman_port_bmi_regs *bmi_regs;
97230 + struct fman_port_qmi_regs *qmi_regs;
97231 + bool im_en;
97232 + uint8_t ext_pools_num;
97233 +};
97234 +
97235 +/** @Description External buffer pools configuration */
97236 +struct fman_port_bpools {
97237 + uint8_t count; /**< Num of pools to set up */
97238 + bool counters_enable; /**< Enable allocate counters */
97239 + uint8_t grp_bp_depleted_num;
97240 + /**< Number of depleted pools - if reached the BMI indicates
97241 + * the MAC to send a pause frame */
97242 + struct {
97243 + uint8_t bpid; /**< BM pool ID */
97244 + uint16_t size;
97245 + /**< Pool's size - must be in ascending order */
97246 + bool is_backup;
97247 + /**< If this is a backup pool */
97248 + bool grp_bp_depleted;
97249 + /**< Consider this buffer in multiple pools depletion criteria*/
97250 + bool single_bp_depleted;
97251 + /**< Consider this buffer in single pool depletion criteria */
97252 + bool pfc_priorities_en;
97253 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
97254 +};
97255 +
97256 +enum fman_port_rate_limiter_scale_down {
97257 + E_FMAN_PORT_RATE_DOWN_NONE,
97258 + E_FMAN_PORT_RATE_DOWN_BY_2,
97259 + E_FMAN_PORT_RATE_DOWN_BY_4,
97260 + E_FMAN_PORT_RATE_DOWN_BY_8
97261 +};
97262 +
97263 +/* Rate limiter configuration */
97264 +struct fman_port_rate_limiter {
97265 + uint8_t count_1micro_bit;
97266 + bool high_burst_size_gran;
97267 + /**< Defines burst_size granularity for OP ports; when TRUE,
97268 + * burst_size below counts in frames, otherwise in 10^3 frames */
97269 + uint16_t burst_size;
97270 + /**< Max burst size, in KBytes for Tx port, according to
97271 + * high_burst_size_gran definition for OP port */
97272 + uint32_t rate;
97273 + /**< In Kbps for Tx port, in frames/sec for OP port */
97274 + enum fman_port_rate_limiter_scale_down rate_factor;
97275 +};
97276 +
97277 +/* BMI statistics counters */
97278 +enum fman_port_stats_counters {
97279 + E_FMAN_PORT_STATS_CNT_FRAME,
97280 + /**< Number of processed frames; valid for all ports */
97281 + E_FMAN_PORT_STATS_CNT_DISCARD,
97282 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
97283 + * frames discarded due to DMA error; valid for all ports */
97284 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
97285 + /**< Number of buffer deallocate operations; valid for all ports */
97286 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
97287 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
97288 + * valid for Rx ports only */
97289 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
97290 + /**< Number of Rx oversized frames, that is frames exceeding max frame
97291 + * size configured for the corresponding ETH controller;
97292 + * valid for Rx ports only */
97293 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
97294 + /**< Frames discarded due to lack of external buffers; valid for
97295 + * Rx ports only */
97296 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
97297 + /**< Frames discarded due to frame length error; valid for Tx and
97298 + * O/H ports only */
97299 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
97300 + /**< Frames discarded due to unsupported FD format; valid for Tx
97301 + * and O/H ports only */
97302 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
97303 + /**< Number of frames filtered out by PCD module; valid for
97304 + * Rx and OP ports only */
97305 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
97306 + /**< Frames rejected by QMAN that were not able to release their
97307 + * buffers due to DMA error; valid for Rx and O/H ports only */
97308 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
97309 + /**< Frames going through O/H port that were not able to to enter the
97310 + * return queue due to WRED algorithm; valid for O/H ports only */
97311 +};
97312 +
97313 +/* BMI performance counters */
97314 +enum fman_port_perf_counters {
97315 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
97316 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
97317 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
97318 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
97319 + * utilization; not valid for O/H ports */
97320 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
97321 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
97322 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
97323 + /**< Number of cycles in which Rx pause activation control is on;
97324 + * valid for Rx ports only */
97325 +};
97326 +
97327 +/* QMI counters */
97328 +enum fman_port_qmi_counters {
97329 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
97330 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
97331 + E_FMAN_PORT_DEQ_FROM_DFLT,
97332 + /**< Dequeue from default FQID counter not valid for Rx ports */
97333 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
97334 +};
97335 +
97336 +
97337 +/** @Collection FM Port API */
97338 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
97339 +int fman_port_init(struct fman_port *port,
97340 + struct fman_port_cfg *cfg,
97341 + struct fman_port_params *params);
97342 +int fman_port_enable(struct fman_port *port);
97343 +int fman_port_disable(const struct fman_port *port);
97344 +int fman_port_set_bpools(const struct fman_port *port,
97345 + const struct fman_port_bpools *bp);
97346 +int fman_port_set_rate_limiter(struct fman_port *port,
97347 + struct fman_port_rate_limiter *rate_limiter);
97348 +int fman_port_delete_rate_limiter(struct fman_port *port);
97349 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
97350 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
97351 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
97352 + uint8_t rx_fd_bits,
97353 + bool add);
97354 +int fman_port_set_perf_cnt_params(struct fman_port *port,
97355 + struct fman_port_perf_cnt_params *params);
97356 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
97357 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
97358 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
97359 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
97360 + uint8_t bpid,
97361 + bool enable);
97362 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
97363 + enum fman_port_stats_counters counter);
97364 +void fman_port_set_stats_counter(struct fman_port *port,
97365 + enum fman_port_stats_counters counter,
97366 + uint32_t value);
97367 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
97368 + enum fman_port_perf_counters counter);
97369 +void fman_port_set_perf_counter(struct fman_port *port,
97370 + enum fman_port_perf_counters counter,
97371 + uint32_t value);
97372 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
97373 + enum fman_port_qmi_counters counter);
97374 +void fman_port_set_qmi_counter(struct fman_port *port,
97375 + enum fman_port_qmi_counters counter,
97376 + uint32_t value);
97377 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
97378 +void fman_port_set_bpool_counter(struct fman_port *port,
97379 + uint8_t bpid,
97380 + uint32_t value);
97381 +int fman_port_add_congestion_grps(struct fman_port *port,
97382 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
97383 +int fman_port_remove_congestion_grps(struct fman_port *port,
97384 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
97385 +
97386 +
97387 +#endif /* __FSL_FMAN_PORT_H */
97388 --- /dev/null
97389 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
97390 @@ -0,0 +1,102 @@
97391 +/*
97392 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97393 + *
97394 + * Redistribution and use in source and binary forms, with or without
97395 + * modification, are permitted provided that the following conditions are met:
97396 + * * Redistributions of source code must retain the above copyright
97397 + * notice, this list of conditions and the following disclaimer.
97398 + * * Redistributions in binary form must reproduce the above copyright
97399 + * notice, this list of conditions and the following disclaimer in the
97400 + * documentation and/or other materials provided with the distribution.
97401 + * * Neither the name of Freescale Semiconductor nor the
97402 + * names of its contributors may be used to endorse or promote products
97403 + * derived from this software without specific prior written permission.
97404 + *
97405 + *
97406 + * ALTERNATIVELY, this software may be distributed under the terms of the
97407 + * GNU General Public License ("GPL") as published by the Free Software
97408 + * Foundation, either version 2 of that License or (at your option) any
97409 + * later version.
97410 + *
97411 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97412 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97413 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97414 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97415 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97416 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97417 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97418 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97419 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97420 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97421 + */
97422 +
97423 +#ifndef __FSL_FMAN_PRS_H
97424 +#define __FSL_FMAN_PRS_H
97425 +
97426 +#include "common/general.h"
97427 +
97428 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
97429 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
97430 +
97431 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
97432 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
97433 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
97434 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
97435 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
97436 +#define PRS_MAX_CYCLE_LIMIT 8191
97437 +
97438 +#define DEFAULT_MAX_PRS_CYC_LIM 0
97439 +
97440 +struct fman_prs_regs {
97441 + uint32_t fmpr_rpclim;
97442 + uint32_t fmpr_rpimac;
97443 + uint32_t pmeec;
97444 + uint32_t res00c[5];
97445 + uint32_t fmpr_pevr;
97446 + uint32_t fmpr_pever;
97447 + uint32_t res028;
97448 + uint32_t fmpr_perr;
97449 + uint32_t fmpr_perer;
97450 + uint32_t res034;
97451 + uint32_t res038[10];
97452 + uint32_t fmpr_ppsc;
97453 + uint32_t res064;
97454 + uint32_t fmpr_pds;
97455 + uint32_t fmpr_l2rrs;
97456 + uint32_t fmpr_l3rrs;
97457 + uint32_t fmpr_l4rrs;
97458 + uint32_t fmpr_srrs;
97459 + uint32_t fmpr_l2rres;
97460 + uint32_t fmpr_l3rres;
97461 + uint32_t fmpr_l4rres;
97462 + uint32_t fmpr_srres;
97463 + uint32_t fmpr_spcs;
97464 + uint32_t fmpr_spscs;
97465 + uint32_t fmpr_hxscs;
97466 + uint32_t fmpr_mrcs;
97467 + uint32_t fmpr_mwcs;
97468 + uint32_t fmpr_mrscs;
97469 + uint32_t fmpr_mwscs;
97470 + uint32_t fmpr_fcscs;
97471 +};
97472 +
97473 +struct fman_prs_cfg {
97474 + uint32_t port_id_stat;
97475 + uint16_t max_prs_cyc_lim;
97476 + uint32_t prs_exceptions;
97477 +};
97478 +
97479 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
97480 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
97481 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
97482 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
97483 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
97484 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
97485 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
97486 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
97487 +void fman_prs_enable(struct fman_prs_regs *regs);
97488 +void fman_prs_disable(struct fman_prs_regs *regs);
97489 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
97490 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
97491 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
97492 +#endif /* __FSL_FMAN_PRS_H */
97493 --- /dev/null
97494 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
97495 @@ -0,0 +1,449 @@
97496 +/*
97497 + * Copyright 2013 Freescale Semiconductor Inc.
97498 + *
97499 + * Redistribution and use in source and binary forms, with or without
97500 + * modification, are permitted provided that the following conditions are met:
97501 + * * Redistributions of source code must retain the above copyright
97502 + * notice, this list of conditions and the following disclaimer.
97503 + * * Redistributions in binary form must reproduce the above copyright
97504 + * notice, this list of conditions and the following disclaimer in the
97505 + * documentation and/or other materials provided with the distribution.
97506 + * * Neither the name of Freescale Semiconductor nor the
97507 + * names of its contributors may be used to endorse or promote products
97508 + * derived from this software without specific prior written permission.
97509 + *
97510 + *
97511 + * ALTERNATIVELY, this software may be distributed under the terms of the
97512 + * GNU General Public License ("GPL") as published by the Free Software
97513 + * Foundation, either version 2 of that License or (at your option) any
97514 + * later version.
97515 + *
97516 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97517 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97518 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97519 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97520 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97521 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97522 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97523 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97524 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97525 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97526 + */
97527 +
97528 +#ifndef __FSL_FMAN_RTC_H
97529 +#define __FSL_FMAN_RTC_H
97530 +
97531 +#include "common/general.h"
97532 +
97533 +/* FM RTC Registers definitions */
97534 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
97535 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
97536 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
97537 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
97538 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
97539 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
97540 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
97541 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
97542 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
97543 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
97544 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
97545 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
97546 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
97547 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
97548 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
97549 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
97550 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
97551 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
97552 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
97553 +
97554 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
97555 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
97556 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
97557 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
97558 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
97559 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
97560 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
97561 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
97562 + FMAN_RTC_TMR_TEVENT_ETS1 |\
97563 + FMAN_RTC_TMR_TEVENT_ALM2 |\
97564 + FMAN_RTC_TMR_TEVENT_ALM1 |\
97565 + FMAN_RTC_TMR_TEVENT_PP1 |\
97566 + FMAN_RTC_TMR_TEVENT_PP2 |\
97567 + FMAN_RTC_TMR_TEVENT_PP3)
97568 +
97569 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
97570 +
97571 +/**************************************************************************//**
97572 + @Description FM RTC Alarm Polarity Options.
97573 +*//***************************************************************************/
97574 +enum fman_rtc_alarm_polarity {
97575 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
97576 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
97577 +};
97578 +
97579 +/**************************************************************************//**
97580 + @Description FM RTC Trigger Polarity Options.
97581 +*//***************************************************************************/
97582 +enum fman_rtc_trigger_polarity {
97583 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
97584 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
97585 +};
97586 +
97587 +/**************************************************************************//**
97588 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
97589 +*//***************************************************************************/
97590 +enum fman_src_clock {
97591 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
97592 + reference clock */
97593 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
97594 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
97595 +};
97596 +
97597 +/* RTC default values */
97598 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
97599 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
97600 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
97601 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
97602 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
97603 +#define DEFAULT_PULSE_REALIGN FALSE
97604 +
97605 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
97606 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
97607 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
97608 +
97609 +/**************************************************************************//**
97610 + @Description FM RTC timer alarm
97611 +*//***************************************************************************/
97612 +struct t_tmr_alarm{
97613 + uint32_t tmr_alarm_h; /**< */
97614 + uint32_t tmr_alarm_l; /**< */
97615 +};
97616 +
97617 +/**************************************************************************//**
97618 + @Description FM RTC timer Ex trigger
97619 +*//***************************************************************************/
97620 +struct t_tmr_ext_trigger{
97621 + uint32_t tmr_etts_h; /**< */
97622 + uint32_t tmr_etts_l; /**< */
97623 +};
97624 +
97625 +struct rtc_regs {
97626 + uint32_t tmr_id; /* 0x000 Module ID register */
97627 + uint32_t tmr_id2; /* 0x004 Controller ID register */
97628 + uint32_t reserved0008[30];
97629 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
97630 + uint32_t tmr_tevent; /* 0x0084 timer event register */
97631 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
97632 + uint32_t reserved008c[3];
97633 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
97634 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
97635 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
97636 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
97637 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
97638 + uint32_t reserved00ac;
97639 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
97640 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
97641 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
97642 + alarm */
97643 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
97644 + fixed period interval */
97645 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
97646 + /* 0x00e0 time stamp general purpose external */
97647 + uint32_t reserved00f0[4];
97648 +};
97649 +
97650 +struct rtc_cfg {
97651 + enum fman_src_clock src_clk;
97652 + uint32_t ext_src_clk_freq;
97653 + uint32_t rtc_freq_hz;
97654 + bool timer_slave_mode;
97655 + bool invert_input_clk_phase;
97656 + bool invert_output_clk_phase;
97657 + uint32_t events_mask;
97658 + bool bypass; /**< Indicates if frequency compensation
97659 + is bypassed */
97660 + bool pulse_realign;
97661 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
97662 + enum fman_rtc_trigger_polarity trigger_polarity
97663 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
97664 +};
97665 +
97666 +/**
97667 + * fman_rtc_defconfig() - Get default RTC configuration
97668 + * @cfg: pointer to configuration structure.
97669 + *
97670 + * Call this function to obtain a default set of configuration values for
97671 + * initializing RTC. The user can overwrite any of the values before calling
97672 + * fman_rtc_init(), if specific configuration needs to be applied.
97673 + */
97674 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
97675 +
97676 +/**
97677 + * fman_rtc_get_events() - Get the events
97678 + * @regs: Pointer to RTC register block
97679 + *
97680 + * Returns: The events
97681 + */
97682 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
97683 +
97684 +/**
97685 + * fman_rtc_get_interrupt_mask() - Get the events mask
97686 + * @regs: Pointer to RTC register block
97687 + *
97688 + * Returns: The events mask
97689 + */
97690 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
97691 +
97692 +
97693 +/**
97694 + * fman_rtc_set_interrupt_mask() - Set the events mask
97695 + * @regs: Pointer to RTC register block
97696 + * @mask: The mask to set
97697 + */
97698 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
97699 +
97700 +/**
97701 + * fman_rtc_get_event() - Check if specific events occurred
97702 + * @regs: Pointer to RTC register block
97703 + * @ev_mask: a mask of the events to check
97704 + *
97705 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
97706 + */
97707 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
97708 +
97709 +/**
97710 + * fman_rtc_check_and_clear_event() - Clear events which are on
97711 + * @regs: Pointer to RTC register block
97712 + *
97713 + * Returns: A mask of the events which were cleared
97714 + */
97715 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
97716 +
97717 +/**
97718 + * fman_rtc_ack_event() - Clear events
97719 + * @regs: Pointer to RTC register block
97720 + * @events: The events to disable
97721 + */
97722 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
97723 +
97724 +/**
97725 + * fman_rtc_enable_interupt() - Enable events interrupts
97726 + * @regs: Pointer to RTC register block
97727 + * @mask: The events to disable
97728 + */
97729 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
97730 +
97731 +/**
97732 + * fman_rtc_disable_interupt() - Disable events interrupts
97733 + * @regs: Pointer to RTC register block
97734 + * @mask: The events to disable
97735 + */
97736 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
97737 +
97738 +/**
97739 + * fman_rtc_get_timer_ctrl() - Get the control register
97740 + * @regs: Pointer to RTC register block
97741 + *
97742 + * Returns: The control register value
97743 + */
97744 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
97745 +
97746 +/**
97747 + * fman_rtc_set_timer_ctrl() - Set timer control register
97748 + * @regs: Pointer to RTC register block
97749 + * @val: The value to set
97750 + */
97751 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
97752 +
97753 +/**
97754 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
97755 + * @regs: Pointer to RTC register block
97756 + *
97757 + * Returns: The timer counter
97758 + */
97759 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
97760 +
97761 +/**
97762 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
97763 + * @regs: Pointer to RTC register block
97764 + * @val: The value to set
97765 + */
97766 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
97767 +
97768 +/**
97769 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
97770 + * @regs: Pointer to RTC register block
97771 + * @id: The id of the trigger stamp
97772 + *
97773 + * Returns: The time stamp
97774 + */
97775 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
97776 +
97777 +/**
97778 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
97779 + * @regs: Pointer to RTC register block
97780 + * @index: The index of alarm to set
97781 + * @val: The value to set
97782 + */
97783 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
97784 + uint32_t val);
97785 +
97786 +/**
97787 + * fman_rtc_set_timer_alarm() - Set timer alarm
97788 + * @regs: Pointer to RTC register block
97789 + * @index: The index of alarm to set
97790 + * @val: The value to set
97791 + */
97792 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
97793 +
97794 +/**
97795 + * fman_rtc_set_timer_fiper() - Set timer fiper
97796 + * @regs: Pointer to RTC register block
97797 + * @index: The index of fiper to set
97798 + * @val: The value to set
97799 + */
97800 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
97801 +
97802 +/**
97803 + * fman_rtc_set_timer_offset() - Set timer offset
97804 + * @regs: Pointer to RTC register block
97805 + * @val: The value to set
97806 + */
97807 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
97808 +
97809 +/**
97810 + * fman_rtc_get_timer() - Get the timer counter
97811 + * @regs: Pointer to RTC register block
97812 + *
97813 + * Returns: The timer counter
97814 + */
97815 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
97816 +{
97817 + uint64_t time;
97818 + /* TMR_CNT_L must be read first to get an accurate value */
97819 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
97820 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
97821 +
97822 + return time;
97823 +}
97824 +
97825 +/**
97826 + * fman_rtc_set_timer() - Set timer counter
97827 + * @regs: Pointer to RTC register block
97828 + * @val: The value to set
97829 + */
97830 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
97831 +{
97832 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
97833 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
97834 +}
97835 +
97836 +/**
97837 + * fman_rtc_timers_soft_reset() - Soft reset
97838 + * @regs: Pointer to RTC register block
97839 + *
97840 + * Resets all the timer registers and state machines for the 1588 IP and
97841 + * the attached client 1588
97842 + */
97843 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
97844 +
97845 +/**
97846 + * fman_rtc_clear_external_trigger() - Clear an external trigger
97847 + * @regs: Pointer to RTC register block
97848 + * @id: The id of the trigger to clear
97849 + */
97850 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
97851 +
97852 +/**
97853 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
97854 + * @regs: Pointer to RTC register block
97855 + * @id: The id of the fiper to clear
97856 + */
97857 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
97858 +
97859 +/**
97860 + * fman_rtc_enable() - Enable RTC hardware block
97861 + * @regs: Pointer to RTC register block
97862 + */
97863 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
97864 +
97865 +/**
97866 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
97867 + * @regs: Pointer to RTC register block
97868 + *
97869 + * Return: TRUE if enabled
97870 + */
97871 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
97872 +
97873 +/**
97874 + * fman_rtc_disable() - Disable RTC hardware block
97875 + * @regs: Pointer to RTC register block
97876 + */
97877 +void fman_rtc_disable(struct rtc_regs *regs);
97878 +
97879 +/**
97880 + * fman_rtc_init() - Init RTC hardware block
97881 + * @cfg: RTC configuration data
97882 + * @regs: Pointer to RTC register block
97883 + * @num_alarms: Number of alarms in RTC
97884 + * @num_fipers: Number of fipers in RTC
97885 + * @num_ext_triggers: Number of external triggers in RTC
97886 + * @freq_compensation: Frequency compensation
97887 + * @output_clock_divisor: Output clock divisor
97888 + *
97889 + * This function initializes RTC and applies basic configuration.
97890 + */
97891 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
97892 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
97893 + uint32_t freq_compensation, uint32_t output_clock_divisor);
97894 +
97895 +/**
97896 + * fman_rtc_set_alarm() - Set an alarm
97897 + * @regs: Pointer to RTC register block
97898 + * @id: id of alarm
97899 + * @val: value to write
97900 + * @enable: should interrupt be enabled
97901 + */
97902 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
97903 +
97904 +/**
97905 + * fman_rtc_set_periodic_pulse() - Set an alarm
97906 + * @regs: Pointer to RTC register block
97907 + * @id: id of fiper
97908 + * @val: value to write
97909 + * @enable: should interrupt be enabled
97910 + */
97911 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
97912 + bool enable);
97913 +
97914 +/**
97915 + * fman_rtc_set_ext_trigger() - Set an external trigger
97916 + * @regs: Pointer to RTC register block
97917 + * @id: id of trigger
97918 + * @enable: should interrupt be enabled
97919 + * @use_pulse_as_input: use the pulse as input
97920 + */
97921 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
97922 + bool use_pulse_as_input);
97923 +
97924 +struct fm_rtc_alarm_params {
97925 + uint8_t alarm_id; /**< 0 or 1 */
97926 + uint64_t alarm_time; /**< In nanoseconds, the time when the
97927 + alarm should go off - must be a
97928 + multiple of the RTC period */
97929 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
97930 + be called when RTC reaches alarmTime */
97931 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
97932 + expired.*/
97933 +};
97934 +
97935 +struct fm_rtc_periodic_pulse_params {
97936 + uint8_t periodic_pulse_id; /**< 0 or 1 */
97937 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
97938 + of the RTC period */
97939 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
97940 + routine will be called every
97941 + periodicPulsePeriod. */
97942 +};
97943 +
97944 +#endif /* __FSL_FMAN_RTC_H */
97945 --- /dev/null
97946 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
97947 @@ -0,0 +1,138 @@
97948 +/*
97949 + * Copyright 2013 Freescale Semiconductor Inc.
97950 + *
97951 + * Redistribution and use in source and binary forms, with or without
97952 + * modification, are permitted provided that the following conditions are met:
97953 + * * Redistributions of source code must retain the above copyright
97954 + * notice, this list of conditions and the following disclaimer.
97955 + * * Redistributions in binary form must reproduce the above copyright
97956 + * notice, this list of conditions and the following disclaimer in the
97957 + * documentation and/or other materials provided with the distribution.
97958 + * * Neither the name of Freescale Semiconductor nor the
97959 + * names of its contributors may be used to endorse or promote products
97960 + * derived from this software without specific prior written permission.
97961 + *
97962 + *
97963 + * ALTERNATIVELY, this software may be distributed under the terms of the
97964 + * GNU General Public License ("GPL") as published by the Free Software
97965 + * Foundation, either version 2 of that License or (at your option) any
97966 + * later version.
97967 + *
97968 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97969 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97970 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97971 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97972 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97973 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97974 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97975 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97976 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97977 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97978 + */
97979 +
97980 +#ifndef __FSL_FMAN_SP_H
97981 +#define __FSL_FMAN_SP_H
97982 +
97983 +#include "common/general.h"
97984 +#include "fsl_fman.h"
97985 +
97986 +
97987 +struct fm_pcd_storage_profile_regs{
97988 + uint32_t fm_sp_ebmpi[8];
97989 + /*offset 0 - 0xc*/
97990 + /**< Buffer Manager pool Information */
97991 +
97992 + uint32_t fm_sp_acnt; /*offset 0x20*/
97993 + uint32_t fm_sp_ebm; /*offset 0x24*/
97994 + uint32_t fm_sp_da; /*offset 0x28*/
97995 + uint32_t fm_sp_icp; /*offset 0x2c*/
97996 + uint32_t fm_sp_mpd; /*offset 0x30*/
97997 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
97998 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
97999 +};
98000 +
98001 +/**************************************************************************//**
98002 + @Description structure for defining internal context copying
98003 +*//***************************************************************************/
98004 +struct fman_sp_int_context_data_copy{
98005 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
98006 + internal context is copied to (Rx)
98007 + or taken from (Tx, Op). */
98008 + uint8_t int_context_offset; /**< Offset within internal context to copy
98009 + from (Rx) or to copy to (Tx, Op).*/
98010 + uint16_t size; /**< Internal offset size to be copied */
98011 +};
98012 +
98013 +/**************************************************************************//**
98014 + @Description struct for defining external buffer margins
98015 +*//***************************************************************************/
98016 +struct fman_sp_buf_margins{
98017 + uint16_t start_margins; /**< Number of bytes to be left at the
98018 + beginning of the external buffer (must be
98019 + divisible by 16) */
98020 + uint16_t end_margins; /**< number of bytes to be left at the end of
98021 + the external buffer(must be divisible by 16)*/
98022 +};
98023 +
98024 +struct fm_storage_profile_params {
98025 + struct fman_ext_pools fm_ext_pools;
98026 + struct fman_backup_bm_pools backup_pools;
98027 + struct fman_sp_int_context_data_copy *int_context;
98028 + struct fman_sp_buf_margins *buf_margins;
98029 + enum fman_dma_swap_option dma_swap_data;
98030 + enum fman_dma_cache_option int_context_cache_attr;
98031 + enum fman_dma_cache_option header_cache_attr;
98032 + enum fman_dma_cache_option scatter_gather_cache_attr;
98033 + bool dma_write_optimize;
98034 + uint16_t liodn_offset;
98035 + bool no_scather_gather;
98036 + struct fman_buf_pool_depletion buf_pool_depletion;
98037 +};
98038 +
98039 +/**************************************************************************//**
98040 + @Description Registers bit fields
98041 +*//***************************************************************************/
98042 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
98043 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
98044 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
98045 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
98046 +#define FMAN_SP_SG_DISABLE 0x80000000
98047 +
98048 +/* shifts */
98049 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
98050 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
98051 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
98052 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
98053 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
98054 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
98055 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
98056 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
98057 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
98058 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
98059 +#define FMAN_SP_IC_SIZE_SHIFT 0
98060 +
98061 +/**************************************************************************//**
98062 + @Description defaults
98063 +*//***************************************************************************/
98064 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
98065 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
98066 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
98067 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
98068 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
98069 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
98070 +
98071 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
98072 +
98073 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
98074 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
98075 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
98076 + int max_num_of_pfc_priorities);
98077 +
98078 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
98079 + uint16_t index);
98080 +
98081 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
98082 + uint16_t index, uint32_t value);
98083 +
98084 +
98085 +#endif /* __FSL_FMAN_SP_H */
98086 --- /dev/null
98087 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
98088 @@ -0,0 +1,479 @@
98089 +/*
98090 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98091 + *
98092 + * Redistribution and use in source and binary forms, with or without
98093 + * modification, are permitted provided that the following conditions are met:
98094 + * * Redistributions of source code must retain the above copyright
98095 + * notice, this list of conditions and the following disclaimer.
98096 + * * Redistributions in binary form must reproduce the above copyright
98097 + * notice, this list of conditions and the following disclaimer in the
98098 + * documentation and/or other materials provided with the distribution.
98099 + * * Neither the name of Freescale Semiconductor nor the
98100 + * names of its contributors may be used to endorse or promote products
98101 + * derived from this software without specific prior written permission.
98102 + *
98103 + *
98104 + * ALTERNATIVELY, this software may be distributed under the terms of the
98105 + * GNU General Public License ("GPL") as published by the Free Software
98106 + * Foundation, either version 2 of that License or (at your option) any
98107 + * later version.
98108 + *
98109 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98110 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98111 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98112 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98113 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98114 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98115 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98116 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98117 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98118 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98119 + */
98120 +
98121 +#ifndef __FSL_FMAN_TGEC_H
98122 +#define __FSL_FMAN_TGEC_H
98123 +
98124 +#include "common/general.h"
98125 +#include "fsl_enet.h"
98126 +
98127 +
98128 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
98129 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
98130 +
98131 +enum tgec_counters {
98132 + E_TGEC_COUNTER_R64,
98133 + E_TGEC_COUNTER_R127,
98134 + E_TGEC_COUNTER_R255,
98135 + E_TGEC_COUNTER_R511,
98136 + E_TGEC_COUNTER_R1023,
98137 + E_TGEC_COUNTER_R1518,
98138 + E_TGEC_COUNTER_R1519X,
98139 + E_TGEC_COUNTER_TRFRG,
98140 + E_TGEC_COUNTER_TRJBR,
98141 + E_TGEC_COUNTER_RDRP,
98142 + E_TGEC_COUNTER_RALN,
98143 + E_TGEC_COUNTER_TRUND,
98144 + E_TGEC_COUNTER_TROVR,
98145 + E_TGEC_COUNTER_RXPF,
98146 + E_TGEC_COUNTER_TXPF,
98147 + E_TGEC_COUNTER_ROCT,
98148 + E_TGEC_COUNTER_RMCA,
98149 + E_TGEC_COUNTER_RBCA,
98150 + E_TGEC_COUNTER_RPKT,
98151 + E_TGEC_COUNTER_RUCA,
98152 + E_TGEC_COUNTER_RERR,
98153 + E_TGEC_COUNTER_TOCT,
98154 + E_TGEC_COUNTER_TMCA,
98155 + E_TGEC_COUNTER_TBCA,
98156 + E_TGEC_COUNTER_TUCA,
98157 + E_TGEC_COUNTER_TERR
98158 +};
98159 +
98160 +/* Command and Configuration Register (COMMAND_CONFIG) */
98161 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
98162 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
98163 +#define CMD_CFG_NO_LEN_CHK 0x00020000
98164 +#define CMD_CFG_SEND_IDLE 0x00010000
98165 +#define CMD_CFG_RX_ER_DISC 0x00004000
98166 +#define CMD_CFG_CMD_FRM_EN 0x00002000
98167 +#define CMD_CFG_STAT_CLR 0x00001000
98168 +#define CMD_CFG_LOOPBACK_EN 0x00000400
98169 +#define CMD_CFG_TX_ADDR_INS 0x00000200
98170 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
98171 +#define CMD_CFG_PAUSE_FWD 0x00000080
98172 +#define CMD_CFG_PROMIS_EN 0x00000010
98173 +#define CMD_CFG_WAN_MODE 0x00000008
98174 +#define CMD_CFG_RX_EN 0x00000002
98175 +#define CMD_CFG_TX_EN 0x00000001
98176 +
98177 +/* Interrupt Mask Register (IMASK) */
98178 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
98179 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
98180 +#define TGEC_IMASK_REM_FAULT 0x00004000
98181 +#define TGEC_IMASK_LOC_FAULT 0x00002000
98182 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
98183 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
98184 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
98185 +#define TGEC_IMASK_TX_ER 0x00000200
98186 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
98187 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
98188 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
98189 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
98190 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
98191 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
98192 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
98193 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
98194 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
98195 +
98196 +#define TGEC_EVENTS_MASK \
98197 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
98198 + TGEC_IMASK_MDIO_CMD_CMPL | \
98199 + TGEC_IMASK_REM_FAULT | \
98200 + TGEC_IMASK_LOC_FAULT | \
98201 + TGEC_IMASK_TX_ECC_ER | \
98202 + TGEC_IMASK_TX_FIFO_UNFL | \
98203 + TGEC_IMASK_TX_FIFO_OVFL | \
98204 + TGEC_IMASK_TX_ER | \
98205 + TGEC_IMASK_RX_FIFO_OVFL | \
98206 + TGEC_IMASK_RX_ECC_ER | \
98207 + TGEC_IMASK_RX_JAB_FRM | \
98208 + TGEC_IMASK_RX_OVRSZ_FRM | \
98209 + TGEC_IMASK_RX_RUNT_FRM | \
98210 + TGEC_IMASK_RX_FRAG_FRM | \
98211 + TGEC_IMASK_RX_LEN_ER | \
98212 + TGEC_IMASK_RX_CRC_ER | \
98213 + TGEC_IMASK_RX_ALIGN_ER))
98214 +
98215 +/* Hashtable Control Register (HASHTABLE_CTRL) */
98216 +#define TGEC_HASH_MCAST_SHIFT 23
98217 +#define TGEC_HASH_MCAST_EN 0x00000200
98218 +#define TGEC_HASH_ADR_MSK 0x000001ff
98219 +
98220 +#define DEFAULT_WAN_MODE_ENABLE FALSE
98221 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
98222 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
98223 +#define DEFAULT_PAUSE_IGNORE FALSE
98224 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
98225 +#define DEFAULT_LOOPBACK_ENABLE FALSE
98226 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
98227 +#define DEFAULT_RX_ERROR_DISCARD FALSE
98228 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
98229 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
98230 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
98231 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
98232 +#define DEFAULT_TX_IPG_LENGTH 12
98233 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
98234 +#define DEFAULT_PAUSE_QUANT 0xf000
98235 +
98236 +/*
98237 + * 10G memory map
98238 + */
98239 +struct tgec_regs {
98240 + uint32_t tgec_id; /* 0x000 Controller ID */
98241 + uint32_t reserved001[1]; /* 0x004 */
98242 + uint32_t command_config; /* 0x008 Control and configuration */
98243 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
98244 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
98245 + uint32_t maxfrm; /* 0x014 Maximum frame length */
98246 + uint32_t pause_quant; /* 0x018 Pause quanta */
98247 + uint32_t rx_fifo_sections; /* 0x01c */
98248 + uint32_t tx_fifo_sections; /* 0x020 */
98249 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
98250 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
98251 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
98252 + uint32_t mdio_cfg_status; /* 0x030 */
98253 + uint32_t mdio_command; /* 0x034 */
98254 + uint32_t mdio_data; /* 0x038 */
98255 + uint32_t mdio_regaddr; /* 0x03c */
98256 + uint32_t status; /* 0x040 */
98257 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
98258 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
98259 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
98260 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
98261 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
98262 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
98263 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
98264 + uint32_t imask; /* 0x060 Interrupt mask */
98265 + uint32_t ievent; /* 0x064 Interrupt event */
98266 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
98267 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
98268 + uint32_t reserved070[4]; /* 0x070 */
98269 + /*10Ge Statistics Counter */
98270 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
98271 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
98272 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
98273 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
98274 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
98275 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
98276 + uint32_t raln_u; /* 98 aAlignmentErrors */
98277 + uint32_t raln_l; /* 9c aAlignmentErrors */
98278 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
98279 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
98280 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
98281 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
98282 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
98283 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
98284 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
98285 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
98286 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
98287 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
98288 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
98289 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
98290 + uint32_t toct_u; /* D0 ifOutOctets */
98291 + uint32_t toct_l; /* D4 ifOutOctets */
98292 + uint32_t roct_u; /* D8 ifInOctets */
98293 + uint32_t roct_l; /* Dc ifInOctets */
98294 + uint32_t ruca_u; /* E0 ifInUcastPkts */
98295 + uint32_t ruca_l; /* E4 ifInUcastPkts */
98296 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
98297 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
98298 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
98299 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
98300 + uint32_t terr_u; /* F8 ifOutErrors */
98301 + uint32_t terr_l; /* Fc ifOutErrors */
98302 + uint32_t reserved100[2]; /* 100-108*/
98303 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
98304 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
98305 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
98306 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
98307 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
98308 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
98309 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
98310 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
98311 + uint32_t reoct_u; /* 128 etherStatsOctets */
98312 + uint32_t reoct_l; /* 12c etherStatsOctets */
98313 + uint32_t rpkt_u; /* 130 etherStatsPkts */
98314 + uint32_t rpkt_l; /* 134 etherStatsPkts */
98315 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
98316 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
98317 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
98318 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
98319 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
98320 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
98321 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
98322 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
98323 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
98324 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
98325 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
98326 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
98327 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
98328 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
98329 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
98330 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
98331 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
98332 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
98333 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
98334 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
98335 + uint32_t trfrg_u; /* 188 etherStatsFragments */
98336 + uint32_t trfrg_l; /* 18C etherStatsFragments */
98337 + uint32_t rerr_u; /* 190 ifInErrors */
98338 + uint32_t rerr_l; /* 194 ifInErrors */
98339 +};
98340 +
98341 +/**
98342 + * struct tgec_cfg - TGEC configuration
98343 + *
98344 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
98345 + * any frame received with an error is discarded in the
98346 + * Core and not forwarded to the Client interface.
98347 + * When set to 0 (Reset value), erroneous Frames are
98348 + * forwarded to the Client interface with ff_rx_err
98349 + * asserted.
98350 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
98351 + * frames are ignored by the MAC. When set to 0
98352 + * (Reset value) the transmit process is stopped for the
98353 + * amount of time specified in the pause quanta received
98354 + * within a pause frame.
98355 + * @pause_forward_enable:
98356 + * Terminate / Forward Pause Frames. If set to 1 pause
98357 + * frames are forwarded to the user application. When set
98358 + * to 0 (Reset value) pause frames are terminated and
98359 + * discarded within the MAC.
98360 + * @no_length_check_enable:
98361 + * Payload Length Check Disable. When set to 0
98362 + * (Reset value), the Core checks the frame's payload
98363 + * length with the Frame Length/Type field, when set to 1
98364 + * the payload length check is disabled.
98365 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
98366 + * all Command Frames are accepted, when set to 0
98367 + * (Reset Value) only Pause Frames are accepted and all
98368 + * other Command Frames are rejected.
98369 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
98370 + * permanently sends XGMII Idle sequences even when faults
98371 + * are received.
98372 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
98373 + * (0, default) of operation.
98374 + * @promiscuous_mode_enable:
98375 + * Enables MAC promiscuous operation. When set to 1, all
98376 + * frames are received without any MAC address filtering,
98377 + * when set to 0 (Reset value) Unicast Frames with a
98378 + * destination address not matching the Core MAC Address
98379 + * (MAC Address programmed in Registers MAC_ADDR_0 and
98380 + * MAC_ADDR_1 or the MAC address programmed in Registers
98381 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
98382 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
98383 + * MAC overwrites the source MAC address received from the
98384 + * Client Interface with one of the MAC addresses. If set
98385 + * to 0 (Reset value), the source MAC address from the
98386 + * Client Interface is transmitted unmodified to the line.
98387 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
98388 + * loop_ena is set to '1', when set to 0 (Reset value)
98389 + * the signal loop_ena is set to 0.
98390 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
98391 + * depending on the value of this Bit
98392 + * @time_stamp_enable: This bit selects between enabling and disabling the
98393 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
98394 + * 0: IEEE 1588 is disabled
98395 + * @max_frame_length: Maximum supported received frame length.
98396 + * The 10GEC MAC supports reception of any frame size up
98397 + * to 16,352 bytes (0x3FE0). Typical settings are
98398 + * 0x05EE (1,518 bytes) for standard frames.
98399 + * Default setting is 0x0600 (1,536 bytes).
98400 + * Received frames that exceed this stated maximum
98401 + * are truncated.
98402 + * @pause_quant: Pause quanta value used with transmitted pause frames.
98403 + * Each quanta represents a 512 bit-times.
98404 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
98405 + * Depending on LAN or WAN mode of operation the value has
98406 + * the following meaning: - LAN Mode: Number of octets in
98407 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
98408 + * fully supported (see 10.6.1 page 49) for any setting. A
98409 + * default of 12 (reset value) must be set to conform to
98410 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
98411 + * be able to perform clock rate compensation. - WAN Mode:
98412 + * Stretch factor. Valid values are 4..15. The stretch
98413 + * factor is calculated as (value+1)*8. A default of 12
98414 + * (reset value) must be set to conform to IEEE 802.3ae
98415 + * (i.e. 13*8=104). A larger value shrinks the IPG
98416 + * (increasing bandwidth).
98417 + *
98418 + * This structure contains basic TGEC configuration and must be passed to
98419 + * fman_tgec_init() function. A default set of configuration values can be
98420 + * obtained by calling fman_tgec_defconfig().
98421 + */
98422 +struct tgec_cfg {
98423 + bool rx_error_discard;
98424 + bool pause_ignore;
98425 + bool pause_forward_enable;
98426 + bool no_length_check_enable;
98427 + bool cmd_frame_enable;
98428 + bool send_idle_enable;
98429 + bool wan_mode_enable;
98430 + bool promiscuous_mode_enable;
98431 + bool tx_addr_ins_enable;
98432 + bool loopback_enable;
98433 + bool lgth_check_nostdr;
98434 + bool time_stamp_enable;
98435 + uint16_t max_frame_length;
98436 + uint16_t pause_quant;
98437 + uint32_t tx_ipg_length;
98438 + bool skip_fman11_workaround;
98439 +};
98440 +
98441 +
98442 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
98443 +
98444 +/**
98445 + * fman_tgec_init() - Init tgec hardware block
98446 + * @regs: Pointer to tgec register block
98447 + * @cfg: tgec configuration data
98448 + * @exceptions_mask: initial exceptions mask
98449 + *
98450 + * This function initializes the tgec controller and applies its
98451 + * basic configuration.
98452 + *
98453 + * Returns: 0 if successful, an error code otherwise.
98454 + */
98455 +
98456 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
98457 + uint32_t exception_mask);
98458 +
98459 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
98460 +
98461 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
98462 +
98463 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
98464 +
98465 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
98466 +
98467 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
98468 +
98469 +/**
98470 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
98471 + * @regs: Pointer to TGEC register block
98472 + */
98473 +void fman_tgec_reset_stat(struct tgec_regs *regs);
98474 +
98475 +/**
98476 + * fman_tgec_get_counter() - Reads TGEC HW counters
98477 + * @regs: Pointer to TGEC register block
98478 + * @reg_name: Counter name according to the appropriate enum
98479 + *
98480 + * Returns: Required counter value
98481 + */
98482 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
98483 + enum tgec_counters reg_name);
98484 +
98485 +/**
98486 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
98487 + * @regs: Pointer to TGEC register block
98488 + * @value: Value to be written in Hashtable Control Register
98489 + */
98490 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
98491 +
98492 +/**
98493 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
98494 + * @regs: Pointer to TGEC register block
98495 + * @pause_time: Pause quanta value used with transmitted pause frames.
98496 + * Each quanta represents a 512 bit-times
98497 + */
98498 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
98499 +
98500 +/**
98501 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
98502 + * @regs: Pointer to TGEC register block
98503 + * @en: Ignore/Respond to pause frame quanta
98504 + *
98505 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
98506 + * 0 - MAC stops transmit process for the duration specified
98507 + * in the Pause frame quanta of a received Pause frame.
98508 + * 1 - MAC ignores received Pause frames.
98509 + */
98510 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
98511 +
98512 +/**
98513 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
98514 + * @regs: Pointer to TGEC register block
98515 + * @en: enable/disable timestamp functionality
98516 + *
98517 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
98518 + * IEEE 1588 timestamp functionality control:
98519 + * 0 disabled, 1 enabled
98520 + */
98521 +
98522 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
98523 +
98524 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
98525 +
98526 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
98527 +
98528 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
98529 +
98530 +/**
98531 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
98532 + * @regs: Pointer to TGEC register block
98533 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
98534 + *
98535 + * Sets the additional station MAC address
98536 + */
98537 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
98538 +
98539 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
98540 +
98541 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
98542 +
98543 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
98544 +
98545 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
98546 +
98547 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
98548 +
98549 +
98550 +/**
98551 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
98552 + * @regs: Pointer to TGEC register block
98553 + */
98554 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
98555 +
98556 +/**
98557 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
98558 + * main tgec configuration parameters
98559 + * @regs: Pointer to TGEC register block
98560 + *
98561 + * TODO
98562 + */
98563 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
98564 + *regs);
98565 +
98566 +
98567 +#endif /* __FSL_FMAN_TGEC_H */
98568 --- /dev/null
98569 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
98570 @@ -0,0 +1,291 @@
98571 +/*
98572 + * Copyright 2012 Freescale Semiconductor Inc.
98573 + *
98574 + * Redistribution and use in source and binary forms, with or without
98575 + * modification, are permitted provided that the following conditions are met:
98576 + * * Redistributions of source code must retain the above copyright
98577 + * notice, this list of conditions and the following disclaimer.
98578 + * * Redistributions in binary form must reproduce the above copyright
98579 + * notice, this list of conditions and the following disclaimer in the
98580 + * documentation and/or other materials provided with the distribution.
98581 + * * Neither the name of Freescale Semiconductor nor the
98582 + * names of its contributors may be used to endorse or promote products
98583 + * derived from this software without specific prior written permission.
98584 + *
98585 + *
98586 + * ALTERNATIVELY, this software may be distributed under the terms of the
98587 + * GNU General Public License ("GPL") as published by the Free Software
98588 + * Foundation, either version 2 of that License or (at your option) any
98589 + * later version.
98590 + *
98591 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98592 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98593 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98594 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98595 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98596 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98597 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98598 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98599 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98600 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98601 + */
98602 +
98603 +/**
98604 +
98605 + @File dpaa_integration_ext.h
98606 +
98607 + @Description T4240 FM external definitions and structures.
98608 +*//***************************************************************************/
98609 +#ifndef __DPAA_INTEGRATION_EXT_H
98610 +#define __DPAA_INTEGRATION_EXT_H
98611 +
98612 +#include "std_ext.h"
98613 +
98614 +
98615 +#define DPAA_VERSION 11
98616 +
98617 +/**************************************************************************//**
98618 + @Description DPAA SW Portals Enumeration.
98619 +*//***************************************************************************/
98620 +typedef enum
98621 +{
98622 + e_DPAA_SWPORTAL0 = 0,
98623 + e_DPAA_SWPORTAL1,
98624 + e_DPAA_SWPORTAL2,
98625 + e_DPAA_SWPORTAL3,
98626 + e_DPAA_SWPORTAL4,
98627 + e_DPAA_SWPORTAL5,
98628 + e_DPAA_SWPORTAL6,
98629 + e_DPAA_SWPORTAL7,
98630 + e_DPAA_SWPORTAL8,
98631 + e_DPAA_SWPORTAL9,
98632 + e_DPAA_SWPORTAL10,
98633 + e_DPAA_SWPORTAL11,
98634 + e_DPAA_SWPORTAL12,
98635 + e_DPAA_SWPORTAL13,
98636 + e_DPAA_SWPORTAL14,
98637 + e_DPAA_SWPORTAL15,
98638 + e_DPAA_SWPORTAL16,
98639 + e_DPAA_SWPORTAL17,
98640 + e_DPAA_SWPORTAL18,
98641 + e_DPAA_SWPORTAL19,
98642 + e_DPAA_SWPORTAL20,
98643 + e_DPAA_SWPORTAL21,
98644 + e_DPAA_SWPORTAL22,
98645 + e_DPAA_SWPORTAL23,
98646 + e_DPAA_SWPORTAL24,
98647 + e_DPAA_SWPORTAL_DUMMY_LAST
98648 +} e_DpaaSwPortal;
98649 +
98650 +/**************************************************************************//**
98651 + @Description DPAA Direct Connect Portals Enumeration.
98652 +*//***************************************************************************/
98653 +typedef enum
98654 +{
98655 + e_DPAA_DCPORTAL0 = 0,
98656 + e_DPAA_DCPORTAL1,
98657 + e_DPAA_DCPORTAL2,
98658 + e_DPAA_DCPORTAL_DUMMY_LAST
98659 +} e_DpaaDcPortal;
98660 +
98661 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98662 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98663 +
98664 +/*****************************************************************************
98665 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98666 +******************************************************************************/
98667 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98668 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98669 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98670 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98671 + /**< FQIDs range - 24 bits */
98672 +
98673 +/**************************************************************************//**
98674 + @Description Work Queue Channel assignments in QMan.
98675 +*//***************************************************************************/
98676 +typedef enum
98677 +{
98678 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98679 + e_QM_FQ_CHANNEL_SWPORTAL1,
98680 + e_QM_FQ_CHANNEL_SWPORTAL2,
98681 + e_QM_FQ_CHANNEL_SWPORTAL3,
98682 + e_QM_FQ_CHANNEL_SWPORTAL4,
98683 + e_QM_FQ_CHANNEL_SWPORTAL5,
98684 + e_QM_FQ_CHANNEL_SWPORTAL6,
98685 + e_QM_FQ_CHANNEL_SWPORTAL7,
98686 + e_QM_FQ_CHANNEL_SWPORTAL8,
98687 + e_QM_FQ_CHANNEL_SWPORTAL9,
98688 + e_QM_FQ_CHANNEL_SWPORTAL10,
98689 + e_QM_FQ_CHANNEL_SWPORTAL11,
98690 + e_QM_FQ_CHANNEL_SWPORTAL12,
98691 + e_QM_FQ_CHANNEL_SWPORTAL13,
98692 + e_QM_FQ_CHANNEL_SWPORTAL14,
98693 + e_QM_FQ_CHANNEL_SWPORTAL15,
98694 + e_QM_FQ_CHANNEL_SWPORTAL16,
98695 + e_QM_FQ_CHANNEL_SWPORTAL17,
98696 + e_QM_FQ_CHANNEL_SWPORTAL18,
98697 + e_QM_FQ_CHANNEL_SWPORTAL19,
98698 + e_QM_FQ_CHANNEL_SWPORTAL20,
98699 + e_QM_FQ_CHANNEL_SWPORTAL21,
98700 + e_QM_FQ_CHANNEL_SWPORTAL22,
98701 + e_QM_FQ_CHANNEL_SWPORTAL23,
98702 + e_QM_FQ_CHANNEL_SWPORTAL24,
98703 +
98704 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98705 + e_QM_FQ_CHANNEL_POOL2,
98706 + e_QM_FQ_CHANNEL_POOL3,
98707 + e_QM_FQ_CHANNEL_POOL4,
98708 + e_QM_FQ_CHANNEL_POOL5,
98709 + e_QM_FQ_CHANNEL_POOL6,
98710 + e_QM_FQ_CHANNEL_POOL7,
98711 + e_QM_FQ_CHANNEL_POOL8,
98712 + e_QM_FQ_CHANNEL_POOL9,
98713 + e_QM_FQ_CHANNEL_POOL10,
98714 + e_QM_FQ_CHANNEL_POOL11,
98715 + e_QM_FQ_CHANNEL_POOL12,
98716 + e_QM_FQ_CHANNEL_POOL13,
98717 + e_QM_FQ_CHANNEL_POOL14,
98718 + e_QM_FQ_CHANNEL_POOL15,
98719 +
98720 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98721 + connected to FMan 0; assigned in incrementing order to
98722 + each sub-portal (SP) in the portal */
98723 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98724 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98725 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98726 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98727 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98728 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98729 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98730 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98731 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98732 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98733 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98734 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98735 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98736 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98737 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98738 +
98739 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98740 + e_QM_FQ_CHANNEL_RMAN_SP1,
98741 +
98742 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98743 + connected to SEC */
98744 +} e_QmFQChannel;
98745 +
98746 +/*****************************************************************************
98747 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98748 +******************************************************************************/
98749 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98750 +
98751 +/*****************************************************************************
98752 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98753 +******************************************************************************/
98754 +#define SEC_NUM_OF_DECOS 3
98755 +#define SEC_ALL_DECOS_MASK 0x00000003
98756 +
98757 +
98758 +/*****************************************************************************
98759 + FM INTEGRATION-SPECIFIC DEFINITIONS
98760 +******************************************************************************/
98761 +#define INTG_MAX_NUM_OF_FM 2
98762 +/* Ports defines */
98763 +#define FM_MAX_NUM_OF_1G_MACS 6
98764 +#define FM_MAX_NUM_OF_10G_MACS 2
98765 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98766 +#define FM_MAX_NUM_OF_OH_PORTS 6
98767 +
98768 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98769 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98770 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98771 +
98772 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98773 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98774 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98775 +
98776 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98777 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98778 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98779 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98780 +
98781 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
98782 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98783 +
98784 +/* RAMs defines */
98785 +#define FM_MURAM_SIZE (384 * KILOBYTE)
98786 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
98787 +#define FM_NUM_OF_CTRL 4
98788 +
98789 +/* PCD defines */
98790 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98791 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98792 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98793 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98794 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98795 +
98796 +/* RTC defines */
98797 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98798 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98799 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98800 +
98801 +/* QMI defines */
98802 +#define QMI_MAX_NUM_OF_TNUMS 64
98803 +#define QMI_DEF_TNUMS_THRESH 32
98804 +/* FPM defines */
98805 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98806 +
98807 +/* DMA defines */
98808 +#define DMA_THRESH_MAX_COMMQ 83
98809 +#define DMA_THRESH_MAX_BUF 127
98810 +
98811 +/* BMI defines */
98812 +#define BMI_MAX_NUM_OF_TASKS 128
98813 +#define BMI_MAX_NUM_OF_DMAS 84
98814 +
98815 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98816 +#define PORT_MAX_WEIGHT 16
98817 +
98818 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98819 +
98820 +/* Unique T4240 */
98821 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98822 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98823 +#define FM_NO_OP_OBSERVED_POOLS
98824 +#define FM_FRAME_END_PARAMS_FOR_OP
98825 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98826 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98827 +
98828 +#define FM_NO_GUARANTEED_RESET_VALUES
98829 +
98830 +/* FM errata */
98831 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98832 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
98833 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98834 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98835 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98836 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
98837 +
98838 +#define FM_BCB_ERRATA_BMI_SW001
98839 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98840 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98841 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98842 +
98843 +/*****************************************************************************
98844 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98845 +******************************************************************************/
98846 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98847 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98848 +
98849 +/* RMan erratas */
98850 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98851 +
98852 +/*****************************************************************************
98853 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98854 +******************************************************************************/
98855 +#define NUM_OF_RX_SC 16
98856 +#define NUM_OF_TX_SC 16
98857 +
98858 +#define NUM_OF_SA_PER_RX_SC 2
98859 +#define NUM_OF_SA_PER_TX_SC 2
98860 +
98861 +#endif /* __DPAA_INTEGRATION_EXT_H */
98862 --- /dev/null
98863 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
98864 @@ -0,0 +1,71 @@
98865 +/*
98866 + * Copyright 2012 Freescale Semiconductor Inc.
98867 + *
98868 + * Redistribution and use in source and binary forms, with or without
98869 + * modification, are permitted provided that the following conditions are met:
98870 + * * Redistributions of source code must retain the above copyright
98871 + * notice, this list of conditions and the following disclaimer.
98872 + * * Redistributions in binary form must reproduce the above copyright
98873 + * notice, this list of conditions and the following disclaimer in the
98874 + * documentation and/or other materials provided with the distribution.
98875 + * * Neither the name of Freescale Semiconductor nor the
98876 + * names of its contributors may be used to endorse or promote products
98877 + * derived from this software without specific prior written permission.
98878 + *
98879 + *
98880 + * ALTERNATIVELY, this software may be distributed under the terms of the
98881 + * GNU General Public License ("GPL") as published by the Free Software
98882 + * Foundation, either version 2 of that License or (at your option) any
98883 + * later version.
98884 + *
98885 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98886 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98887 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98888 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98889 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98890 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98891 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98892 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98893 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98894 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98895 + */
98896 +
98897 +/**************************************************************************//**
98898 +
98899 + @File part_ext.h
98900 +
98901 + @Description Definitions for the part (integration) module.
98902 +*//***************************************************************************/
98903 +
98904 +#ifndef __PART_EXT_H
98905 +#define __PART_EXT_H
98906 +
98907 +#include "std_ext.h"
98908 +#include "part_integration_ext.h"
98909 +
98910 +#if !(defined(P1023) || \
98911 + defined(P2041) || \
98912 + defined(P3041) || \
98913 + defined(P4080) || \
98914 + defined(P5020) || \
98915 + defined(P5040) || \
98916 + defined(B4860) || \
98917 + defined(T4240))
98918 +#error "unable to proceed without chip-definition"
98919 +#endif
98920 +
98921 +
98922 +/**************************************************************************//*
98923 + @Description Part data structure - must be contained in any integration
98924 + data structure.
98925 +*//***************************************************************************/
98926 +typedef struct t_Part
98927 +{
98928 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98929 + /**< Returns the address of the module's memory map base. */
98930 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98931 + /**< Returns the module's ID according to its memory map base. */
98932 +} t_Part;
98933 +
98934 +
98935 +#endif /* __PART_EXT_H */
98936 --- /dev/null
98937 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
98938 @@ -0,0 +1,304 @@
98939 +/*
98940 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98941 + *
98942 + * Redistribution and use in source and binary forms, with or without
98943 + * modification, are permitted provided that the following conditions are met:
98944 + * * Redistributions of source code must retain the above copyright
98945 + * notice, this list of conditions and the following disclaimer.
98946 + * * Redistributions in binary form must reproduce the above copyright
98947 + * notice, this list of conditions and the following disclaimer in the
98948 + * documentation and/or other materials provided with the distribution.
98949 + * * Neither the name of Freescale Semiconductor nor the
98950 + * names of its contributors may be used to endorse or promote products
98951 + * derived from this software without specific prior written permission.
98952 + *
98953 + *
98954 + * ALTERNATIVELY, this software may be distributed under the terms of the
98955 + * GNU General Public License ("GPL") as published by the Free Software
98956 + * Foundation, either version 2 of that License or (at your option) any
98957 + * later version.
98958 + *
98959 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98960 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98961 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98962 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98963 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98964 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98965 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98966 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98967 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98968 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98969 + */
98970 +
98971 +/**
98972 +
98973 + @File part_integration_ext.h
98974 +
98975 + @Description T4240 external definitions and structures.
98976 +*//***************************************************************************/
98977 +#ifndef __PART_INTEGRATION_EXT_H
98978 +#define __PART_INTEGRATION_EXT_H
98979 +
98980 +#include "std_ext.h"
98981 +#include "ddr_std_ext.h"
98982 +#include "enet_ext.h"
98983 +#include "dpaa_integration_ext.h"
98984 +
98985 +
98986 +/**************************************************************************//**
98987 + @Group T4240_chip_id T4240 Application Programming Interface
98988 +
98989 + @Description T4240 Chip functions,definitions and enums.
98990 +
98991 + @{
98992 +*//***************************************************************************/
98993 +
98994 +#define CORE_E6500
98995 +
98996 +#define INTG_MAX_NUM_OF_CORES 24
98997 +
98998 +
98999 +/**************************************************************************//**
99000 + @Description Module types.
99001 +*//***************************************************************************/
99002 +typedef enum e_ModuleId
99003 +{
99004 + e_MODULE_ID_DUART_1 = 0,
99005 + e_MODULE_ID_DUART_2,
99006 + e_MODULE_ID_DUART_3,
99007 + e_MODULE_ID_DUART_4,
99008 + e_MODULE_ID_LAW,
99009 + e_MODULE_ID_IFC,
99010 + e_MODULE_ID_PAMU,
99011 + e_MODULE_ID_QM, /**< Queue manager module */
99012 + e_MODULE_ID_BM, /**< Buffer manager module */
99013 + e_MODULE_ID_QM_CE_PORTAL_0,
99014 + e_MODULE_ID_QM_CI_PORTAL_0,
99015 + e_MODULE_ID_QM_CE_PORTAL_1,
99016 + e_MODULE_ID_QM_CI_PORTAL_1,
99017 + e_MODULE_ID_QM_CE_PORTAL_2,
99018 + e_MODULE_ID_QM_CI_PORTAL_2,
99019 + e_MODULE_ID_QM_CE_PORTAL_3,
99020 + e_MODULE_ID_QM_CI_PORTAL_3,
99021 + e_MODULE_ID_QM_CE_PORTAL_4,
99022 + e_MODULE_ID_QM_CI_PORTAL_4,
99023 + e_MODULE_ID_QM_CE_PORTAL_5,
99024 + e_MODULE_ID_QM_CI_PORTAL_5,
99025 + e_MODULE_ID_QM_CE_PORTAL_6,
99026 + e_MODULE_ID_QM_CI_PORTAL_6,
99027 + e_MODULE_ID_QM_CE_PORTAL_7,
99028 + e_MODULE_ID_QM_CI_PORTAL_7,
99029 + e_MODULE_ID_QM_CE_PORTAL_8,
99030 + e_MODULE_ID_QM_CI_PORTAL_8,
99031 + e_MODULE_ID_QM_CE_PORTAL_9,
99032 + e_MODULE_ID_QM_CI_PORTAL_9,
99033 + e_MODULE_ID_BM_CE_PORTAL_0,
99034 + e_MODULE_ID_BM_CI_PORTAL_0,
99035 + e_MODULE_ID_BM_CE_PORTAL_1,
99036 + e_MODULE_ID_BM_CI_PORTAL_1,
99037 + e_MODULE_ID_BM_CE_PORTAL_2,
99038 + e_MODULE_ID_BM_CI_PORTAL_2,
99039 + e_MODULE_ID_BM_CE_PORTAL_3,
99040 + e_MODULE_ID_BM_CI_PORTAL_3,
99041 + e_MODULE_ID_BM_CE_PORTAL_4,
99042 + e_MODULE_ID_BM_CI_PORTAL_4,
99043 + e_MODULE_ID_BM_CE_PORTAL_5,
99044 + e_MODULE_ID_BM_CI_PORTAL_5,
99045 + e_MODULE_ID_BM_CE_PORTAL_6,
99046 + e_MODULE_ID_BM_CI_PORTAL_6,
99047 + e_MODULE_ID_BM_CE_PORTAL_7,
99048 + e_MODULE_ID_BM_CI_PORTAL_7,
99049 + e_MODULE_ID_BM_CE_PORTAL_8,
99050 + e_MODULE_ID_BM_CI_PORTAL_8,
99051 + e_MODULE_ID_BM_CE_PORTAL_9,
99052 + e_MODULE_ID_BM_CI_PORTAL_9,
99053 + e_MODULE_ID_FM, /**< Frame manager module */
99054 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99055 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99056 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99057 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99058 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
99059 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99060 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99061 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99062 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99063 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
99064 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
99065 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
99066 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99067 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
99068 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
99069 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
99070 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
99071 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
99072 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
99073 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
99074 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99075 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
99076 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
99077 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
99078 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
99079 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
99080 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
99081 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
99082 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99083 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99084 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99085 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99086 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99087 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
99088 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
99089 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99090 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99091 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
99092 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
99093 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
99094 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
99095 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
99096 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
99097 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
99098 +
99099 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99100 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99101 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99102 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99103 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99104 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99105 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99106 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99107 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99108 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99109 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99110 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99111 +
99112 + e_MODULE_ID_PIC, /**< PIC */
99113 + e_MODULE_ID_GPIO, /**< GPIO */
99114 + e_MODULE_ID_SERDES, /**< SERDES */
99115 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
99116 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
99117 +
99118 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
99119 +
99120 + e_MODULE_ID_DUMMY_LAST
99121 +} e_ModuleId;
99122 +
99123 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99124 +
99125 +#if 0 /* using unified values */
99126 +/*****************************************************************************
99127 + INTEGRATION-SPECIFIC MODULE CODES
99128 +******************************************************************************/
99129 +#define MODULE_UNKNOWN 0x00000000
99130 +#define MODULE_MEM 0x00010000
99131 +#define MODULE_MM 0x00020000
99132 +#define MODULE_CORE 0x00030000
99133 +#define MODULE_T4240 0x00040000
99134 +#define MODULE_T4240_PLATFORM 0x00050000
99135 +#define MODULE_PM 0x00060000
99136 +#define MODULE_MMU 0x00070000
99137 +#define MODULE_PIC 0x00080000
99138 +#define MODULE_CPC 0x00090000
99139 +#define MODULE_DUART 0x000a0000
99140 +#define MODULE_SERDES 0x000b0000
99141 +#define MODULE_PIO 0x000c0000
99142 +#define MODULE_QM 0x000d0000
99143 +#define MODULE_BM 0x000e0000
99144 +#define MODULE_SEC 0x000f0000
99145 +#define MODULE_LAW 0x00100000
99146 +#define MODULE_LBC 0x00110000
99147 +#define MODULE_PAMU 0x00120000
99148 +#define MODULE_FM 0x00130000
99149 +#define MODULE_FM_MURAM 0x00140000
99150 +#define MODULE_FM_PCD 0x00150000
99151 +#define MODULE_FM_RTC 0x00160000
99152 +#define MODULE_FM_MAC 0x00170000
99153 +#define MODULE_FM_PORT 0x00180000
99154 +#define MODULE_FM_SP 0x00190000
99155 +#define MODULE_DPA_PORT 0x001a0000
99156 +#define MODULE_MII 0x001b0000
99157 +#define MODULE_I2C 0x001c0000
99158 +#define MODULE_DMA 0x001d0000
99159 +#define MODULE_DDR 0x001e0000
99160 +#define MODULE_ESPI 0x001f0000
99161 +#define MODULE_DPAA_IPSEC 0x00200000
99162 +#endif /* using unified values */
99163 +
99164 +/*****************************************************************************
99165 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
99166 +******************************************************************************/
99167 +#define PAMU_NUM_OF_PARTITIONS 4
99168 +
99169 +/*****************************************************************************
99170 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99171 +******************************************************************************/
99172 +#define LAW_NUM_OF_WINDOWS 32
99173 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
99174 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
99175 +
99176 +
99177 +/*****************************************************************************
99178 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99179 +******************************************************************************/
99180 +/**************************************************************************//**
99181 + @Group lbc_exception_grp LBC Exception Unit
99182 +
99183 + @Description LBC Exception unit API functions, definitions and enums
99184 +
99185 + @{
99186 +*//***************************************************************************/
99187 +
99188 +/**************************************************************************//**
99189 + @Anchor lbc_exbm
99190 +
99191 + @Collection LBC Errors Bit Mask
99192 +
99193 + These errors are reported through the exceptions callback..
99194 + The values can be or'ed in any combination in the errors mask
99195 + parameter of the errors report structure.
99196 +
99197 + These errors can also be passed as a bit-mask to
99198 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99199 + for enabling or disabling error checking.
99200 + @{
99201 +*//***************************************************************************/
99202 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99203 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99204 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99205 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99206 +
99207 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99208 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99209 + /**< All possible errors */
99210 +/* @} */
99211 +/** @} */ /* end of lbc_exception_grp group */
99212 +
99213 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
99214 +
99215 +#define LBC_NUM_OF_BANKS 8
99216 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
99217 +#define LBC_PARITY_SUPPORT
99218 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99219 +#define LBC_HIGH_CLK_DIVIDERS
99220 +#define LBC_FCM_AVAILABLE
99221 +
99222 +/*****************************************************************************
99223 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
99224 +******************************************************************************/
99225 +#define GPIO_PORT_OFFSET_0x1000
99226 +
99227 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
99228 + Each port contains up to 32 I/O pins. */
99229 +
99230 +#define GPIO_VALID_PIN_MASKS \
99231 + { /* Port A */ 0xFFFFFFFF, \
99232 + /* Port B */ 0xFFFFFFFF, \
99233 + /* Port C */ 0xFFFFFFFF }
99234 +
99235 +#define GPIO_VALID_INTR_MASKS \
99236 + { /* Port A */ 0xFFFFFFFF, \
99237 + /* Port B */ 0xFFFFFFFF, \
99238 + /* Port C */ 0xFFFFFFFF }
99239 +
99240 +
99241 +
99242 +#endif /* __PART_INTEGRATION_EXT_H */
99243 --- /dev/null
99244 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
99245 @@ -0,0 +1,293 @@
99246 +/*
99247 + * Copyright 2012 Freescale Semiconductor Inc.
99248 + *
99249 + * Redistribution and use in source and binary forms, with or without
99250 + * modification, are permitted provided that the following conditions are met:
99251 + * * Redistributions of source code must retain the above copyright
99252 + * notice, this list of conditions and the following disclaimer.
99253 + * * Redistributions in binary form must reproduce the above copyright
99254 + * notice, this list of conditions and the following disclaimer in the
99255 + * documentation and/or other materials provided with the distribution.
99256 + * * Neither the name of Freescale Semiconductor nor the
99257 + * names of its contributors may be used to endorse or promote products
99258 + * derived from this software without specific prior written permission.
99259 + *
99260 + *
99261 + * ALTERNATIVELY, this software may be distributed under the terms of the
99262 + * GNU General Public License ("GPL") as published by the Free Software
99263 + * Foundation, either version 2 of that License or (at your option) any
99264 + * later version.
99265 + *
99266 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99267 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99268 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99269 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99270 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99271 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99272 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99273 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99274 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99275 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99276 + */
99277 +
99278 +/**
99279 +
99280 + @File dpaa_integration_ext.h
99281 +
99282 + @Description T4240 FM external definitions and structures.
99283 +*//***************************************************************************/
99284 +#ifndef __DPAA_INTEGRATION_EXT_H
99285 +#define __DPAA_INTEGRATION_EXT_H
99286 +
99287 +#include "std_ext.h"
99288 +
99289 +
99290 +#define DPAA_VERSION 11
99291 +
99292 +/**************************************************************************//**
99293 + @Description DPAA SW Portals Enumeration.
99294 +*//***************************************************************************/
99295 +typedef enum
99296 +{
99297 + e_DPAA_SWPORTAL0 = 0,
99298 + e_DPAA_SWPORTAL1,
99299 + e_DPAA_SWPORTAL2,
99300 + e_DPAA_SWPORTAL3,
99301 + e_DPAA_SWPORTAL4,
99302 + e_DPAA_SWPORTAL5,
99303 + e_DPAA_SWPORTAL6,
99304 + e_DPAA_SWPORTAL7,
99305 + e_DPAA_SWPORTAL8,
99306 + e_DPAA_SWPORTAL9,
99307 + e_DPAA_SWPORTAL10,
99308 + e_DPAA_SWPORTAL11,
99309 + e_DPAA_SWPORTAL12,
99310 + e_DPAA_SWPORTAL13,
99311 + e_DPAA_SWPORTAL14,
99312 + e_DPAA_SWPORTAL15,
99313 + e_DPAA_SWPORTAL16,
99314 + e_DPAA_SWPORTAL17,
99315 + e_DPAA_SWPORTAL18,
99316 + e_DPAA_SWPORTAL19,
99317 + e_DPAA_SWPORTAL20,
99318 + e_DPAA_SWPORTAL21,
99319 + e_DPAA_SWPORTAL22,
99320 + e_DPAA_SWPORTAL23,
99321 + e_DPAA_SWPORTAL24,
99322 + e_DPAA_SWPORTAL_DUMMY_LAST
99323 +} e_DpaaSwPortal;
99324 +
99325 +/**************************************************************************//**
99326 + @Description DPAA Direct Connect Portals Enumeration.
99327 +*//***************************************************************************/
99328 +typedef enum
99329 +{
99330 + e_DPAA_DCPORTAL0 = 0,
99331 + e_DPAA_DCPORTAL1,
99332 + e_DPAA_DCPORTAL2,
99333 + e_DPAA_DCPORTAL_DUMMY_LAST
99334 +} e_DpaaDcPortal;
99335 +
99336 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99337 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99338 +
99339 +/*****************************************************************************
99340 + QMan INTEGRATION-SPECIFIC DEFINITIONS
99341 +******************************************************************************/
99342 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
99343 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
99344 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
99345 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
99346 + /**< FQIDs range - 24 bits */
99347 +
99348 +/**************************************************************************//**
99349 + @Description Work Queue Channel assignments in QMan.
99350 +*//***************************************************************************/
99351 +typedef enum
99352 +{
99353 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
99354 + e_QM_FQ_CHANNEL_SWPORTAL1,
99355 + e_QM_FQ_CHANNEL_SWPORTAL2,
99356 + e_QM_FQ_CHANNEL_SWPORTAL3,
99357 + e_QM_FQ_CHANNEL_SWPORTAL4,
99358 + e_QM_FQ_CHANNEL_SWPORTAL5,
99359 + e_QM_FQ_CHANNEL_SWPORTAL6,
99360 + e_QM_FQ_CHANNEL_SWPORTAL7,
99361 + e_QM_FQ_CHANNEL_SWPORTAL8,
99362 + e_QM_FQ_CHANNEL_SWPORTAL9,
99363 + e_QM_FQ_CHANNEL_SWPORTAL10,
99364 + e_QM_FQ_CHANNEL_SWPORTAL11,
99365 + e_QM_FQ_CHANNEL_SWPORTAL12,
99366 + e_QM_FQ_CHANNEL_SWPORTAL13,
99367 + e_QM_FQ_CHANNEL_SWPORTAL14,
99368 + e_QM_FQ_CHANNEL_SWPORTAL15,
99369 + e_QM_FQ_CHANNEL_SWPORTAL16,
99370 + e_QM_FQ_CHANNEL_SWPORTAL17,
99371 + e_QM_FQ_CHANNEL_SWPORTAL18,
99372 + e_QM_FQ_CHANNEL_SWPORTAL19,
99373 + e_QM_FQ_CHANNEL_SWPORTAL20,
99374 + e_QM_FQ_CHANNEL_SWPORTAL21,
99375 + e_QM_FQ_CHANNEL_SWPORTAL22,
99376 + e_QM_FQ_CHANNEL_SWPORTAL23,
99377 + e_QM_FQ_CHANNEL_SWPORTAL24,
99378 +
99379 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
99380 + e_QM_FQ_CHANNEL_POOL2,
99381 + e_QM_FQ_CHANNEL_POOL3,
99382 + e_QM_FQ_CHANNEL_POOL4,
99383 + e_QM_FQ_CHANNEL_POOL5,
99384 + e_QM_FQ_CHANNEL_POOL6,
99385 + e_QM_FQ_CHANNEL_POOL7,
99386 + e_QM_FQ_CHANNEL_POOL8,
99387 + e_QM_FQ_CHANNEL_POOL9,
99388 + e_QM_FQ_CHANNEL_POOL10,
99389 + e_QM_FQ_CHANNEL_POOL11,
99390 + e_QM_FQ_CHANNEL_POOL12,
99391 + e_QM_FQ_CHANNEL_POOL13,
99392 + e_QM_FQ_CHANNEL_POOL14,
99393 + e_QM_FQ_CHANNEL_POOL15,
99394 +
99395 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
99396 + connected to FMan 0; assigned in incrementing order to
99397 + each sub-portal (SP) in the portal */
99398 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99399 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99400 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99401 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99402 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99403 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99404 + e_QM_FQ_CHANNEL_FMAN0_SP7,
99405 + e_QM_FQ_CHANNEL_FMAN0_SP8,
99406 + e_QM_FQ_CHANNEL_FMAN0_SP9,
99407 + e_QM_FQ_CHANNEL_FMAN0_SP10,
99408 + e_QM_FQ_CHANNEL_FMAN0_SP11,
99409 + e_QM_FQ_CHANNEL_FMAN0_SP12,
99410 + e_QM_FQ_CHANNEL_FMAN0_SP13,
99411 + e_QM_FQ_CHANNEL_FMAN0_SP14,
99412 + e_QM_FQ_CHANNEL_FMAN0_SP15,
99413 +
99414 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
99415 + e_QM_FQ_CHANNEL_RMAN_SP1,
99416 +
99417 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
99418 + connected to SEC */
99419 +} e_QmFQChannel;
99420 +
99421 +/*****************************************************************************
99422 + BMan INTEGRATION-SPECIFIC DEFINITIONS
99423 +******************************************************************************/
99424 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
99425 +
99426 +/*****************************************************************************
99427 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99428 +******************************************************************************/
99429 +#define SEC_NUM_OF_DECOS 3
99430 +#define SEC_ALL_DECOS_MASK 0x00000003
99431 +
99432 +
99433 +/*****************************************************************************
99434 + FM INTEGRATION-SPECIFIC DEFINITIONS
99435 +******************************************************************************/
99436 +#define INTG_MAX_NUM_OF_FM 1
99437 +/* Ports defines */
99438 +#define FM_MAX_NUM_OF_1G_MACS 5
99439 +#define FM_MAX_NUM_OF_10G_MACS 1
99440 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99441 +#define FM_MAX_NUM_OF_OH_PORTS 4
99442 +
99443 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99444 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99445 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99446 +
99447 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99448 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99449 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99450 +
99451 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
99452 +
99453 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99454 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
99455 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
99456 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
99457 +
99458 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
99459 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
99460 +
99461 +/* RAMs defines */
99462 +#define FM_MURAM_SIZE (192 * KILOBYTE)
99463 +#define FM_IRAM_SIZE(major, minor) \
99464 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
99465 +#define FM_NUM_OF_CTRL 2
99466 +
99467 +/* PCD defines */
99468 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
99469 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
99470 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
99471 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
99472 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99473 +
99474 +/* RTC defines */
99475 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
99476 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
99477 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
99478 +
99479 +/* QMI defines */
99480 +#define QMI_MAX_NUM_OF_TNUMS 64
99481 +#define QMI_DEF_TNUMS_THRESH 32
99482 +/* FPM defines */
99483 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99484 +
99485 +/* DMA defines */
99486 +#define DMA_THRESH_MAX_COMMQ 83
99487 +#define DMA_THRESH_MAX_BUF 127
99488 +
99489 +/* BMI defines */
99490 +#define BMI_MAX_NUM_OF_TASKS 64
99491 +#define BMI_MAX_NUM_OF_DMAS 32
99492 +
99493 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99494 +#define PORT_MAX_WEIGHT 16
99495 +
99496 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
99497 +
99498 +/* Unique T4240 */
99499 +#define FM_OP_OPEN_DMA_MIN_LIMIT
99500 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
99501 +#define FM_NO_OP_OBSERVED_POOLS
99502 +#define FM_FRAME_END_PARAMS_FOR_OP
99503 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99504 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
99505 +
99506 +#define FM_NO_GUARANTEED_RESET_VALUES
99507 +
99508 +/* FM errata */
99509 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
99510 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
99511 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
99512 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
99513 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
99514 +
99515 +#define FM_BCB_ERRATA_BMI_SW001
99516 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
99517 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
99518 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
99519 +
99520 +/*****************************************************************************
99521 + RMan INTEGRATION-SPECIFIC DEFINITIONS
99522 +******************************************************************************/
99523 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
99524 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
99525 +
99526 +/* RMan erratas */
99527 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
99528 +
99529 +/*****************************************************************************
99530 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99531 +******************************************************************************/
99532 +#define NUM_OF_RX_SC 16
99533 +#define NUM_OF_TX_SC 16
99534 +
99535 +#define NUM_OF_SA_PER_RX_SC 2
99536 +#define NUM_OF_SA_PER_TX_SC 2
99537 +
99538 +#endif /* __DPAA_INTEGRATION_EXT_H */
99539 --- /dev/null
99540 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
99541 @@ -0,0 +1,59 @@
99542 +/*
99543 + * Copyright 2012 Freescale Semiconductor Inc.
99544 + *
99545 + * Redistribution and use in source and binary forms, with or without
99546 + * modification, are permitted provided that the following conditions are met:
99547 + * * Redistributions of source code must retain the above copyright
99548 + * notice, this list of conditions and the following disclaimer.
99549 + * * Redistributions in binary form must reproduce the above copyright
99550 + * notice, this list of conditions and the following disclaimer in the
99551 + * documentation and/or other materials provided with the distribution.
99552 + * * Neither the name of Freescale Semiconductor nor the
99553 + * names of its contributors may be used to endorse or promote products
99554 + * derived from this software without specific prior written permission.
99555 + *
99556 + *
99557 + * ALTERNATIVELY, this software may be distributed under the terms of the
99558 + * GNU General Public License ("GPL") as published by the Free Software
99559 + * Foundation, either version 2 of that License or (at your option) any
99560 + * later version.
99561 + *
99562 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99563 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99564 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99565 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99566 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99567 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99568 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99569 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99570 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99571 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99572 + */
99573 +
99574 +/**************************************************************************//**
99575 +
99576 + @File part_ext.h
99577 +
99578 + @Description Definitions for the part (integration) module.
99579 +*//***************************************************************************/
99580 +
99581 +#ifndef __PART_EXT_H
99582 +#define __PART_EXT_H
99583 +
99584 +#include "std_ext.h"
99585 +#include "part_integration_ext.h"
99586 +
99587 +/**************************************************************************//*
99588 + @Description Part data structure - must be contained in any integration
99589 + data structure.
99590 +*//***************************************************************************/
99591 +typedef struct t_Part
99592 +{
99593 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99594 + /**< Returns the address of the module's memory map base. */
99595 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
99596 + /**< Returns the module's ID according to its memory map base. */
99597 +} t_Part;
99598 +
99599 +
99600 +#endif /* __PART_EXT_H */
99601 --- /dev/null
99602 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
99603 @@ -0,0 +1,304 @@
99604 +/*
99605 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99606 + *
99607 + * Redistribution and use in source and binary forms, with or without
99608 + * modification, are permitted provided that the following conditions are met:
99609 + * * Redistributions of source code must retain the above copyright
99610 + * notice, this list of conditions and the following disclaimer.
99611 + * * Redistributions in binary form must reproduce the above copyright
99612 + * notice, this list of conditions and the following disclaimer in the
99613 + * documentation and/or other materials provided with the distribution.
99614 + * * Neither the name of Freescale Semiconductor nor the
99615 + * names of its contributors may be used to endorse or promote products
99616 + * derived from this software without specific prior written permission.
99617 + *
99618 + *
99619 + * ALTERNATIVELY, this software may be distributed under the terms of the
99620 + * GNU General Public License ("GPL") as published by the Free Software
99621 + * Foundation, either version 2 of that License or (at your option) any
99622 + * later version.
99623 + *
99624 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99625 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99626 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99627 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99628 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99629 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99630 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99631 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99632 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99633 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99634 + */
99635 +
99636 +/**
99637 +
99638 + @File part_integration_ext.h
99639 +
99640 + @Description T4240 external definitions and structures.
99641 +*//***************************************************************************/
99642 +#ifndef __PART_INTEGRATION_EXT_H
99643 +#define __PART_INTEGRATION_EXT_H
99644 +
99645 +#include "std_ext.h"
99646 +#include "ddr_std_ext.h"
99647 +#include "enet_ext.h"
99648 +#include "dpaa_integration_ext.h"
99649 +
99650 +
99651 +/**************************************************************************//**
99652 + @Group T4240_chip_id T4240 Application Programming Interface
99653 +
99654 + @Description T4240 Chip functions,definitions and enums.
99655 +
99656 + @{
99657 +*//***************************************************************************/
99658 +
99659 +#define CORE_E6500
99660 +
99661 +#define INTG_MAX_NUM_OF_CORES 24
99662 +
99663 +
99664 +/**************************************************************************//**
99665 + @Description Module types.
99666 +*//***************************************************************************/
99667 +typedef enum e_ModuleId
99668 +{
99669 + e_MODULE_ID_DUART_1 = 0,
99670 + e_MODULE_ID_DUART_2,
99671 + e_MODULE_ID_DUART_3,
99672 + e_MODULE_ID_DUART_4,
99673 + e_MODULE_ID_LAW,
99674 + e_MODULE_ID_IFC,
99675 + e_MODULE_ID_PAMU,
99676 + e_MODULE_ID_QM, /**< Queue manager module */
99677 + e_MODULE_ID_BM, /**< Buffer manager module */
99678 + e_MODULE_ID_QM_CE_PORTAL_0,
99679 + e_MODULE_ID_QM_CI_PORTAL_0,
99680 + e_MODULE_ID_QM_CE_PORTAL_1,
99681 + e_MODULE_ID_QM_CI_PORTAL_1,
99682 + e_MODULE_ID_QM_CE_PORTAL_2,
99683 + e_MODULE_ID_QM_CI_PORTAL_2,
99684 + e_MODULE_ID_QM_CE_PORTAL_3,
99685 + e_MODULE_ID_QM_CI_PORTAL_3,
99686 + e_MODULE_ID_QM_CE_PORTAL_4,
99687 + e_MODULE_ID_QM_CI_PORTAL_4,
99688 + e_MODULE_ID_QM_CE_PORTAL_5,
99689 + e_MODULE_ID_QM_CI_PORTAL_5,
99690 + e_MODULE_ID_QM_CE_PORTAL_6,
99691 + e_MODULE_ID_QM_CI_PORTAL_6,
99692 + e_MODULE_ID_QM_CE_PORTAL_7,
99693 + e_MODULE_ID_QM_CI_PORTAL_7,
99694 + e_MODULE_ID_QM_CE_PORTAL_8,
99695 + e_MODULE_ID_QM_CI_PORTAL_8,
99696 + e_MODULE_ID_QM_CE_PORTAL_9,
99697 + e_MODULE_ID_QM_CI_PORTAL_9,
99698 + e_MODULE_ID_BM_CE_PORTAL_0,
99699 + e_MODULE_ID_BM_CI_PORTAL_0,
99700 + e_MODULE_ID_BM_CE_PORTAL_1,
99701 + e_MODULE_ID_BM_CI_PORTAL_1,
99702 + e_MODULE_ID_BM_CE_PORTAL_2,
99703 + e_MODULE_ID_BM_CI_PORTAL_2,
99704 + e_MODULE_ID_BM_CE_PORTAL_3,
99705 + e_MODULE_ID_BM_CI_PORTAL_3,
99706 + e_MODULE_ID_BM_CE_PORTAL_4,
99707 + e_MODULE_ID_BM_CI_PORTAL_4,
99708 + e_MODULE_ID_BM_CE_PORTAL_5,
99709 + e_MODULE_ID_BM_CI_PORTAL_5,
99710 + e_MODULE_ID_BM_CE_PORTAL_6,
99711 + e_MODULE_ID_BM_CI_PORTAL_6,
99712 + e_MODULE_ID_BM_CE_PORTAL_7,
99713 + e_MODULE_ID_BM_CI_PORTAL_7,
99714 + e_MODULE_ID_BM_CE_PORTAL_8,
99715 + e_MODULE_ID_BM_CI_PORTAL_8,
99716 + e_MODULE_ID_BM_CE_PORTAL_9,
99717 + e_MODULE_ID_BM_CI_PORTAL_9,
99718 + e_MODULE_ID_FM, /**< Frame manager module */
99719 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99720 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99721 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99722 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99723 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
99724 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99725 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99726 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99727 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99728 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
99729 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
99730 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
99731 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99732 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
99733 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
99734 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
99735 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
99736 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
99737 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
99738 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
99739 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99740 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
99741 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
99742 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
99743 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
99744 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
99745 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
99746 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
99747 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99748 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99749 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99750 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99751 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99752 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
99753 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
99754 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99755 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99756 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
99757 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
99758 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
99759 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
99760 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
99761 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
99762 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
99763 +
99764 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99765 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99766 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99767 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99768 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99769 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99770 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99771 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99772 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99773 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99774 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99775 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99776 +
99777 + e_MODULE_ID_PIC, /**< PIC */
99778 + e_MODULE_ID_GPIO, /**< GPIO */
99779 + e_MODULE_ID_SERDES, /**< SERDES */
99780 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
99781 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
99782 +
99783 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
99784 +
99785 + e_MODULE_ID_DUMMY_LAST
99786 +} e_ModuleId;
99787 +
99788 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99789 +
99790 +#if 0 /* using unified values */
99791 +/*****************************************************************************
99792 + INTEGRATION-SPECIFIC MODULE CODES
99793 +******************************************************************************/
99794 +#define MODULE_UNKNOWN 0x00000000
99795 +#define MODULE_MEM 0x00010000
99796 +#define MODULE_MM 0x00020000
99797 +#define MODULE_CORE 0x00030000
99798 +#define MODULE_T4240 0x00040000
99799 +#define MODULE_T4240_PLATFORM 0x00050000
99800 +#define MODULE_PM 0x00060000
99801 +#define MODULE_MMU 0x00070000
99802 +#define MODULE_PIC 0x00080000
99803 +#define MODULE_CPC 0x00090000
99804 +#define MODULE_DUART 0x000a0000
99805 +#define MODULE_SERDES 0x000b0000
99806 +#define MODULE_PIO 0x000c0000
99807 +#define MODULE_QM 0x000d0000
99808 +#define MODULE_BM 0x000e0000
99809 +#define MODULE_SEC 0x000f0000
99810 +#define MODULE_LAW 0x00100000
99811 +#define MODULE_LBC 0x00110000
99812 +#define MODULE_PAMU 0x00120000
99813 +#define MODULE_FM 0x00130000
99814 +#define MODULE_FM_MURAM 0x00140000
99815 +#define MODULE_FM_PCD 0x00150000
99816 +#define MODULE_FM_RTC 0x00160000
99817 +#define MODULE_FM_MAC 0x00170000
99818 +#define MODULE_FM_PORT 0x00180000
99819 +#define MODULE_FM_SP 0x00190000
99820 +#define MODULE_DPA_PORT 0x001a0000
99821 +#define MODULE_MII 0x001b0000
99822 +#define MODULE_I2C 0x001c0000
99823 +#define MODULE_DMA 0x001d0000
99824 +#define MODULE_DDR 0x001e0000
99825 +#define MODULE_ESPI 0x001f0000
99826 +#define MODULE_DPAA_IPSEC 0x00200000
99827 +#endif /* using unified values */
99828 +
99829 +/*****************************************************************************
99830 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
99831 +******************************************************************************/
99832 +#define PAMU_NUM_OF_PARTITIONS 4
99833 +
99834 +/*****************************************************************************
99835 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99836 +******************************************************************************/
99837 +#define LAW_NUM_OF_WINDOWS 32
99838 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
99839 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
99840 +
99841 +
99842 +/*****************************************************************************
99843 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99844 +******************************************************************************/
99845 +/**************************************************************************//**
99846 + @Group lbc_exception_grp LBC Exception Unit
99847 +
99848 + @Description LBC Exception unit API functions, definitions and enums
99849 +
99850 + @{
99851 +*//***************************************************************************/
99852 +
99853 +/**************************************************************************//**
99854 + @Anchor lbc_exbm
99855 +
99856 + @Collection LBC Errors Bit Mask
99857 +
99858 + These errors are reported through the exceptions callback..
99859 + The values can be or'ed in any combination in the errors mask
99860 + parameter of the errors report structure.
99861 +
99862 + These errors can also be passed as a bit-mask to
99863 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99864 + for enabling or disabling error checking.
99865 + @{
99866 +*//***************************************************************************/
99867 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99868 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99869 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99870 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99871 +
99872 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99873 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99874 + /**< All possible errors */
99875 +/* @} */
99876 +/** @} */ /* end of lbc_exception_grp group */
99877 +
99878 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
99879 +
99880 +#define LBC_NUM_OF_BANKS 8
99881 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
99882 +#define LBC_PARITY_SUPPORT
99883 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99884 +#define LBC_HIGH_CLK_DIVIDERS
99885 +#define LBC_FCM_AVAILABLE
99886 +
99887 +/*****************************************************************************
99888 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
99889 +******************************************************************************/
99890 +#define GPIO_PORT_OFFSET_0x1000
99891 +
99892 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
99893 + Each port contains up to 32 I/O pins. */
99894 +
99895 +#define GPIO_VALID_PIN_MASKS \
99896 + { /* Port A */ 0xFFFFFFFF, \
99897 + /* Port B */ 0xFFFFFFFF, \
99898 + /* Port C */ 0xFFFFFFFF }
99899 +
99900 +#define GPIO_VALID_INTR_MASKS \
99901 + { /* Port A */ 0xFFFFFFFF, \
99902 + /* Port B */ 0xFFFFFFFF, \
99903 + /* Port C */ 0xFFFFFFFF }
99904 +
99905 +
99906 +
99907 +#endif /* __PART_INTEGRATION_EXT_H */
99908 --- /dev/null
99909 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
99910 @@ -0,0 +1,291 @@
99911 +/*
99912 + * Copyright 2012 Freescale Semiconductor Inc.
99913 + *
99914 + * Redistribution and use in source and binary forms, with or without
99915 + * modification, are permitted provided that the following conditions are met:
99916 + * * Redistributions of source code must retain the above copyright
99917 + * notice, this list of conditions and the following disclaimer.
99918 + * * Redistributions in binary form must reproduce the above copyright
99919 + * notice, this list of conditions and the following disclaimer in the
99920 + * documentation and/or other materials provided with the distribution.
99921 + * * Neither the name of Freescale Semiconductor nor the
99922 + * names of its contributors may be used to endorse or promote products
99923 + * derived from this software without specific prior written permission.
99924 + *
99925 + *
99926 + * ALTERNATIVELY, this software may be distributed under the terms of the
99927 + * GNU General Public License ("GPL") as published by the Free Software
99928 + * Foundation, either version 2 of that License or (at your option) any
99929 + * later version.
99930 + *
99931 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99932 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99933 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99934 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99935 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99936 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99937 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99938 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99939 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99940 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99941 + */
99942 +
99943 +/**
99944 +
99945 + @File dpaa_integration_ext.h
99946 +
99947 + @Description T4240 FM external definitions and structures.
99948 +*//***************************************************************************/
99949 +#ifndef __DPAA_INTEGRATION_EXT_H
99950 +#define __DPAA_INTEGRATION_EXT_H
99951 +
99952 +#include "std_ext.h"
99953 +
99954 +
99955 +#define DPAA_VERSION 11
99956 +
99957 +/**************************************************************************//**
99958 + @Description DPAA SW Portals Enumeration.
99959 +*//***************************************************************************/
99960 +typedef enum
99961 +{
99962 + e_DPAA_SWPORTAL0 = 0,
99963 + e_DPAA_SWPORTAL1,
99964 + e_DPAA_SWPORTAL2,
99965 + e_DPAA_SWPORTAL3,
99966 + e_DPAA_SWPORTAL4,
99967 + e_DPAA_SWPORTAL5,
99968 + e_DPAA_SWPORTAL6,
99969 + e_DPAA_SWPORTAL7,
99970 + e_DPAA_SWPORTAL8,
99971 + e_DPAA_SWPORTAL9,
99972 + e_DPAA_SWPORTAL10,
99973 + e_DPAA_SWPORTAL11,
99974 + e_DPAA_SWPORTAL12,
99975 + e_DPAA_SWPORTAL13,
99976 + e_DPAA_SWPORTAL14,
99977 + e_DPAA_SWPORTAL15,
99978 + e_DPAA_SWPORTAL16,
99979 + e_DPAA_SWPORTAL17,
99980 + e_DPAA_SWPORTAL18,
99981 + e_DPAA_SWPORTAL19,
99982 + e_DPAA_SWPORTAL20,
99983 + e_DPAA_SWPORTAL21,
99984 + e_DPAA_SWPORTAL22,
99985 + e_DPAA_SWPORTAL23,
99986 + e_DPAA_SWPORTAL24,
99987 + e_DPAA_SWPORTAL_DUMMY_LAST
99988 +} e_DpaaSwPortal;
99989 +
99990 +/**************************************************************************//**
99991 + @Description DPAA Direct Connect Portals Enumeration.
99992 +*//***************************************************************************/
99993 +typedef enum
99994 +{
99995 + e_DPAA_DCPORTAL0 = 0,
99996 + e_DPAA_DCPORTAL1,
99997 + e_DPAA_DCPORTAL2,
99998 + e_DPAA_DCPORTAL_DUMMY_LAST
99999 +} e_DpaaDcPortal;
100000 +
100001 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100002 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100003 +
100004 +/*****************************************************************************
100005 + QMan INTEGRATION-SPECIFIC DEFINITIONS
100006 +******************************************************************************/
100007 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
100008 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
100009 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
100010 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
100011 + /**< FQIDs range - 24 bits */
100012 +
100013 +/**************************************************************************//**
100014 + @Description Work Queue Channel assignments in QMan.
100015 +*//***************************************************************************/
100016 +typedef enum
100017 +{
100018 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
100019 + e_QM_FQ_CHANNEL_SWPORTAL1,
100020 + e_QM_FQ_CHANNEL_SWPORTAL2,
100021 + e_QM_FQ_CHANNEL_SWPORTAL3,
100022 + e_QM_FQ_CHANNEL_SWPORTAL4,
100023 + e_QM_FQ_CHANNEL_SWPORTAL5,
100024 + e_QM_FQ_CHANNEL_SWPORTAL6,
100025 + e_QM_FQ_CHANNEL_SWPORTAL7,
100026 + e_QM_FQ_CHANNEL_SWPORTAL8,
100027 + e_QM_FQ_CHANNEL_SWPORTAL9,
100028 + e_QM_FQ_CHANNEL_SWPORTAL10,
100029 + e_QM_FQ_CHANNEL_SWPORTAL11,
100030 + e_QM_FQ_CHANNEL_SWPORTAL12,
100031 + e_QM_FQ_CHANNEL_SWPORTAL13,
100032 + e_QM_FQ_CHANNEL_SWPORTAL14,
100033 + e_QM_FQ_CHANNEL_SWPORTAL15,
100034 + e_QM_FQ_CHANNEL_SWPORTAL16,
100035 + e_QM_FQ_CHANNEL_SWPORTAL17,
100036 + e_QM_FQ_CHANNEL_SWPORTAL18,
100037 + e_QM_FQ_CHANNEL_SWPORTAL19,
100038 + e_QM_FQ_CHANNEL_SWPORTAL20,
100039 + e_QM_FQ_CHANNEL_SWPORTAL21,
100040 + e_QM_FQ_CHANNEL_SWPORTAL22,
100041 + e_QM_FQ_CHANNEL_SWPORTAL23,
100042 + e_QM_FQ_CHANNEL_SWPORTAL24,
100043 +
100044 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
100045 + e_QM_FQ_CHANNEL_POOL2,
100046 + e_QM_FQ_CHANNEL_POOL3,
100047 + e_QM_FQ_CHANNEL_POOL4,
100048 + e_QM_FQ_CHANNEL_POOL5,
100049 + e_QM_FQ_CHANNEL_POOL6,
100050 + e_QM_FQ_CHANNEL_POOL7,
100051 + e_QM_FQ_CHANNEL_POOL8,
100052 + e_QM_FQ_CHANNEL_POOL9,
100053 + e_QM_FQ_CHANNEL_POOL10,
100054 + e_QM_FQ_CHANNEL_POOL11,
100055 + e_QM_FQ_CHANNEL_POOL12,
100056 + e_QM_FQ_CHANNEL_POOL13,
100057 + e_QM_FQ_CHANNEL_POOL14,
100058 + e_QM_FQ_CHANNEL_POOL15,
100059 +
100060 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
100061 + connected to FMan 0; assigned in incrementing order to
100062 + each sub-portal (SP) in the portal */
100063 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100064 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100065 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100066 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100067 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100068 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100069 + e_QM_FQ_CHANNEL_FMAN0_SP7,
100070 + e_QM_FQ_CHANNEL_FMAN0_SP8,
100071 + e_QM_FQ_CHANNEL_FMAN0_SP9,
100072 + e_QM_FQ_CHANNEL_FMAN0_SP10,
100073 + e_QM_FQ_CHANNEL_FMAN0_SP11,
100074 + e_QM_FQ_CHANNEL_FMAN0_SP12,
100075 + e_QM_FQ_CHANNEL_FMAN0_SP13,
100076 + e_QM_FQ_CHANNEL_FMAN0_SP14,
100077 + e_QM_FQ_CHANNEL_FMAN0_SP15,
100078 +
100079 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
100080 + e_QM_FQ_CHANNEL_RMAN_SP1,
100081 +
100082 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
100083 + connected to SEC */
100084 +} e_QmFQChannel;
100085 +
100086 +/*****************************************************************************
100087 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100088 +******************************************************************************/
100089 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100090 +
100091 +/*****************************************************************************
100092 + SEC INTEGRATION-SPECIFIC DEFINITIONS
100093 +******************************************************************************/
100094 +#define SEC_NUM_OF_DECOS 3
100095 +#define SEC_ALL_DECOS_MASK 0x00000003
100096 +
100097 +
100098 +/*****************************************************************************
100099 + FM INTEGRATION-SPECIFIC DEFINITIONS
100100 +******************************************************************************/
100101 +#define INTG_MAX_NUM_OF_FM 2
100102 +
100103 +/* Ports defines */
100104 +#define FM_MAX_NUM_OF_1G_MACS 6
100105 +#define FM_MAX_NUM_OF_10G_MACS 2
100106 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100107 +#define FM_MAX_NUM_OF_OH_PORTS 6
100108 +
100109 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100110 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100111 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100112 +
100113 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100114 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100115 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100116 +
100117 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
100118 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100119 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
100120 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100121 +
100122 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
100123 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
100124 +
100125 +/* RAMs defines */
100126 +#define FM_MURAM_SIZE (384 * KILOBYTE)
100127 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100128 +#define FM_NUM_OF_CTRL 4
100129 +
100130 +/* PCD defines */
100131 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100132 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100133 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100134 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
100135 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100136 +
100137 +/* RTC defines */
100138 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100139 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
100140 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100141 +
100142 +/* QMI defines */
100143 +#define QMI_MAX_NUM_OF_TNUMS 64
100144 +#define QMI_DEF_TNUMS_THRESH 32
100145 +/* FPM defines */
100146 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100147 +
100148 +/* DMA defines */
100149 +#define DMA_THRESH_MAX_COMMQ 83
100150 +#define DMA_THRESH_MAX_BUF 127
100151 +
100152 +/* BMI defines */
100153 +#define BMI_MAX_NUM_OF_TASKS 128
100154 +#define BMI_MAX_NUM_OF_DMAS 84
100155 +
100156 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100157 +#define PORT_MAX_WEIGHT 16
100158 +
100159 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100160 +
100161 +/* Unique T4240 */
100162 +#define FM_OP_OPEN_DMA_MIN_LIMIT
100163 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
100164 +#define FM_NO_OP_OBSERVED_POOLS
100165 +#define FM_FRAME_END_PARAMS_FOR_OP
100166 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
100167 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
100168 +
100169 +#define FM_NO_GUARANTEED_RESET_VALUES
100170 +
100171 +/* FM errata */
100172 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
100173 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
100174 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
100175 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
100176 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
100177 +
100178 +#define FM_BCB_ERRATA_BMI_SW001
100179 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100180 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
100181 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
100182 +
100183 +/*****************************************************************************
100184 + RMan INTEGRATION-SPECIFIC DEFINITIONS
100185 +******************************************************************************/
100186 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
100187 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
100188 +
100189 +/* RMan erratas */
100190 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
100191 +
100192 +/*****************************************************************************
100193 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100194 +******************************************************************************/
100195 +#define NUM_OF_RX_SC 16
100196 +#define NUM_OF_TX_SC 16
100197 +
100198 +#define NUM_OF_SA_PER_RX_SC 2
100199 +#define NUM_OF_SA_PER_TX_SC 2
100200 +
100201 +#endif /* __DPAA_INTEGRATION_EXT_H */
100202 --- /dev/null
100203 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
100204 @@ -0,0 +1,64 @@
100205 +/*
100206 + * Copyright 2012 Freescale Semiconductor Inc.
100207 + *
100208 + * Redistribution and use in source and binary forms, with or without
100209 + * modification, are permitted provided that the following conditions are met:
100210 + * * Redistributions of source code must retain the above copyright
100211 + * notice, this list of conditions and the following disclaimer.
100212 + * * Redistributions in binary form must reproduce the above copyright
100213 + * notice, this list of conditions and the following disclaimer in the
100214 + * documentation and/or other materials provided with the distribution.
100215 + * * Neither the name of Freescale Semiconductor nor the
100216 + * names of its contributors may be used to endorse or promote products
100217 + * derived from this software without specific prior written permission.
100218 + *
100219 + *
100220 + * ALTERNATIVELY, this software may be distributed under the terms of the
100221 + * GNU General Public License ("GPL") as published by the Free Software
100222 + * Foundation, either version 2 of that License or (at your option) any
100223 + * later version.
100224 + *
100225 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100226 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100227 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100228 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100229 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100230 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100231 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100232 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100233 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100234 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100235 + */
100236 +
100237 +/**************************************************************************//**
100238 +
100239 + @File part_ext.h
100240 +
100241 + @Description Definitions for the part (integration) module.
100242 +*//***************************************************************************/
100243 +
100244 +#ifndef __PART_EXT_H
100245 +#define __PART_EXT_H
100246 +
100247 +#include "std_ext.h"
100248 +#include "part_integration_ext.h"
100249 +
100250 +#if !(defined(LS1043))
100251 +#error "unable to proceed without chip-definition"
100252 +#endif
100253 +
100254 +
100255 +/**************************************************************************//*
100256 + @Description Part data structure - must be contained in any integration
100257 + data structure.
100258 +*//***************************************************************************/
100259 +typedef struct t_Part
100260 +{
100261 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100262 + /**< Returns the address of the module's memory map base. */
100263 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100264 + /**< Returns the module's ID according to its memory map base. */
100265 +} t_Part;
100266 +
100267 +
100268 +#endif /* __PART_EXT_H */
100269 --- /dev/null
100270 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
100271 @@ -0,0 +1,185 @@
100272 +/*
100273 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100274 + *
100275 + * Redistribution and use in source and binary forms, with or without
100276 + * modification, are permitted provided that the following conditions are met:
100277 + * * Redistributions of source code must retain the above copyright
100278 + * notice, this list of conditions and the following disclaimer.
100279 + * * Redistributions in binary form must reproduce the above copyright
100280 + * notice, this list of conditions and the following disclaimer in the
100281 + * documentation and/or other materials provided with the distribution.
100282 + * * Neither the name of Freescale Semiconductor nor the
100283 + * names of its contributors may be used to endorse or promote products
100284 + * derived from this software without specific prior written permission.
100285 + *
100286 + *
100287 + * ALTERNATIVELY, this software may be distributed under the terms of the
100288 + * GNU General Public License ("GPL") as published by the Free Software
100289 + * Foundation, either version 2 of that License or (at your option) any
100290 + * later version.
100291 + *
100292 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100293 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100294 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100295 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100296 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100297 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100298 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100299 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100300 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100301 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100302 + */
100303 +
100304 +/**
100305 +
100306 + @File part_integration_ext.h
100307 +
100308 + @Description T4240 external definitions and structures.
100309 +*//***************************************************************************/
100310 +#ifndef __PART_INTEGRATION_EXT_H
100311 +#define __PART_INTEGRATION_EXT_H
100312 +
100313 +#include "std_ext.h"
100314 +#include "ddr_std_ext.h"
100315 +#include "enet_ext.h"
100316 +#include "dpaa_integration_ext.h"
100317 +
100318 +
100319 +/**************************************************************************//**
100320 + @Group T4240_chip_id T4240 Application Programming Interface
100321 +
100322 + @Description T4240 Chip functions,definitions and enums.
100323 +
100324 + @{
100325 +*//***************************************************************************/
100326 +
100327 +#define INTG_MAX_NUM_OF_CORES 4
100328 +
100329 +/**************************************************************************//**
100330 + @Description Module types.
100331 +*//***************************************************************************/
100332 +typedef enum e_ModuleId
100333 +{
100334 + e_MODULE_ID_DUART_1 = 0,
100335 + e_MODULE_ID_DUART_2,
100336 + e_MODULE_ID_DUART_3,
100337 + e_MODULE_ID_DUART_4,
100338 + e_MODULE_ID_LAW,
100339 + e_MODULE_ID_IFC,
100340 + e_MODULE_ID_PAMU,
100341 + e_MODULE_ID_QM, /**< Queue manager module */
100342 + e_MODULE_ID_BM, /**< Buffer manager module */
100343 + e_MODULE_ID_QM_CE_PORTAL_0,
100344 + e_MODULE_ID_QM_CI_PORTAL_0,
100345 + e_MODULE_ID_QM_CE_PORTAL_1,
100346 + e_MODULE_ID_QM_CI_PORTAL_1,
100347 + e_MODULE_ID_QM_CE_PORTAL_2,
100348 + e_MODULE_ID_QM_CI_PORTAL_2,
100349 + e_MODULE_ID_QM_CE_PORTAL_3,
100350 + e_MODULE_ID_QM_CI_PORTAL_3,
100351 + e_MODULE_ID_QM_CE_PORTAL_4,
100352 + e_MODULE_ID_QM_CI_PORTAL_4,
100353 + e_MODULE_ID_QM_CE_PORTAL_5,
100354 + e_MODULE_ID_QM_CI_PORTAL_5,
100355 + e_MODULE_ID_QM_CE_PORTAL_6,
100356 + e_MODULE_ID_QM_CI_PORTAL_6,
100357 + e_MODULE_ID_QM_CE_PORTAL_7,
100358 + e_MODULE_ID_QM_CI_PORTAL_7,
100359 + e_MODULE_ID_QM_CE_PORTAL_8,
100360 + e_MODULE_ID_QM_CI_PORTAL_8,
100361 + e_MODULE_ID_QM_CE_PORTAL_9,
100362 + e_MODULE_ID_QM_CI_PORTAL_9,
100363 + e_MODULE_ID_BM_CE_PORTAL_0,
100364 + e_MODULE_ID_BM_CI_PORTAL_0,
100365 + e_MODULE_ID_BM_CE_PORTAL_1,
100366 + e_MODULE_ID_BM_CI_PORTAL_1,
100367 + e_MODULE_ID_BM_CE_PORTAL_2,
100368 + e_MODULE_ID_BM_CI_PORTAL_2,
100369 + e_MODULE_ID_BM_CE_PORTAL_3,
100370 + e_MODULE_ID_BM_CI_PORTAL_3,
100371 + e_MODULE_ID_BM_CE_PORTAL_4,
100372 + e_MODULE_ID_BM_CI_PORTAL_4,
100373 + e_MODULE_ID_BM_CE_PORTAL_5,
100374 + e_MODULE_ID_BM_CI_PORTAL_5,
100375 + e_MODULE_ID_BM_CE_PORTAL_6,
100376 + e_MODULE_ID_BM_CI_PORTAL_6,
100377 + e_MODULE_ID_BM_CE_PORTAL_7,
100378 + e_MODULE_ID_BM_CI_PORTAL_7,
100379 + e_MODULE_ID_BM_CE_PORTAL_8,
100380 + e_MODULE_ID_BM_CI_PORTAL_8,
100381 + e_MODULE_ID_BM_CE_PORTAL_9,
100382 + e_MODULE_ID_BM_CI_PORTAL_9,
100383 + e_MODULE_ID_FM, /**< Frame manager module */
100384 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
100385 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
100386 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
100387 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
100388 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
100389 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100390 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100391 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100392 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100393 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100394 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100395 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
100396 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100397 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100398 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100399 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100400 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
100401 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
100402 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
100403 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
100404 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100405 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100406 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100407 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100408 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
100409 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
100410 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
100411 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
100412 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
100413 + e_MODULE_ID_FM_KG, /**< FM Keygen */
100414 + e_MODULE_ID_FM_DMA, /**< FM DMA */
100415 + e_MODULE_ID_FM_FPM, /**< FM FPM */
100416 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
100417 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
100418 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
100419 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100420 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
100421 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
100422 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
100423 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
100424 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
100425 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
100426 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
100427 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
100428 +
100429 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100430 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100431 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100432 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100433 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100434 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100435 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100436 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100437 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100438 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100439 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100440 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100441 +
100442 + e_MODULE_ID_PIC, /**< PIC */
100443 + e_MODULE_ID_GPIO, /**< GPIO */
100444 + e_MODULE_ID_SERDES, /**< SERDES */
100445 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100446 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100447 +
100448 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100449 +
100450 + e_MODULE_ID_DUMMY_LAST
100451 +} e_ModuleId;
100452 +
100453 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100454 +
100455 +
100456 +#endif /* __PART_INTEGRATION_EXT_H */
100457 --- /dev/null
100458 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
100459 @@ -0,0 +1,213 @@
100460 +/*
100461 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100462 + *
100463 + * Redistribution and use in source and binary forms, with or without
100464 + * modification, are permitted provided that the following conditions are met:
100465 + * * Redistributions of source code must retain the above copyright
100466 + * notice, this list of conditions and the following disclaimer.
100467 + * * Redistributions in binary form must reproduce the above copyright
100468 + * notice, this list of conditions and the following disclaimer in the
100469 + * documentation and/or other materials provided with the distribution.
100470 + * * Neither the name of Freescale Semiconductor nor the
100471 + * names of its contributors may be used to endorse or promote products
100472 + * derived from this software without specific prior written permission.
100473 + *
100474 + *
100475 + * ALTERNATIVELY, this software may be distributed under the terms of the
100476 + * GNU General Public License ("GPL") as published by the Free Software
100477 + * Foundation, either version 2 of that License or (at your option) any
100478 + * later version.
100479 + *
100480 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100481 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100482 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100483 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100484 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100485 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100486 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100487 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100488 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100489 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100490 + */
100491 +
100492 +
100493 +/**
100494 +
100495 + @File dpaa_integration_ext.h
100496 +
100497 + @Description P1023 FM external definitions and structures.
100498 +*//***************************************************************************/
100499 +#ifndef __DPAA_INTEGRATION_EXT_H
100500 +#define __DPAA_INTEGRATION_EXT_H
100501 +
100502 +#include "std_ext.h"
100503 +
100504 +
100505 +#define DPAA_VERSION 10
100506 +
100507 +typedef enum e_DpaaSwPortal {
100508 + e_DPAA_SWPORTAL0 = 0,
100509 + e_DPAA_SWPORTAL1,
100510 + e_DPAA_SWPORTAL2,
100511 + e_DPAA_SWPORTAL_DUMMY_LAST
100512 +} e_DpaaSwPortal;
100513 +
100514 +typedef enum {
100515 + e_DPAA_DCPORTAL0 = 0,
100516 + e_DPAA_DCPORTAL2,
100517 + e_DPAA_DCPORTAL_DUMMY_LAST
100518 +} e_DpaaDcPortal;
100519 +
100520 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100521 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100522 +
100523 +/*****************************************************************************
100524 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
100525 +******************************************************************************/
100526 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
100527 +#define QM_MAX_NUM_OF_WQ 8
100528 +#define QM_MAX_NUM_OF_SWP_AS 2
100529 +#define QM_MAX_NUM_OF_CGS 64
100530 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
100531 +
100532 +typedef enum {
100533 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
100534 + e_QM_FQ_CHANNEL_SWPORTAL1,
100535 + e_QM_FQ_CHANNEL_SWPORTAL2,
100536 +
100537 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
100538 + e_QM_FQ_CHANNEL_POOL2,
100539 + e_QM_FQ_CHANNEL_POOL3,
100540 +
100541 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
100542 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100543 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100544 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100545 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100546 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100547 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100548 +
100549 +
100550 + e_QM_FQ_CHANNEL_CAAM = 0x80
100551 +} e_QmFQChannel;
100552 +
100553 +/*****************************************************************************
100554 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
100555 +******************************************************************************/
100556 +#define BM_MAX_NUM_OF_POOLS 8
100557 +
100558 +/*****************************************************************************
100559 + SEC INTEGRATION-SPECIFIC DEFINITIONS
100560 +******************************************************************************/
100561 +#define SEC_NUM_OF_DECOS 2
100562 +#define SEC_ALL_DECOS_MASK 0x00000003
100563 +#define SEC_RNGB
100564 +#define SEC_NO_ESP_TRAILER_REMOVAL
100565 +
100566 +/*****************************************************************************
100567 + FM INTEGRATION-SPECIFIC DEFINITIONS
100568 +******************************************************************************/
100569 +#define INTG_MAX_NUM_OF_FM 1
100570 +
100571 +/* Ports defines */
100572 +#define FM_MAX_NUM_OF_1G_MACS 2
100573 +#define FM_MAX_NUM_OF_10G_MACS 0
100574 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100575 +#define FM_MAX_NUM_OF_OH_PORTS 5
100576 +
100577 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100578 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100579 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100580 +
100581 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100582 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100583 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100584 +
100585 +#define FM_MAX_NUM_OF_MACSECS 1
100586 +
100587 +#define FM_MACSEC_SUPPORT
100588 +
100589 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
100590 +
100591 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
100592 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
100593 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
100594 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
100595 +
100596 +/* Rams defines */
100597 +#define FM_MURAM_SIZE (64*KILOBYTE)
100598 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
100599 +#define FM_NUM_OF_CTRL 2
100600 +
100601 +/* PCD defines */
100602 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
100603 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
100604 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
100605 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */
100606 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100607 +
100608 +/* RTC defines */
100609 +#define FM_RTC_NUM_OF_ALARMS 2
100610 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
100611 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
100612 +
100613 +/* QMI defines */
100614 +#define QMI_MAX_NUM_OF_TNUMS 15
100615 +
100616 +/* FPM defines */
100617 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100618 +
100619 +/* DMA defines */
100620 +#define DMA_THRESH_MAX_COMMQ 15
100621 +#define DMA_THRESH_MAX_BUF 7
100622 +
100623 +/* BMI defines */
100624 +#define BMI_MAX_NUM_OF_TASKS 64
100625 +#define BMI_MAX_NUM_OF_DMAS 16
100626 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100627 +#define PORT_MAX_WEIGHT 4
100628 +
100629 +/*****************************************************************************
100630 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100631 +******************************************************************************/
100632 +#define NUM_OF_RX_SC 16
100633 +#define NUM_OF_TX_SC 16
100634 +
100635 +#define NUM_OF_SA_PER_RX_SC 2
100636 +#define NUM_OF_SA_PER_TX_SC 2
100637 +
100638 +/**************************************************************************//**
100639 + @Description Enum for inter-module interrupts registration
100640 +*//***************************************************************************/
100641 +
100642 +/* 1023 unique features */
100643 +#define FM_QMI_NO_ECC_EXCEPTIONS
100644 +#define FM_CSI_CFED_LIMIT
100645 +#define FM_PEDANTIC_DMA
100646 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
100647 +#define FM_FIFO_ALLOCATION_ALG
100648 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
100649 +#define FM_HAS_TOTAL_DMAS
100650 +#define FM_KG_NO_IPPID_SUPPORT
100651 +#define FM_NO_GUARANTEED_RESET_VALUES
100652 +#define FM_MAC_RESET
100653 +
100654 +/* FM erratas */
100655 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
100656 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
100657 +
100658 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
100659 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
100660 +
100661 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
100662 +
100663 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
100664 +
100665 +/*
100666 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
100667 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
100668 +*/
100669 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
100670 +
100671 +
100672 +#endif /* __DPAA_INTEGRATION_EXT_H */
100673 --- /dev/null
100674 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
100675 @@ -0,0 +1,82 @@
100676 +/*
100677 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100678 + *
100679 + * Redistribution and use in source and binary forms, with or without
100680 + * modification, are permitted provided that the following conditions are met:
100681 + * * Redistributions of source code must retain the above copyright
100682 + * notice, this list of conditions and the following disclaimer.
100683 + * * Redistributions in binary form must reproduce the above copyright
100684 + * notice, this list of conditions and the following disclaimer in the
100685 + * documentation and/or other materials provided with the distribution.
100686 + * * Neither the name of Freescale Semiconductor nor the
100687 + * names of its contributors may be used to endorse or promote products
100688 + * derived from this software without specific prior written permission.
100689 + *
100690 + *
100691 + * ALTERNATIVELY, this software may be distributed under the terms of the
100692 + * GNU General Public License ("GPL") as published by the Free Software
100693 + * Foundation, either version 2 of that License or (at your option) any
100694 + * later version.
100695 + *
100696 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100697 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100698 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100699 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100700 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100701 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100702 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100703 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100704 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100705 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100706 + */
100707 +
100708 +
100709 +/**************************************************************************//**
100710 +
100711 + @File part_ext.h
100712 +
100713 + @Description Definitions for the part (integration) module.
100714 +*//***************************************************************************/
100715 +
100716 +#ifndef __PART_EXT_H
100717 +#define __PART_EXT_H
100718 +
100719 +#include "std_ext.h"
100720 +#include "part_integration_ext.h"
100721 +
100722 +
100723 +#if !(defined(MPC8306) || \
100724 + defined(MPC8309) || \
100725 + defined(MPC834x) || \
100726 + defined(MPC836x) || \
100727 + defined(MPC832x) || \
100728 + defined(MPC837x) || \
100729 + defined(MPC8568) || \
100730 + defined(MPC8569) || \
100731 + defined(P1020) || \
100732 + defined(P1021) || \
100733 + defined(P1022) || \
100734 + defined(P1023) || \
100735 + defined(P2020) || \
100736 + defined(P3041) || \
100737 + defined(P4080) || \
100738 + defined(P5020) || \
100739 + defined(MSC814x))
100740 +#error "unable to proceed without chip-definition"
100741 +#endif
100742 +
100743 +
100744 +/**************************************************************************//*
100745 + @Description Part data structure - must be contained in any integration
100746 + data structure.
100747 +*//***************************************************************************/
100748 +typedef struct t_Part
100749 +{
100750 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100751 + /**< Returns the address of the module's memory map base. */
100752 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
100753 + /**< Returns the module's ID according to its memory map base. */
100754 +} t_Part;
100755 +
100756 +
100757 +#endif /* __PART_EXT_H */
100758 --- /dev/null
100759 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
100760 @@ -0,0 +1,635 @@
100761 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100762 + * All rights reserved.
100763 + *
100764 + * Redistribution and use in source and binary forms, with or without
100765 + * modification, are permitted provided that the following conditions are met:
100766 + * * Redistributions of source code must retain the above copyright
100767 + * notice, this list of conditions and the following disclaimer.
100768 + * * Redistributions in binary form must reproduce the above copyright
100769 + * notice, this list of conditions and the following disclaimer in the
100770 + * documentation and/or other materials provided with the distribution.
100771 + * * Neither the name of Freescale Semiconductor nor the
100772 + * names of its contributors may be used to endorse or promote products
100773 + * derived from this software without specific prior written permission.
100774 + *
100775 + *
100776 + * ALTERNATIVELY, this software may be distributed under the terms of the
100777 + * GNU General Public License ("GPL") as published by the Free Software
100778 + * Foundation, either version 2 of that License or (at your option) any
100779 + * later version.
100780 + *
100781 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100782 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100783 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100784 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100785 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100786 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100787 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100788 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100789 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100790 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100791 + */
100792 +
100793 +/**************************************************************************//**
100794 + @File part_integration_ext.h
100795 +
100796 + @Description P1023 external definitions and structures.
100797 +*//***************************************************************************/
100798 +#ifndef __PART_INTEGRATION_EXT_H
100799 +#define __PART_INTEGRATION_EXT_H
100800 +
100801 +#include "std_ext.h"
100802 +#include "dpaa_integration_ext.h"
100803 +
100804 +
100805 +/**************************************************************************//**
100806 + @Group 1023_chip_id P1023 Application Programming Interface
100807 +
100808 + @Description P1023 Chip functions,definitions and enums.
100809 +
100810 + @{
100811 +*//***************************************************************************/
100812 +
100813 +#define INTG_MAX_NUM_OF_CORES 2
100814 +
100815 +
100816 +/**************************************************************************//**
100817 + @Description Module types.
100818 +*//***************************************************************************/
100819 +typedef enum e_ModuleId
100820 +{
100821 + e_MODULE_ID_LAW, /**< Local Access module */
100822 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
100823 + e_MODULE_ID_DDR, /**< DDR memory controller */
100824 + e_MODULE_ID_I2C_1, /**< I2C 1 */
100825 + e_MODULE_ID_I2C_2, /**< I2C 1 */
100826 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
100827 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
100828 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
100829 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
100830 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
100831 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
100832 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
100833 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
100834 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
100835 + e_MODULE_ID_MSI, /**< MSI registers */
100836 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
100837 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
100838 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
100839 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
100840 + e_MODULE_ID_ESPI, /**< ESPI module */
100841 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
100842 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100843 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100844 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100845 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100846 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100847 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100848 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100849 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100850 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100851 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100852 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100853 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100854 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
100855 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
100856 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
100857 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
100858 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
100859 + e_MODULE_ID_GUTS, /**< Serial DMA */
100860 + e_MODULE_ID_PM, /**< Performance Monitor module */
100861 + e_MODULE_ID_QM, /**< Queue manager module */
100862 + e_MODULE_ID_BM, /**< Buffer manager module */
100863 + e_MODULE_ID_QM_CE_PORTAL,
100864 + e_MODULE_ID_QM_CI_PORTAL,
100865 + e_MODULE_ID_BM_CE_PORTAL,
100866 + e_MODULE_ID_BM_CI_PORTAL,
100867 + e_MODULE_ID_FM, /**< Frame manager #1 module */
100868 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
100869 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
100870 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
100871 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
100872 + e_MODULE_ID_FM_PRS, /**< FM parser block */
100873 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100874 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100875 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100876 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100877 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100878 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100879 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100880 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100881 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100882 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
100883 + e_MODULE_ID_FM_KG, /**< FM Keygen */
100884 + e_MODULE_ID_FM_DMA, /**< FM DMA */
100885 + e_MODULE_ID_FM_FPM, /**< FM FPM */
100886 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
100887 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100888 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100889 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100890 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
100891 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
100892 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
100893 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
100894 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
100895 +
100896 + e_MODULE_ID_DUMMY_LAST
100897 +} e_ModuleId;
100898 +
100899 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100900 +
100901 +
100902 +#define P1023_OFFSET_LAW 0x00000C08
100903 +#define P1023_OFFSET_ECM 0x00001000
100904 +#define P1023_OFFSET_DDR 0x00002000
100905 +#define P1023_OFFSET_I2C1 0x00003000
100906 +#define P1023_OFFSET_I2C2 0x00003100
100907 +#define P1023_OFFSET_DUART1 0x00004500
100908 +#define P1023_OFFSET_DUART2 0x00004600
100909 +#define P1023_OFFSET_LBC 0x00005000
100910 +#define P1023_OFFSET_ESPI 0x00007000
100911 +#define P1023_OFFSET_PCIE2 0x00009000
100912 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
100913 +#define P1023_OFFSET_PCIE1 0x0000A000
100914 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
100915 +#define P1023_OFFSET_PCIE3 0x0000B000
100916 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
100917 +#define P1023_OFFSET_DMA2 0x0000C100
100918 +#define P1023_OFFSET_GPIO 0x0000F000
100919 +#define P1023_OFFSET_L2_SRAM 0x00020000
100920 +#define P1023_OFFSET_DMA1 0x00021100
100921 +#define P1023_OFFSET_USB1 0x00022000
100922 +#define P1023_OFFSET_SEC_GEN 0x00030000
100923 +#define P1023_OFFSET_SEC_JQ0 0x00031000
100924 +#define P1023_OFFSET_SEC_JQ1 0x00032000
100925 +#define P1023_OFFSET_SEC_JQ2 0x00033000
100926 +#define P1023_OFFSET_SEC_JQ3 0x00034000
100927 +#define P1023_OFFSET_SEC_RTIC 0x00036000
100928 +#define P1023_OFFSET_SEC_QI 0x00037000
100929 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
100930 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
100931 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
100932 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
100933 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
100934 +#define P1023_OFFSET_PIC 0x00040000
100935 +#define P1023_OFFSET_MSI 0x00041600
100936 +#define P1023_OFFSET_AXI 0x00081000
100937 +#define P1023_OFFSET_QM 0x00088000
100938 +#define P1023_OFFSET_BM 0x0008A000
100939 +#define P1022_OFFSET_PM 0x000E1000
100940 +
100941 +#define P1023_OFFSET_GUTIL 0x000E0000
100942 +#define P1023_OFFSET_PM 0x000E1000
100943 +#define P1023_OFFSET_DEBUG 0x000E2000
100944 +#define P1023_OFFSET_SERDES 0x000E3000
100945 +#define P1023_OFFSET_ROM 0x000F0000
100946 +#define P1023_OFFSET_FM 0x00100000
100947 +
100948 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
100949 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
100950 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
100951 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
100952 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
100953 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
100954 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
100955 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
100956 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
100957 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
100958 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
100959 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
100960 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
100961 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
100962 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
100963 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
100964 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
100965 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
100966 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
100967 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
100968 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
100969 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
100970 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
100971 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
100972 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
100973 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
100974 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
100975 +
100976 +/* Offsets relative to QM or BM portals base */
100977 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
100978 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
100979 +
100980 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
100981 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
100982 +
100983 +/**************************************************************************//**
100984 + @Description Transaction source ID (for memory controllers error reporting).
100985 +*//***************************************************************************/
100986 +typedef enum e_TransSrc
100987 +{
100988 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
100989 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
100990 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
100991 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
100992 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
100993 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
100994 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
100995 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
100996 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
100997 +} e_TransSrc;
100998 +
100999 +/**************************************************************************//**
101000 + @Description Local Access Window Target interface ID
101001 +*//***************************************************************************/
101002 +typedef enum e_P1023LawTargetId
101003 +{
101004 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
101005 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
101006 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
101007 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
101008 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
101009 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
101010 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
101011 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
101012 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
101013 +} e_P1023LawTargetId;
101014 +
101015 +
101016 +/**************************************************************************//**
101017 + @Group 1023_init_grp P1023 Initialization Unit
101018 +
101019 + @Description P1023 initialization unit API functions, definitions and enums
101020 +
101021 + @{
101022 +*//***************************************************************************/
101023 +
101024 +/**************************************************************************//**
101025 + @Description Part ID and revision number
101026 +*//***************************************************************************/
101027 +typedef enum e_P1023DeviceName
101028 +{
101029 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
101030 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
101031 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
101032 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
101033 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
101034 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
101035 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
101036 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
101037 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
101038 +} e_P1023DeviceName;
101039 +
101040 +/**************************************************************************//**
101041 + @Description structure representing P1023 initialization parameters
101042 +*//***************************************************************************/
101043 +typedef struct t_P1023Params
101044 +{
101045 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
101046 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
101047 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
101048 +} t_P1023Params;
101049 +
101050 +/**************************************************************************//**
101051 + @Function P1023_ConfigAndInit
101052 +
101053 + @Description General initiation of the chip registers.
101054 +
101055 + @Param[in] p_P1023Params - A pointer to data structure of parameters
101056 +
101057 + @Return A handle to the P1023 data structure.
101058 +*//***************************************************************************/
101059 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
101060 +
101061 +/**************************************************************************//**
101062 + @Function P1023_Free
101063 +
101064 + @Description Free all resources.
101065 +
101066 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
101067 +
101068 + @Return E_OK on success; Other value otherwise.
101069 +*//***************************************************************************/
101070 +t_Error P1023_Free(t_Handle h_P1023);
101071 +
101072 +/**************************************************************************//**
101073 + @Function P1023_GetRevInfo
101074 +
101075 + @Description This routine enables access to chip and revision information.
101076 +
101077 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101078 +
101079 + @Return Part ID and revision.
101080 +*//***************************************************************************/
101081 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
101082 +
101083 +/**************************************************************************//**
101084 + @Function P1023_GetE500Factor
101085 +
101086 + @Description Returns E500 core clock multiplication factor.
101087 +
101088 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101089 + @Param[in] coreId - Id of the requested core.
101090 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
101091 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
101092 +
101093 + @Return E_OK on success; Other value otherwise.
101094 +*
101095 +*//***************************************************************************/
101096 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
101097 + uint32_t coreId,
101098 + uint32_t *p_E500MulFactor,
101099 + uint32_t *p_E500DivFactor);
101100 +
101101 +/**************************************************************************//**
101102 + @Function P1023_GetFmFactor
101103 +
101104 + @Description returns FM multiplication factors. (This value is returned using
101105 + two parameters to avoid using float parameter).
101106 +
101107 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101108 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
101109 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
101110 +
101111 + @Return E_OK on success; Other value otherwise.
101112 +*//***************************************************************************/
101113 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
101114 +
101115 +/**************************************************************************//**
101116 + @Function P1023_GetCcbFactor
101117 +
101118 + @Description returns system multiplication factor.
101119 +
101120 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101121 +
101122 + @Return System multiplication factor.
101123 +*//***************************************************************************/
101124 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
101125 +
101126 +#if 0
101127 +/**************************************************************************//**
101128 + @Function P1023_GetDdrFactor
101129 +
101130 + @Description returns the multiplication factor of the clock in for the DDR clock .
101131 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
101132 +
101133 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101134 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
101135 + @Param p_DdrDivFactor - returns DDR division factor.
101136 +
101137 + @Return E_OK on success; Other value otherwise..
101138 +*//***************************************************************************/
101139 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
101140 + uint32_t *p_DdrMulFactor,
101141 + uint32_t *p_DdrDivFactor);
101142 +
101143 +/**************************************************************************//**
101144 + @Function P1023_GetDdrType
101145 +
101146 + @Description returns the multiplication factor of the clock in for the DDR clock .
101147 +
101148 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101149 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
101150 +
101151 + @Return E_OK on success; Other value otherwise.
101152 +*//***************************************************************************/
101153 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
101154 +#endif
101155 +
101156 +/** @} */ /* end of 1023_init_grp group */
101157 +/** @} */ /* end of 1023_grp group */
101158 +
101159 +#define CORE_E500V2
101160 +
101161 +#if 0 /* using unified values */
101162 +/*****************************************************************************
101163 + INTEGRATION-SPECIFIC MODULE CODES
101164 +******************************************************************************/
101165 +#define MODULE_UNKNOWN 0x00000000
101166 +#define MODULE_MEM 0x00010000
101167 +#define MODULE_MM 0x00020000
101168 +#define MODULE_CORE 0x00030000
101169 +#define MODULE_P1023 0x00040000
101170 +#define MODULE_MII 0x00050000
101171 +#define MODULE_PM 0x00060000
101172 +#define MODULE_MMU 0x00070000
101173 +#define MODULE_PIC 0x00080000
101174 +#define MODULE_L2_CACHE 0x00090000
101175 +#define MODULE_DUART 0x000a0000
101176 +#define MODULE_SERDES 0x000b0000
101177 +#define MODULE_PIO 0x000c0000
101178 +#define MODULE_QM 0x000d0000
101179 +#define MODULE_BM 0x000e0000
101180 +#define MODULE_SEC 0x000f0000
101181 +#define MODULE_FM 0x00100000
101182 +#define MODULE_FM_MURAM 0x00110000
101183 +#define MODULE_FM_PCD 0x00120000
101184 +#define MODULE_FM_RTC 0x00130000
101185 +#define MODULE_FM_MAC 0x00140000
101186 +#define MODULE_FM_PORT 0x00150000
101187 +#define MODULE_FM_MACSEC 0x00160000
101188 +#define MODULE_FM_MACSEC_SECY 0x00170000
101189 +#define MODULE_FM_SP 0x00280000
101190 +#define MODULE_ECM 0x00190000
101191 +#define MODULE_DMA 0x001a0000
101192 +#define MODULE_DDR 0x001b0000
101193 +#define MODULE_LAW 0x001c0000
101194 +#define MODULE_LBC 0x001d0000
101195 +#define MODULE_I2C 0x001e0000
101196 +#define MODULE_ESPI 0x001f0000
101197 +#define MODULE_PCI 0x00200000
101198 +#define MODULE_DPA_PORT 0x00210000
101199 +#define MODULE_USB 0x00220000
101200 +#endif /* using unified values */
101201 +
101202 +/*****************************************************************************
101203 + LBC INTEGRATION-SPECIFIC DEFINITIONS
101204 +******************************************************************************/
101205 +/**************************************************************************//**
101206 + @Group lbc_exception_grp LBC Exception Unit
101207 +
101208 + @Description LBC Exception unit API functions, definitions and enums
101209 +
101210 + @{
101211 +*//***************************************************************************/
101212 +
101213 +/**************************************************************************//**
101214 + @Anchor lbc_exbm
101215 +
101216 + @Collection LBC Errors Bit Mask
101217 +
101218 + These errors are reported through the exceptions callback..
101219 + The values can be or'ed in any combination in the errors mask
101220 + parameter of the errors report structure.
101221 +
101222 + These errors can also be passed as a bit-mask to
101223 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
101224 + for enabling or disabling error checking.
101225 + @{
101226 +*//***************************************************************************/
101227 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
101228 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
101229 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
101230 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
101231 +
101232 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
101233 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
101234 + /**< All possible errors */
101235 +/* @} */
101236 +/** @} */ /* end of lbc_exception_grp group */
101237 +
101238 +#define LBC_NUM_OF_BANKS 2
101239 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
101240 +#define LBC_ATOMIC_OPERATION_SUPPORT
101241 +#define LBC_PARITY_SUPPORT
101242 +#define LBC_ADDRESS_SHIFT_SUPPORT
101243 +#define LBC_ADDRESS_HOLD_TIME_CTRL
101244 +#define LBC_HIGH_CLK_DIVIDERS
101245 +#define LBC_FCM_AVAILABLE
101246 +
101247 +
101248 +/*****************************************************************************
101249 + LAW INTEGRATION-SPECIFIC DEFINITIONS
101250 +******************************************************************************/
101251 +#define LAW_ARCH_CCB
101252 +#define LAW_NUM_OF_WINDOWS 12
101253 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
101254 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
101255 +
101256 +
101257 +/*****************************************************************************
101258 + SPI INTEGRATION-SPECIFIC DEFINITIONS
101259 +******************************************************************************/
101260 +#define SPI_NUM_OF_CONTROLLERS 1
101261 +
101262 +/*****************************************************************************
101263 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
101264 +******************************************************************************/
101265 +
101266 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
101267 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
101268 +
101269 +/**************************************************************************//**
101270 + @Description Target interface of an inbound window
101271 +*//***************************************************************************/
101272 +typedef enum e_PciTargetInterface
101273 +{
101274 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
101275 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
101276 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
101277 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
101278 +
101279 +} e_PciTargetInterface;
101280 +
101281 +/*****************************************************************************
101282 + DDR INTEGRATION-SPECIFIC DEFINITIONS
101283 +******************************************************************************/
101284 +#define DDR_NUM_OF_VALID_CS 2
101285 +
101286 +/*****************************************************************************
101287 + SEC INTEGRATION-SPECIFIC DEFINITIONS
101288 +******************************************************************************/
101289 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
101290 +
101291 +/*****************************************************************************
101292 + DMA INTEGRATION-SPECIFIC DEFINITIONS
101293 +******************************************************************************/
101294 +#define DMA_NUM_OF_CONTROLLERS 2
101295 +
101296 +
101297 +
101298 +
101299 +/*****************************************************************************
101300 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
101301 +******************************************************************************/
101302 +#define PTP_V2
101303 +
101304 +/**************************************************************************//**
101305 + @Function P1023_GetMuxControlReg
101306 +
101307 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
101308 + Control Register)
101309 +
101310 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101311 +
101312 + @Return Value of PMUXCR
101313 +*//***************************************************************************/
101314 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
101315 +
101316 +/**************************************************************************//**
101317 + @Function P1023_SetMuxControlReg
101318 +
101319 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
101320 + Control Register)
101321 +
101322 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101323 + @Param[in] val - the new value for PMUXCR.
101324 +
101325 + @Return None
101326 +*//***************************************************************************/
101327 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
101328 +
101329 +/**************************************************************************//**
101330 + @Function P1023_GetDeviceDisableStatusRegister
101331 +
101332 + @Description Returns the value of DEVDISR (Device Disable Register)
101333 +
101334 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101335 +
101336 + @Return Value of DEVDISR
101337 +*//***************************************************************************/
101338 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
101339 +
101340 +/**************************************************************************//**
101341 + @Function P1023_GetPorDeviceStatusRegister
101342 +
101343 + @Description Returns the value of POR Device Status Register
101344 +
101345 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101346 +
101347 + @Return POR Device Status Register
101348 +*//***************************************************************************/
101349 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
101350 +
101351 +/**************************************************************************//**
101352 + @Function P1023_GetPorBootModeStatusRegister
101353 +
101354 + @Description Returns the value of POR Boot Mode Status Register
101355 +
101356 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101357 +
101358 + @Return POR Boot Mode Status Register value
101359 +*//***************************************************************************/
101360 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
101361 +
101362 +
101363 +#define PORDEVSR_SGMII1_DIS 0x10000000
101364 +#define PORDEVSR_SGMII2_DIS 0x08000000
101365 +#define PORDEVSR_ECP1 0x02000000
101366 +#define PORDEVSR_IO_SEL 0x00780000
101367 +#define PORDEVSR_IO_SEL_SHIFT 19
101368 +#define PORBMSR_HA 0x00070000
101369 +#define PORBMSR_HA_SHIFT 16
101370 +
101371 +#define DEVDISR_QM_BM 0x80000000
101372 +#define DEVDISR_FM 0x40000000
101373 +#define DEVDISR_PCIE1 0x20000000
101374 +#define DEVDISR_MAC_SEC 0x10000000
101375 +#define DEVDISR_ELBC 0x08000000
101376 +#define DEVDISR_PCIE2 0x04000000
101377 +#define DEVDISR_PCIE3 0x02000000
101378 +#define DEVDISR_CAAM 0x01000000
101379 +#define DEVDISR_USB0 0x00800000
101380 +#define DEVDISR_1588 0x00020000
101381 +#define DEVDISR_CORE0 0x00008000
101382 +#define DEVDISR_TB0 0x00004000
101383 +#define DEVDISR_CORE1 0x00002000
101384 +#define DEVDISR_TB1 0x00001000
101385 +#define DEVDISR_DMA1 0x00000400
101386 +#define DEVDISR_DMA2 0x00000200
101387 +#define DEVDISR_DDR 0x00000010
101388 +#define DEVDISR_TSEC1 0x00000080
101389 +#define DEVDISR_TSEC2 0x00000040
101390 +#define DEVDISR_SPI 0x00000008
101391 +#define DEVDISR_I2C 0x00000004
101392 +#define DEVDISR_DUART 0x00000002
101393 +
101394 +
101395 +#endif /* __PART_INTEGRATION_EXT_H */
101396 --- /dev/null
101397 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
101398 @@ -0,0 +1,276 @@
101399 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
101400 + * All rights reserved.
101401 + *
101402 + * Redistribution and use in source and binary forms, with or without
101403 + * modification, are permitted provided that the following conditions are met:
101404 + * * Redistributions of source code must retain the above copyright
101405 + * notice, this list of conditions and the following disclaimer.
101406 + * * Redistributions in binary form must reproduce the above copyright
101407 + * notice, this list of conditions and the following disclaimer in the
101408 + * documentation and/or other materials provided with the distribution.
101409 + * * Neither the name of Freescale Semiconductor nor the
101410 + * names of its contributors may be used to endorse or promote products
101411 + * derived from this software without specific prior written permission.
101412 + *
101413 + *
101414 + * ALTERNATIVELY, this software may be distributed under the terms of the
101415 + * GNU General Public License ("GPL") as published by the Free Software
101416 + * Foundation, either version 2 of that License or (at your option) any
101417 + * later version.
101418 + *
101419 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101420 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101421 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101422 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101423 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101424 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101425 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101426 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101427 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101428 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101429 + */
101430 +
101431 +/**************************************************************************//**
101432 + @File dpaa_integration_ext.h
101433 +
101434 + @Description P3040/P4080/P5020 FM external definitions and structures.
101435 +*//***************************************************************************/
101436 +#ifndef __DPAA_INTEGRATION_EXT_H
101437 +#define __DPAA_INTEGRATION_EXT_H
101438 +
101439 +#include "std_ext.h"
101440 +
101441 +
101442 +#define DPAA_VERSION 10
101443 +
101444 +typedef enum {
101445 + e_DPAA_SWPORTAL0 = 0,
101446 + e_DPAA_SWPORTAL1,
101447 + e_DPAA_SWPORTAL2,
101448 + e_DPAA_SWPORTAL3,
101449 + e_DPAA_SWPORTAL4,
101450 + e_DPAA_SWPORTAL5,
101451 + e_DPAA_SWPORTAL6,
101452 + e_DPAA_SWPORTAL7,
101453 + e_DPAA_SWPORTAL8,
101454 + e_DPAA_SWPORTAL9,
101455 + e_DPAA_SWPORTAL_DUMMY_LAST
101456 +} e_DpaaSwPortal;
101457 +
101458 +typedef enum {
101459 + e_DPAA_DCPORTAL0 = 0,
101460 + e_DPAA_DCPORTAL1,
101461 + e_DPAA_DCPORTAL2,
101462 + e_DPAA_DCPORTAL3,
101463 + e_DPAA_DCPORTAL4,
101464 + e_DPAA_DCPORTAL_DUMMY_LAST
101465 +} e_DpaaDcPortal;
101466 +
101467 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
101468 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
101469 +
101470 +/*****************************************************************************
101471 + QMan INTEGRATION-SPECIFIC DEFINITIONS
101472 +******************************************************************************/
101473 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
101474 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
101475 +#define QM_MAX_NUM_OF_SWP_AS 4
101476 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
101477 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
101478 +
101479 +/**************************************************************************//**
101480 + @Description Work Queue Channel assignments in QMan.
101481 +*//***************************************************************************/
101482 +typedef enum
101483 +{
101484 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
101485 + e_QM_FQ_CHANNEL_SWPORTAL1,
101486 + e_QM_FQ_CHANNEL_SWPORTAL2,
101487 + e_QM_FQ_CHANNEL_SWPORTAL3,
101488 + e_QM_FQ_CHANNEL_SWPORTAL4,
101489 + e_QM_FQ_CHANNEL_SWPORTAL5,
101490 + e_QM_FQ_CHANNEL_SWPORTAL6,
101491 + e_QM_FQ_CHANNEL_SWPORTAL7,
101492 + e_QM_FQ_CHANNEL_SWPORTAL8,
101493 + e_QM_FQ_CHANNEL_SWPORTAL9,
101494 +
101495 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
101496 + e_QM_FQ_CHANNEL_POOL2,
101497 + e_QM_FQ_CHANNEL_POOL3,
101498 + e_QM_FQ_CHANNEL_POOL4,
101499 + e_QM_FQ_CHANNEL_POOL5,
101500 + e_QM_FQ_CHANNEL_POOL6,
101501 + e_QM_FQ_CHANNEL_POOL7,
101502 + e_QM_FQ_CHANNEL_POOL8,
101503 + e_QM_FQ_CHANNEL_POOL9,
101504 + e_QM_FQ_CHANNEL_POOL10,
101505 + e_QM_FQ_CHANNEL_POOL11,
101506 + e_QM_FQ_CHANNEL_POOL12,
101507 + e_QM_FQ_CHANNEL_POOL13,
101508 + e_QM_FQ_CHANNEL_POOL14,
101509 + e_QM_FQ_CHANNEL_POOL15,
101510 +
101511 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
101512 + connected to FMan 0; assigned in incrementing order to
101513 + each sub-portal (SP) in the portal */
101514 + e_QM_FQ_CHANNEL_FMAN0_SP1,
101515 + e_QM_FQ_CHANNEL_FMAN0_SP2,
101516 + e_QM_FQ_CHANNEL_FMAN0_SP3,
101517 + e_QM_FQ_CHANNEL_FMAN0_SP4,
101518 + e_QM_FQ_CHANNEL_FMAN0_SP5,
101519 + e_QM_FQ_CHANNEL_FMAN0_SP6,
101520 + e_QM_FQ_CHANNEL_FMAN0_SP7,
101521 + e_QM_FQ_CHANNEL_FMAN0_SP8,
101522 + e_QM_FQ_CHANNEL_FMAN0_SP9,
101523 + e_QM_FQ_CHANNEL_FMAN0_SP10,
101524 + e_QM_FQ_CHANNEL_FMAN0_SP11,
101525 +/* difference between 5020 and 4080 :) */
101526 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
101527 + e_QM_FQ_CHANNEL_FMAN1_SP1,
101528 + e_QM_FQ_CHANNEL_FMAN1_SP2,
101529 + e_QM_FQ_CHANNEL_FMAN1_SP3,
101530 + e_QM_FQ_CHANNEL_FMAN1_SP4,
101531 + e_QM_FQ_CHANNEL_FMAN1_SP5,
101532 + e_QM_FQ_CHANNEL_FMAN1_SP6,
101533 + e_QM_FQ_CHANNEL_FMAN1_SP7,
101534 + e_QM_FQ_CHANNEL_FMAN1_SP8,
101535 + e_QM_FQ_CHANNEL_FMAN1_SP9,
101536 + e_QM_FQ_CHANNEL_FMAN1_SP10,
101537 + e_QM_FQ_CHANNEL_FMAN1_SP11,
101538 +
101539 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
101540 + connected to SEC 4.x */
101541 +
101542 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
101543 + connected to PME */
101544 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
101545 + connected to RAID */
101546 +} e_QmFQChannel;
101547 +
101548 +/*****************************************************************************
101549 + BMan INTEGRATION-SPECIFIC DEFINITIONS
101550 +******************************************************************************/
101551 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
101552 +
101553 +
101554 +/*****************************************************************************
101555 + FM INTEGRATION-SPECIFIC DEFINITIONS
101556 +******************************************************************************/
101557 +#define INTG_MAX_NUM_OF_FM 2
101558 +
101559 +/* Ports defines */
101560 +#define FM_MAX_NUM_OF_1G_MACS 5
101561 +#define FM_MAX_NUM_OF_10G_MACS 1
101562 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
101563 +#define FM_MAX_NUM_OF_OH_PORTS 7
101564 +
101565 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
101566 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
101567 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
101568 +
101569 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
101570 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
101571 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
101572 +
101573 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
101574 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
101575 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
101576 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
101577 +
101578 +/* Rams defines */
101579 +#define FM_MURAM_SIZE (160*KILOBYTE)
101580 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
101581 +#define FM_NUM_OF_CTRL 2
101582 +
101583 +/* PCD defines */
101584 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
101585 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
101586 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
101587 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
101588 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
101589 +
101590 +/* RTC defines */
101591 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
101592 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
101593 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
101594 +
101595 +/* QMI defines */
101596 +#define QMI_MAX_NUM_OF_TNUMS 64
101597 +#define QMI_DEF_TNUMS_THRESH 48
101598 +
101599 +/* FPM defines */
101600 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
101601 +
101602 +/* DMA defines */
101603 +#define DMA_THRESH_MAX_COMMQ 31
101604 +#define DMA_THRESH_MAX_BUF 127
101605 +
101606 +/* BMI defines */
101607 +#define BMI_MAX_NUM_OF_TASKS 128
101608 +#define BMI_MAX_NUM_OF_DMAS 32
101609 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
101610 +#define PORT_MAX_WEIGHT 16
101611 +
101612 +
101613 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
101614 +
101615 +/* p4080-rev1 unique features */
101616 +#define QM_CGS_NO_FRAME_MODE
101617 +
101618 +/* p4080 unique features */
101619 +#define FM_NO_DISPATCH_RAM_ECC
101620 +#define FM_NO_WATCHDOG
101621 +#define FM_NO_TNUM_AGING
101622 +#define FM_KG_NO_BYPASS_FQID_GEN
101623 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
101624 +#define FM_NO_BACKUP_POOLS
101625 +#define FM_NO_OP_OBSERVED_POOLS
101626 +#define FM_NO_ADVANCED_RATE_LIMITER
101627 +#define FM_NO_OP_OBSERVED_CGS
101628 +#define FM_HAS_TOTAL_DMAS
101629 +#define FM_KG_NO_IPPID_SUPPORT
101630 +#define FM_NO_GUARANTEED_RESET_VALUES
101631 +#define FM_MAC_RESET
101632 +
101633 +/* FM erratas */
101634 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
101635 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
101636 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
101637 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
101638 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
101639 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
101640 +
101641 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
101642 +#define FM_GRS_ERRATA_DTSEC_A002
101643 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
101644 +#define FM_GTS_ERRATA_DTSEC_A004
101645 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
101646 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
101647 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
101648 +
101649 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
101650 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
101651 +
101652 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
101653 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
101654 +
101655 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
101656 +
101657 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
101658 +
101659 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
101660 +
101661 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
101662 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
101663 +
101664 +/*****************************************************************************
101665 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
101666 +******************************************************************************/
101667 +#define NUM_OF_RX_SC 16
101668 +#define NUM_OF_TX_SC 16
101669 +
101670 +#define NUM_OF_SA_PER_RX_SC 2
101671 +#define NUM_OF_SA_PER_TX_SC 2
101672 +
101673 +
101674 +#endif /* __DPAA_INTEGRATION_EXT_H */
101675 --- /dev/null
101676 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
101677 @@ -0,0 +1,83 @@
101678 +/*
101679 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101680 + *
101681 + * Redistribution and use in source and binary forms, with or without
101682 + * modification, are permitted provided that the following conditions are met:
101683 + * * Redistributions of source code must retain the above copyright
101684 + * notice, this list of conditions and the following disclaimer.
101685 + * * Redistributions in binary form must reproduce the above copyright
101686 + * notice, this list of conditions and the following disclaimer in the
101687 + * documentation and/or other materials provided with the distribution.
101688 + * * Neither the name of Freescale Semiconductor nor the
101689 + * names of its contributors may be used to endorse or promote products
101690 + * derived from this software without specific prior written permission.
101691 + *
101692 + *
101693 + * ALTERNATIVELY, this software may be distributed under the terms of the
101694 + * GNU General Public License ("GPL") as published by the Free Software
101695 + * Foundation, either version 2 of that License or (at your option) any
101696 + * later version.
101697 + *
101698 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101699 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101700 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101701 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101702 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101703 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101704 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101705 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101706 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101707 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101708 + */
101709 +
101710 +/**************************************************************************//**
101711 +
101712 + @File part_ext.h
101713 +
101714 + @Description Definitions for the part (integration) module.
101715 +*//***************************************************************************/
101716 +
101717 +#ifndef __PART_EXT_H
101718 +#define __PART_EXT_H
101719 +
101720 +#include "std_ext.h"
101721 +#include "part_integration_ext.h"
101722 +
101723 +
101724 +#if !(defined(MPC8306) || \
101725 + defined(MPC8309) || \
101726 + defined(MPC834x) || \
101727 + defined(MPC836x) || \
101728 + defined(MPC832x) || \
101729 + defined(MPC837x) || \
101730 + defined(MPC8568) || \
101731 + defined(MPC8569) || \
101732 + defined(P1020) || \
101733 + defined(P1021) || \
101734 + defined(P1022) || \
101735 + defined(P1023) || \
101736 + defined(P2020) || \
101737 + defined(P2040) || \
101738 + defined(P3041) || \
101739 + defined(P4080) || \
101740 + defined(SC4080) || \
101741 + defined(P5020) || \
101742 + defined(MSC814x))
101743 +#error "unable to proceed without chip-definition"
101744 +#endif /* !(defined(MPC834x) || ... */
101745 +
101746 +
101747 +/**************************************************************************//*
101748 + @Description Part data structure - must be contained in any integration
101749 + data structure.
101750 +*//***************************************************************************/
101751 +typedef struct t_Part
101752 +{
101753 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
101754 + /**< Returns the address of the module's memory map base. */
101755 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
101756 + /**< Returns the module's ID according to its memory map base. */
101757 +} t_Part;
101758 +
101759 +
101760 +#endif /* __PART_EXT_H */
101761 --- /dev/null
101762 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
101763 @@ -0,0 +1,336 @@
101764 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101765 + * All rights reserved.
101766 + *
101767 + * Redistribution and use in source and binary forms, with or without
101768 + * modification, are permitted provided that the following conditions are met:
101769 + * * Redistributions of source code must retain the above copyright
101770 + * notice, this list of conditions and the following disclaimer.
101771 + * * Redistributions in binary form must reproduce the above copyright
101772 + * notice, this list of conditions and the following disclaimer in the
101773 + * documentation and/or other materials provided with the distribution.
101774 + * * Neither the name of Freescale Semiconductor nor the
101775 + * names of its contributors may be used to endorse or promote products
101776 + * derived from this software without specific prior written permission.
101777 + *
101778 + *
101779 + * ALTERNATIVELY, this software may be distributed under the terms of the
101780 + * GNU General Public License ("GPL") as published by the Free Software
101781 + * Foundation, either version 2 of that License or (at your option) any
101782 + * later version.
101783 + *
101784 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101785 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101786 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101787 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101788 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101789 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101790 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101791 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101792 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101793 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101794 + */
101795 +
101796 +/**************************************************************************//**
101797 + @File part_integration_ext.h
101798 +
101799 + @Description P3040/P4080/P5020 external definitions and structures.
101800 +*//***************************************************************************/
101801 +#ifndef __PART_INTEGRATION_EXT_H
101802 +#define __PART_INTEGRATION_EXT_H
101803 +
101804 +#include "std_ext.h"
101805 +#include "dpaa_integration_ext.h"
101806 +
101807 +
101808 +/**************************************************************************//**
101809 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
101810 +
101811 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
101812 +
101813 + @{
101814 +*//***************************************************************************/
101815 +
101816 +#define CORE_E500MC
101817 +
101818 +#define INTG_MAX_NUM_OF_CORES 1
101819 +
101820 +
101821 +/**************************************************************************//**
101822 + @Description Module types.
101823 +*//***************************************************************************/
101824 +typedef enum e_ModuleId
101825 +{
101826 + e_MODULE_ID_DUART_1 = 0,
101827 + e_MODULE_ID_DUART_2,
101828 + e_MODULE_ID_DUART_3,
101829 + e_MODULE_ID_DUART_4,
101830 + e_MODULE_ID_LAW,
101831 + e_MODULE_ID_LBC,
101832 + e_MODULE_ID_PAMU,
101833 + e_MODULE_ID_QM, /**< Queue manager module */
101834 + e_MODULE_ID_BM, /**< Buffer manager module */
101835 + e_MODULE_ID_QM_CE_PORTAL_0,
101836 + e_MODULE_ID_QM_CI_PORTAL_0,
101837 + e_MODULE_ID_QM_CE_PORTAL_1,
101838 + e_MODULE_ID_QM_CI_PORTAL_1,
101839 + e_MODULE_ID_QM_CE_PORTAL_2,
101840 + e_MODULE_ID_QM_CI_PORTAL_2,
101841 + e_MODULE_ID_QM_CE_PORTAL_3,
101842 + e_MODULE_ID_QM_CI_PORTAL_3,
101843 + e_MODULE_ID_QM_CE_PORTAL_4,
101844 + e_MODULE_ID_QM_CI_PORTAL_4,
101845 + e_MODULE_ID_QM_CE_PORTAL_5,
101846 + e_MODULE_ID_QM_CI_PORTAL_5,
101847 + e_MODULE_ID_QM_CE_PORTAL_6,
101848 + e_MODULE_ID_QM_CI_PORTAL_6,
101849 + e_MODULE_ID_QM_CE_PORTAL_7,
101850 + e_MODULE_ID_QM_CI_PORTAL_7,
101851 + e_MODULE_ID_QM_CE_PORTAL_8,
101852 + e_MODULE_ID_QM_CI_PORTAL_8,
101853 + e_MODULE_ID_QM_CE_PORTAL_9,
101854 + e_MODULE_ID_QM_CI_PORTAL_9,
101855 + e_MODULE_ID_BM_CE_PORTAL_0,
101856 + e_MODULE_ID_BM_CI_PORTAL_0,
101857 + e_MODULE_ID_BM_CE_PORTAL_1,
101858 + e_MODULE_ID_BM_CI_PORTAL_1,
101859 + e_MODULE_ID_BM_CE_PORTAL_2,
101860 + e_MODULE_ID_BM_CI_PORTAL_2,
101861 + e_MODULE_ID_BM_CE_PORTAL_3,
101862 + e_MODULE_ID_BM_CI_PORTAL_3,
101863 + e_MODULE_ID_BM_CE_PORTAL_4,
101864 + e_MODULE_ID_BM_CI_PORTAL_4,
101865 + e_MODULE_ID_BM_CE_PORTAL_5,
101866 + e_MODULE_ID_BM_CI_PORTAL_5,
101867 + e_MODULE_ID_BM_CE_PORTAL_6,
101868 + e_MODULE_ID_BM_CI_PORTAL_6,
101869 + e_MODULE_ID_BM_CE_PORTAL_7,
101870 + e_MODULE_ID_BM_CI_PORTAL_7,
101871 + e_MODULE_ID_BM_CE_PORTAL_8,
101872 + e_MODULE_ID_BM_CI_PORTAL_8,
101873 + e_MODULE_ID_BM_CE_PORTAL_9,
101874 + e_MODULE_ID_BM_CI_PORTAL_9,
101875 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
101876 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
101877 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
101878 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
101879 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
101880 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
101881 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
101882 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
101883 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
101884 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
101885 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
101886 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
101887 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
101888 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
101889 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
101890 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
101891 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
101892 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
101893 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
101894 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
101895 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
101896 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
101897 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
101898 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
101899 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
101900 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
101901 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
101902 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
101903 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
101904 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
101905 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
101906 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
101907 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
101908 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
101909 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
101910 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
101911 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
101912 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
101913 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
101914 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
101915 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
101916 +
101917 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
101918 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
101919 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
101920 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
101921 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
101922 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
101923 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
101924 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
101925 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
101926 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
101927 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
101928 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
101929 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
101930 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
101931 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
101932 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
101933 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
101934 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
101935 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
101936 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
101937 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
101938 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
101939 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
101940 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
101941 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
101942 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
101943 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
101944 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
101945 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
101946 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
101947 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
101948 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
101949 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
101950 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
101951 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
101952 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
101953 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
101954 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
101955 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
101956 +
101957 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
101958 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
101959 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
101960 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
101961 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
101962 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
101963 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
101964 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
101965 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
101966 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
101967 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
101968 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
101969 +
101970 + e_MODULE_ID_MPIC, /**< MPIC */
101971 + e_MODULE_ID_GPIO, /**< GPIO */
101972 + e_MODULE_ID_SERDES, /**< SERDES */
101973 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
101974 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
101975 +
101976 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
101977 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
101978 +
101979 + e_MODULE_ID_DUMMY_LAST
101980 +} e_ModuleId;
101981 +
101982 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
101983 +
101984 +#if 0 /* using unified values */
101985 +/*****************************************************************************
101986 + INTEGRATION-SPECIFIC MODULE CODES
101987 +******************************************************************************/
101988 +#define MODULE_UNKNOWN 0x00000000
101989 +#define MODULE_MEM 0x00010000
101990 +#define MODULE_MM 0x00020000
101991 +#define MODULE_CORE 0x00030000
101992 +#define MODULE_CHIP 0x00040000
101993 +#define MODULE_PLTFRM 0x00050000
101994 +#define MODULE_PM 0x00060000
101995 +#define MODULE_MMU 0x00070000
101996 +#define MODULE_PIC 0x00080000
101997 +#define MODULE_CPC 0x00090000
101998 +#define MODULE_DUART 0x000a0000
101999 +#define MODULE_SERDES 0x000b0000
102000 +#define MODULE_PIO 0x000c0000
102001 +#define MODULE_QM 0x000d0000
102002 +#define MODULE_BM 0x000e0000
102003 +#define MODULE_SEC 0x000f0000
102004 +#define MODULE_LAW 0x00100000
102005 +#define MODULE_LBC 0x00110000
102006 +#define MODULE_PAMU 0x00120000
102007 +#define MODULE_FM 0x00130000
102008 +#define MODULE_FM_MURAM 0x00140000
102009 +#define MODULE_FM_PCD 0x00150000
102010 +#define MODULE_FM_RTC 0x00160000
102011 +#define MODULE_FM_MAC 0x00170000
102012 +#define MODULE_FM_PORT 0x00180000
102013 +#define MODULE_FM_SP 0x00190000
102014 +#define MODULE_DPA_PORT 0x001a0000
102015 +#define MODULE_MII 0x001b0000
102016 +#define MODULE_I2C 0x001c0000
102017 +#define MODULE_DMA 0x001d0000
102018 +#define MODULE_DDR 0x001e0000
102019 +#define MODULE_ESPI 0x001f0000
102020 +#define MODULE_DPAA_IPSEC 0x00200000
102021 +#endif /* using unified values */
102022 +
102023 +/*****************************************************************************
102024 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
102025 +******************************************************************************/
102026 +#define PAMU_NUM_OF_PARTITIONS 5
102027 +
102028 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
102029 +
102030 +/*****************************************************************************
102031 + LAW INTEGRATION-SPECIFIC DEFINITIONS
102032 +******************************************************************************/
102033 +#define LAW_NUM_OF_WINDOWS 32
102034 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
102035 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
102036 +
102037 +
102038 +/*****************************************************************************
102039 + LBC INTEGRATION-SPECIFIC DEFINITIONS
102040 +******************************************************************************/
102041 +/**************************************************************************//**
102042 + @Group lbc_exception_grp LBC Exception Unit
102043 +
102044 + @Description LBC Exception unit API functions, definitions and enums
102045 +
102046 + @{
102047 +*//***************************************************************************/
102048 +
102049 +/**************************************************************************//**
102050 + @Anchor lbc_exbm
102051 +
102052 + @Collection LBC Errors Bit Mask
102053 +
102054 + These errors are reported through the exceptions callback..
102055 + The values can be or'ed in any combination in the errors mask
102056 + parameter of the errors report structure.
102057 +
102058 + These errors can also be passed as a bit-mask to
102059 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
102060 + for enabling or disabling error checking.
102061 + @{
102062 +*//***************************************************************************/
102063 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
102064 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
102065 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
102066 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
102067 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
102068 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
102069 +
102070 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
102071 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
102072 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
102073 + /**< All possible errors */
102074 +/* @} */
102075 +/** @} */ /* end of lbc_exception_grp group */
102076 +
102077 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
102078 +
102079 +#define LBC_NUM_OF_BANKS 8
102080 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
102081 +#define LBC_ATOMIC_OPERATION_SUPPORT
102082 +#define LBC_PARITY_SUPPORT
102083 +#define LBC_ADDRESS_HOLD_TIME_CTRL
102084 +#define LBC_HIGH_CLK_DIVIDERS
102085 +#define LBC_FCM_AVAILABLE
102086 +
102087 +/*****************************************************************************
102088 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
102089 +******************************************************************************/
102090 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
102091 + Each port contains up to 32 i/O pins. */
102092 +
102093 +#define GPIO_VALID_PIN_MASKS \
102094 + { /* Port A */ 0xFFFFFFFF }
102095 +
102096 +#define GPIO_VALID_INTR_MASKS \
102097 + { /* Port A */ 0xFFFFFFFF }
102098 +
102099 +#endif /* __PART_INTEGRATION_EXT_H */
102100 --- /dev/null
102101 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
102102 @@ -0,0 +1,100 @@
102103 +/*
102104 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102105 + *
102106 + * Redistribution and use in source and binary forms, with or without
102107 + * modification, are permitted provided that the following conditions are met:
102108 + * * Redistributions of source code must retain the above copyright
102109 + * notice, this list of conditions and the following disclaimer.
102110 + * * Redistributions in binary form must reproduce the above copyright
102111 + * notice, this list of conditions and the following disclaimer in the
102112 + * documentation and/or other materials provided with the distribution.
102113 + * * Neither the name of Freescale Semiconductor nor the
102114 + * names of its contributors may be used to endorse or promote products
102115 + * derived from this software without specific prior written permission.
102116 + *
102117 + *
102118 + * ALTERNATIVELY, this software may be distributed under the terms of the
102119 + * GNU General Public License ("GPL") as published by the Free Software
102120 + * Foundation, either version 2 of that License or (at your option) any
102121 + * later version.
102122 + *
102123 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102124 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102125 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102126 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102127 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102128 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102129 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102130 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102131 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102132 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102133 + */
102134 +
102135 +
102136 +#ifndef __MATH_EXT_H
102137 +#define __MATH_EXT_H
102138 +
102139 +
102140 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
102141 +#include <linux/math.h>
102142 +#include <linux/math64.h>
102143 +
102144 +#elif defined(__MWERKS__)
102145 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
102146 +#define HIGH(x) (*(int32_t*)&x)
102147 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
102148 +#define UHIGH(x) (*(uint32_t*)&x)
102149 +
102150 +static const double big = 1.0e300;
102151 +
102152 +/* Macro for checking if a number is a power of 2 */
102153 +static __inline__ double ceil(double x)
102154 +{
102155 + int32_t i0,i1,j0; /*- cc 020130 -*/
102156 + uint32_t i,j; /*- cc 020130 -*/
102157 + i0 = HIGH(x);
102158 + i1 = LOW(x);
102159 + j0 = ((i0>>20)&0x7ff)-0x3ff;
102160 + if(j0<20) {
102161 + if(j0<0) { /* raise inexact if x != 0 */
102162 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
102163 + if(i0<0) {i0=0x80000000;i1=0;}
102164 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
102165 + }
102166 + } else {
102167 + i = (uint32_t)(0x000fffff)>>j0;
102168 + if(((i0&i)|i1)==0) return x; /* x is integral */
102169 + if(big+x>0.0) { /* raise inexact flag */
102170 + if(i0>0) i0 += (0x00100000)>>j0;
102171 + i0 &= (~i); i1=0;
102172 + }
102173 + }
102174 + } else if (j0>51) {
102175 + if(j0==0x400) return x+x; /* inf or NaN */
102176 + else return x; /* x is integral */
102177 + } else {
102178 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
102179 + if((i1&i)==0) return x; /* x is integral */
102180 + if(big+x>0.0) { /* raise inexact flag */
102181 + if(i0>0) {
102182 + if(j0==20) i0+=1;
102183 + else {
102184 + j = (uint32_t)(i1 + (1<<(52-j0)));
102185 + if(j<i1) i0+=1; /* got a carry */
102186 + i1 = (int32_t)j;
102187 + }
102188 + }
102189 + i1 &= (~i);
102190 + }
102191 + }
102192 + HIGH(x) = i0;
102193 + LOW(x) = i1;
102194 + return x;
102195 +}
102196 +
102197 +#else
102198 +#include <math.h>
102199 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102200 +
102201 +
102202 +#endif /* __MATH_EXT_H */
102203 --- /dev/null
102204 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
102205 @@ -0,0 +1,435 @@
102206 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102207 + * All rights reserved.
102208 + *
102209 + * Redistribution and use in source and binary forms, with or without
102210 + * modification, are permitted provided that the following conditions are met:
102211 + * * Redistributions of source code must retain the above copyright
102212 + * notice, this list of conditions and the following disclaimer.
102213 + * * Redistributions in binary form must reproduce the above copyright
102214 + * notice, this list of conditions and the following disclaimer in the
102215 + * documentation and/or other materials provided with the distribution.
102216 + * * Neither the name of Freescale Semiconductor nor the
102217 + * names of its contributors may be used to endorse or promote products
102218 + * derived from this software without specific prior written permission.
102219 + *
102220 + *
102221 + * ALTERNATIVELY, this software may be distributed under the terms of the
102222 + * GNU General Public License ("GPL") as published by the Free Software
102223 + * Foundation, either version 2 of that License or (at your option) any
102224 + * later version.
102225 + *
102226 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102227 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102228 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102229 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102230 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102231 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102232 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102233 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102234 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102235 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102236 + */
102237 +
102238 +
102239 +/**************************************************************************//**
102240 + @File ncsw_ext.h
102241 +
102242 + @Description General NetCommSw Standard Definitions
102243 +*//***************************************************************************/
102244 +
102245 +#ifndef __NCSW_EXT_H
102246 +#define __NCSW_EXT_H
102247 +
102248 +
102249 +#include "memcpy_ext.h"
102250 +
102251 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
102252 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
102253 +
102254 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
102255 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
102256 +
102257 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
102258 +
102259 +
102260 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
102261 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
102262 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
102263 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
102264 +
102265 +/* Little-Endian access macros */
102266 +
102267 +#define WRITE_UINT16_LE(arg, data) \
102268 + WRITE_UINT16((arg), SwapUint16(data))
102269 +
102270 +#define WRITE_UINT32_LE(arg, data) \
102271 + WRITE_UINT32((arg), SwapUint32(data))
102272 +
102273 +#define WRITE_UINT64_LE(arg, data) \
102274 + WRITE_UINT64((arg), SwapUint64(data))
102275 +
102276 +#define GET_UINT16_LE(arg) \
102277 + SwapUint16(GET_UINT16(arg))
102278 +
102279 +#define GET_UINT32_LE(arg) \
102280 + SwapUint32(GET_UINT32(arg))
102281 +
102282 +#define GET_UINT64_LE(arg) \
102283 + SwapUint64(GET_UINT64(arg))
102284 +
102285 +/* Write and Read again macros */
102286 +#define WRITE_UINT_SYNC(size, arg, data) \
102287 + do { \
102288 + WRITE_UINT##size((arg), (data)); \
102289 + CORE_MemoryBarrier(); \
102290 + } while (0)
102291 +
102292 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
102293 +
102294 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
102295 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
102296 +
102297 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
102298 +
102299 +
102300 +/*----------------------*/
102301 +/* Miscellaneous macros */
102302 +/*----------------------*/
102303 +
102304 +#define UNUSED(_x) ((void)(_x))
102305 +
102306 +#define KILOBYTE 0x400UL /* 1024 */
102307 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
102308 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
102309 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
102310 +
102311 +#ifndef NO_IRQ
102312 +#define NO_IRQ (0)
102313 +#endif
102314 +#define NCSW_MASTER_ID (0)
102315 +
102316 +/* Macro for checking if a number is a power of 2 */
102317 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
102318 +
102319 +/* Macro for calculating log of base 2 */
102320 +#define LOG2(num, log2Num) \
102321 + do \
102322 + { \
102323 + uint64_t tmp = (num); \
102324 + log2Num = 0; \
102325 + while (tmp > 1) \
102326 + { \
102327 + log2Num++; \
102328 + tmp >>= 1; \
102329 + } \
102330 + } while (0)
102331 +
102332 +#define NEXT_POWER_OF_2(_num, _nextPow) \
102333 +do \
102334 +{ \
102335 + if (POWER_OF_2(_num)) \
102336 + _nextPow = (_num); \
102337 + else \
102338 + { \
102339 + uint64_t tmp = (_num); \
102340 + _nextPow = 1; \
102341 + while (tmp) \
102342 + { \
102343 + _nextPow <<= 1; \
102344 + tmp >>= 1; \
102345 + } \
102346 + } \
102347 +} while (0)
102348 +
102349 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
102350 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
102351 +
102352 +/* Round up a number to be a multiple of a second number */
102353 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
102354 +
102355 +/* Timing macro for converting usec units to number of ticks. */
102356 +/* (number of usec * clock_Hz) / 1,000,000) - since */
102357 +/* clk is in MHz units, no division needed. */
102358 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
102359 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
102360 +
102361 +/* Timing macros for converting between nsec units and number of clocks. */
102362 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
102363 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
102364 +
102365 +/* Timing macros for converting between psec units and number of clocks. */
102366 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
102367 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
102368 +
102369 +/* Min, Max macros */
102370 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
102371 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
102372 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
102373 +
102374 +#define ABS(a) ((a<0)?(a*-1):a)
102375 +
102376 +#if !(defined(ARRAY_SIZE))
102377 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
102378 +#endif /* !defined(ARRAY_SIZE) */
102379 +
102380 +
102381 +/* possible alignments */
102382 +#define HALF_WORD_ALIGNMENT 2
102383 +#define WORD_ALIGNMENT 4
102384 +#define DOUBLE_WORD_ALIGNMENT 8
102385 +#define BURST_ALIGNMENT 32
102386 +
102387 +#define HALF_WORD_ALIGNED 0x00000001
102388 +#define WORD_ALIGNED 0x00000003
102389 +#define DOUBLE_WORD_ALIGNED 0x00000007
102390 +#define BURST_ALIGNED 0x0000001f
102391 +#ifndef IS_ALIGNED
102392 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
102393 +#endif /* IS_ALIGNED */
102394 +
102395 +
102396 +#define LAST_BUF 1
102397 +#define FIRST_BUF 2
102398 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
102399 +#define MIDDLE_BUF 4
102400 +
102401 +#define ARRAY_END -1
102402 +
102403 +#define ILLEGAL_BASE (~0)
102404 +
102405 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
102406 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
102407 +
102408 +
102409 +/**************************************************************************//**
102410 + @Description Timers operation mode
102411 +*//***************************************************************************/
102412 +typedef enum e_TimerMode
102413 +{
102414 + e_TIMER_MODE_INVALID = 0,
102415 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
102416 + after reaching the reference value. */
102417 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
102418 + after reaching the reference value. */
102419 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
102420 + after reaching the reference value. */
102421 +} e_TimerMode;
102422 +
102423 +
102424 +/**************************************************************************//**
102425 + @Description Enumeration (bit flags) of communication modes (Transmit,
102426 + receive or both).
102427 +*//***************************************************************************/
102428 +typedef enum e_CommMode
102429 +{
102430 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
102431 + e_COMM_MODE_RX = 1, /**< Only receive communication */
102432 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
102433 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
102434 +} e_CommMode;
102435 +
102436 +/**************************************************************************//**
102437 + @Description General Diagnostic Mode
102438 +*//***************************************************************************/
102439 +typedef enum e_DiagMode
102440 +{
102441 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
102442 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
102443 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
102444 + controller; e.g. IO-pins, SerDes, etc. */
102445 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
102446 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
102447 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
102448 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
102449 +} e_DiagMode;
102450 +
102451 +/**************************************************************************//**
102452 + @Description Possible RxStore callback responses.
102453 +*//***************************************************************************/
102454 +typedef enum e_RxStoreResponse
102455 +{
102456 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
102457 + in polling mode, start again invoking callback
102458 + only next time user invokes the receive routine;
102459 + in interrupt mode, start again invoking callback
102460 + only next time a receive event triggers an interrupt;
102461 + in all cases, received data that are pending are not
102462 + lost, rather, their processing is temporarily deferred;
102463 + in all cases, received data are processed in the order
102464 + in which they were received. */
102465 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
102466 +} e_RxStoreResponse;
102467 +
102468 +
102469 +/**************************************************************************//**
102470 + @Description General Handle
102471 +*//***************************************************************************/
102472 +typedef void * t_Handle; /**< handle, used as object's descriptor */
102473 +
102474 +/**************************************************************************//**
102475 + @Description MUTEX type
102476 +*//***************************************************************************/
102477 +typedef uint32_t t_Mutex;
102478 +
102479 +/**************************************************************************//**
102480 + @Description Error Code.
102481 +
102482 + The high word of the error code is the code of the software
102483 + module (driver). The low word is the error type (e_ErrorType).
102484 + To get the values from the error code, use GET_ERROR_TYPE()
102485 + and GET_ERROR_MODULE().
102486 +*//***************************************************************************/
102487 +typedef uint32_t t_Error;
102488 +
102489 +/**************************************************************************//**
102490 + @Description General prototype of interrupt service routine (ISR).
102491 +
102492 + @Param[in] handle - Optional handle of the module handling the interrupt.
102493 +
102494 + @Return None
102495 + *//***************************************************************************/
102496 +typedef void (t_Isr)(t_Handle handle);
102497 +
102498 +/**************************************************************************//**
102499 + @Anchor mem_attr
102500 +
102501 + @Collection Memory Attributes
102502 +
102503 + Various attributes of memory partitions. These values may be
102504 + or'ed together to create a mask of all memory attributes.
102505 + @{
102506 +*//***************************************************************************/
102507 +#define MEMORY_ATTR_CACHEABLE 0x00000001
102508 + /**< Memory is cacheable */
102509 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
102510 + /**< Memory can be accessed by QUICC Engine
102511 + through its secondary bus interface */
102512 +
102513 +/* @} */
102514 +
102515 +
102516 +/**************************************************************************//**
102517 + @Function t_GetBufFunction
102518 +
102519 + @Description User callback function called by driver to get data buffer.
102520 +
102521 + User provides this function. Driver invokes it.
102522 +
102523 + @Param[in] h_BufferPool - A handle to buffer pool manager
102524 + @Param[out] p_BufContextHandle - Returns the user's private context that
102525 + should be associated with the buffer
102526 +
102527 + @Return Pointer to data buffer, NULL if error
102528 + *//***************************************************************************/
102529 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
102530 + t_Handle *p_BufContextHandle);
102531 +
102532 +/**************************************************************************//**
102533 + @Function t_PutBufFunction
102534 +
102535 + @Description User callback function called by driver to return data buffer.
102536 +
102537 + User provides this function. Driver invokes it.
102538 +
102539 + @Param[in] h_BufferPool - A handle to buffer pool manager
102540 + @Param[in] p_Buffer - A pointer to buffer to return
102541 + @Param[in] h_BufContext - The user's private context associated with
102542 + the returned buffer
102543 +
102544 + @Return E_OK on success; Error code otherwise
102545 + *//***************************************************************************/
102546 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
102547 + uint8_t *p_Buffer,
102548 + t_Handle h_BufContext);
102549 +
102550 +/**************************************************************************//**
102551 + @Function t_PhysToVirt
102552 +
102553 + @Description Translates a physical address to the matching virtual address.
102554 +
102555 + @Param[in] addr - The physical address to translate.
102556 +
102557 + @Return Virtual address.
102558 +*//***************************************************************************/
102559 +typedef void * t_PhysToVirt(physAddress_t addr);
102560 +
102561 +/**************************************************************************//**
102562 + @Function t_VirtToPhys
102563 +
102564 + @Description Translates a virtual address to the matching physical address.
102565 +
102566 + @Param[in] addr - The virtual address to translate.
102567 +
102568 + @Return Physical address.
102569 +*//***************************************************************************/
102570 +typedef physAddress_t t_VirtToPhys(void *addr);
102571 +
102572 +/**************************************************************************//**
102573 + @Description Buffer Pool Information Structure.
102574 +*//***************************************************************************/
102575 +typedef struct t_BufferPoolInfo
102576 +{
102577 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
102578 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
102579 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
102580 + uint16_t bufferSize; /**< Buffer size (in bytes) */
102581 +
102582 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
102583 + physical addresses to virtual addresses */
102584 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
102585 + virtual addresses to physical addresses */
102586 +} t_BufferPoolInfo;
102587 +
102588 +
102589 +/**************************************************************************//**
102590 + @Description User callback function called by driver when transmit completed.
102591 +
102592 + User provides this function. Driver invokes it.
102593 +
102594 + @Param[in] h_App - Application's handle, as was provided to the
102595 + driver by the user
102596 + @Param[in] queueId - Transmit queue ID
102597 + @Param[in] p_Data - Pointer to the data buffer
102598 + @Param[in] h_BufContext - The user's private context associated with
102599 + the given data buffer
102600 + @Param[in] status - Transmit status and errors
102601 + @Param[in] flags - Driver-dependent information
102602 + *//***************************************************************************/
102603 +typedef void (t_TxConfFunction)(t_Handle h_App,
102604 + uint32_t queueId,
102605 + uint8_t *p_Data,
102606 + t_Handle h_BufContext,
102607 + uint16_t status,
102608 + uint32_t flags);
102609 +
102610 +/**************************************************************************//**
102611 + @Description User callback function called by driver with receive data.
102612 +
102613 + User provides this function. Driver invokes it.
102614 +
102615 + @Param[in] h_App - Application's handle, as was provided to the
102616 + driver by the user
102617 + @Param[in] queueId - Receive queue ID
102618 + @Param[in] p_Data - Pointer to the buffer with received data
102619 + @Param[in] h_BufContext - The user's private context associated with
102620 + the given data buffer
102621 + @Param[in] length - Length of received data
102622 + @Param[in] status - Receive status and errors
102623 + @Param[in] position - Position of buffer in frame
102624 + @Param[in] flags - Driver-dependent information
102625 +
102626 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
102627 + operation for all ready data.
102628 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
102629 + *//***************************************************************************/
102630 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
102631 + uint32_t queueId,
102632 + uint8_t *p_Data,
102633 + t_Handle h_BufContext,
102634 + uint32_t length,
102635 + uint16_t status,
102636 + uint8_t position,
102637 + uint32_t flags);
102638 +
102639 +
102640 +#endif /* __NCSW_EXT_H */
102641 --- /dev/null
102642 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
102643 @@ -0,0 +1,430 @@
102644 +/*
102645 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102646 + *
102647 + * Redistribution and use in source and binary forms, with or without
102648 + * modification, are permitted provided that the following conditions are met:
102649 + * * Redistributions of source code must retain the above copyright
102650 + * notice, this list of conditions and the following disclaimer.
102651 + * * Redistributions in binary form must reproduce the above copyright
102652 + * notice, this list of conditions and the following disclaimer in the
102653 + * documentation and/or other materials provided with the distribution.
102654 + * * Neither the name of Freescale Semiconductor nor the
102655 + * names of its contributors may be used to endorse or promote products
102656 + * derived from this software without specific prior written permission.
102657 + *
102658 + *
102659 + * ALTERNATIVELY, this software may be distributed under the terms of the
102660 + * GNU General Public License ("GPL") as published by the Free Software
102661 + * Foundation, either version 2 of that License or (at your option) any
102662 + * later version.
102663 + *
102664 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102665 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102666 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102667 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102668 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102669 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102670 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102671 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102672 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102673 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102674 + */
102675 +
102676 +
102677 +/**************************************************************************//**
102678 + @File net_ext.h
102679 +
102680 + @Description This file contains common and general netcomm headers definitions.
102681 +*//***************************************************************************/
102682 +#ifndef __NET_EXT_H
102683 +#define __NET_EXT_H
102684 +
102685 +#include "std_ext.h"
102686 +
102687 +
102688 +typedef uint8_t headerFieldPpp_t;
102689 +
102690 +#define NET_HEADER_FIELD_PPP_PID (1)
102691 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
102692 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
102693 +
102694 +
102695 +typedef uint8_t headerFieldPppoe_t;
102696 +
102697 +#define NET_HEADER_FIELD_PPPoE_VER (1)
102698 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
102699 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
102700 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
102701 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
102702 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
102703 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
102704 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
102705 +
102706 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
102707 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
102708 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
102709 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
102710 +
102711 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
102712 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
102713 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
102714 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
102715 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
102716 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
102717 +
102718 +
102719 +typedef uint8_t headerFieldEth_t;
102720 +
102721 +#define NET_HEADER_FIELD_ETH_DA (1)
102722 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
102723 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
102724 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
102725 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
102726 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
102727 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
102728 +
102729 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
102730 +
102731 +typedef uint16_t headerFieldIp_t;
102732 +
102733 +#define NET_HEADER_FIELD_IP_VER (1)
102734 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
102735 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
102736 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
102737 +
102738 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
102739 +
102740 +typedef uint16_t headerFieldIpv4_t;
102741 +
102742 +#define NET_HEADER_FIELD_IPv4_VER (1)
102743 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
102744 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
102745 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
102746 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
102747 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
102748 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
102749 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
102750 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
102751 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
102752 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
102753 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
102754 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
102755 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
102756 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
102757 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
102758 +
102759 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
102760 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
102761 +
102762 +
102763 +typedef uint8_t headerFieldIpv6_t;
102764 +
102765 +#define NET_HEADER_FIELD_IPv6_VER (1)
102766 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
102767 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
102768 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
102769 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
102770 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
102771 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
102772 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
102773 +
102774 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
102775 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
102776 +
102777 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
102778 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
102779 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
102780 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
102781 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
102782 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
102783 +
102784 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
102785 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
102786 +
102787 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
102788 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
102789 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
102790 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
102791 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
102792 +
102793 +
102794 +typedef uint16_t headerFieldTcp_t;
102795 +
102796 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
102797 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
102798 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
102799 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
102800 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
102801 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
102802 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
102803 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
102804 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
102805 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
102806 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
102807 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
102808 +
102809 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
102810 +
102811 +
102812 +typedef uint8_t headerFieldSctp_t;
102813 +
102814 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
102815 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
102816 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
102817 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
102818 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
102819 +
102820 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
102821 +
102822 +typedef uint8_t headerFieldDccp_t;
102823 +
102824 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
102825 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
102826 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
102827 +
102828 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
102829 +
102830 +
102831 +typedef uint8_t headerFieldUdp_t;
102832 +
102833 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
102834 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
102835 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
102836 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
102837 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
102838 +
102839 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
102840 +
102841 +typedef uint8_t headerFieldUdpLite_t;
102842 +
102843 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
102844 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
102845 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
102846 +
102847 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
102848 +
102849 +typedef uint8_t headerFieldUdpEncapEsp_t;
102850 +
102851 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
102852 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
102853 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
102854 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
102855 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
102856 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
102857 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
102858 +
102859 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
102860 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
102861 +
102862 +#define NET_HEADER_FIELD_IPHC_CID (1)
102863 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
102864 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
102865 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
102866 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
102867 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
102868 +
102869 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
102870 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
102871 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
102872 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
102873 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
102874 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
102875 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
102876 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
102877 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
102878 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
102879 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
102880 +
102881 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
102882 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
102883 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
102884 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
102885 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
102886 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
102887 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
102888 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
102889 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
102890 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
102891 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
102892 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
102893 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
102894 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
102895 +
102896 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
102897 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
102898 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
102899 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
102900 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
102901 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
102902 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
102903 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
102904 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
102905 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
102906 +
102907 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
102908 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
102909 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
102910 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
102911 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
102912 +
102913 +
102914 +typedef uint8_t headerFieldVlan_t;
102915 +
102916 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
102917 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
102918 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
102919 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
102920 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
102921 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
102922 +
102923 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
102924 + NET_HEADER_FIELD_VLAN_CFI | \
102925 + NET_HEADER_FIELD_VLAN_VID)
102926 +
102927 +
102928 +typedef uint8_t headerFieldLlc_t;
102929 +
102930 +#define NET_HEADER_FIELD_LLC_DSAP (1)
102931 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
102932 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
102933 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
102934 +
102935 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
102936 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
102937 +
102938 +
102939 +typedef uint8_t headerFieldSnap_t;
102940 +
102941 +#define NET_HEADER_FIELD_SNAP_OUI (1)
102942 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
102943 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
102944 +
102945 +
102946 +typedef uint8_t headerFieldLlcSnap_t;
102947 +
102948 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
102949 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
102950 +
102951 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
102952 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
102953 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
102954 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
102955 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
102956 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
102957 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
102958 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
102959 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
102960 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
102961 +
102962 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
102963 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
102964 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
102965 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
102966 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
102967 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
102968 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
102969 +
102970 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
102971 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
102972 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
102973 +
102974 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
102975 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
102976 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
102977 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
102978 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
102979 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
102980 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
102981 +
102982 +
102983 +typedef uint8_t headerFieldGre_t;
102984 +
102985 +#define NET_HEADER_FIELD_GRE_TYPE (1)
102986 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
102987 +
102988 +
102989 +typedef uint8_t headerFieldMinencap_t;
102990 +
102991 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
102992 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
102993 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
102994 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
102995 +
102996 +
102997 +typedef uint8_t headerFieldIpsecAh_t;
102998 +
102999 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
103000 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
103001 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
103002 +
103003 +
103004 +typedef uint8_t headerFieldIpsecEsp_t;
103005 +
103006 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
103007 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
103008 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
103009 +
103010 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
103011 +
103012 +
103013 +typedef uint8_t headerFieldMpls_t;
103014 +
103015 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
103016 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
103017 +
103018 +
103019 +typedef uint8_t headerFieldMacsec_t;
103020 +
103021 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
103022 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
103023 +
103024 +
103025 +typedef enum {
103026 + HEADER_TYPE_NONE = 0,
103027 + HEADER_TYPE_PAYLOAD,
103028 + HEADER_TYPE_ETH,
103029 + HEADER_TYPE_VLAN,
103030 + HEADER_TYPE_IPv4,
103031 + HEADER_TYPE_IPv6,
103032 + HEADER_TYPE_IP,
103033 + HEADER_TYPE_TCP,
103034 + HEADER_TYPE_UDP,
103035 + HEADER_TYPE_UDP_LITE,
103036 + HEADER_TYPE_IPHC,
103037 + HEADER_TYPE_SCTP,
103038 + HEADER_TYPE_SCTP_CHUNK_DATA,
103039 + HEADER_TYPE_PPPoE,
103040 + HEADER_TYPE_PPP,
103041 + HEADER_TYPE_PPPMUX,
103042 + HEADER_TYPE_PPPMUX_SUBFRAME,
103043 + HEADER_TYPE_L2TPv2,
103044 + HEADER_TYPE_L2TPv3_CTRL,
103045 + HEADER_TYPE_L2TPv3_SESS,
103046 + HEADER_TYPE_LLC,
103047 + HEADER_TYPE_LLC_SNAP,
103048 + HEADER_TYPE_NLPID,
103049 + HEADER_TYPE_SNAP,
103050 + HEADER_TYPE_MPLS,
103051 + HEADER_TYPE_IPSEC_AH,
103052 + HEADER_TYPE_IPSEC_ESP,
103053 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
103054 + HEADER_TYPE_MACSEC,
103055 + HEADER_TYPE_GRE,
103056 + HEADER_TYPE_MINENCAP,
103057 + HEADER_TYPE_DCCP,
103058 + HEADER_TYPE_ICMP,
103059 + HEADER_TYPE_IGMP,
103060 + HEADER_TYPE_ARP,
103061 + HEADER_TYPE_CAPWAP,
103062 + HEADER_TYPE_CAPWAP_DTLS,
103063 + HEADER_TYPE_RFC2684,
103064 + HEADER_TYPE_USER_DEFINED_L2,
103065 + HEADER_TYPE_USER_DEFINED_L3,
103066 + HEADER_TYPE_USER_DEFINED_L4,
103067 + HEADER_TYPE_USER_DEFINED_SHIM1,
103068 + HEADER_TYPE_USER_DEFINED_SHIM2,
103069 + MAX_HEADER_TYPE_COUNT
103070 +} e_NetHeaderType;
103071 +
103072 +
103073 +#endif /* __NET_EXT_H */
103074 --- /dev/null
103075 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
103076 @@ -0,0 +1,48 @@
103077 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
103078 + * All rights reserved.
103079 + *
103080 + * Redistribution and use in source and binary forms, with or without
103081 + * modification, are permitted provided that the following conditions are met:
103082 + * * Redistributions of source code must retain the above copyright
103083 + * notice, this list of conditions and the following disclaimer.
103084 + * * Redistributions in binary form must reproduce the above copyright
103085 + * notice, this list of conditions and the following disclaimer in the
103086 + * documentation and/or other materials provided with the distribution.
103087 + * * Neither the name of Freescale Semiconductor nor the
103088 + * names of its contributors may be used to endorse or promote products
103089 + * derived from this software without specific prior written permission.
103090 + *
103091 + *
103092 + * ALTERNATIVELY, this software may be distributed under the terms of the
103093 + * GNU General Public License ("GPL") as published by the Free Software
103094 + * Foundation, either version 2 of that License or (at your option) any
103095 + * later version.
103096 + *
103097 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103098 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103099 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103100 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103101 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103102 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103103 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103104 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103105 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103106 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103107 + */
103108 +
103109 +
103110 +/**************************************************************************//**
103111 + @File std_ext.h
103112 +
103113 + @Description General Standard Definitions
103114 +*//***************************************************************************/
103115 +
103116 +#ifndef __STD_EXT_H
103117 +#define __STD_EXT_H
103118 +
103119 +
103120 +#include "types_ext.h"
103121 +#include "ncsw_ext.h"
103122 +
103123 +
103124 +#endif /* __STD_EXT_H */
103125 --- /dev/null
103126 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
103127 @@ -0,0 +1,49 @@
103128 +/*
103129 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103130 + *
103131 + * Redistribution and use in source and binary forms, with or without
103132 + * modification, are permitted provided that the following conditions are met:
103133 + * * Redistributions of source code must retain the above copyright
103134 + * notice, this list of conditions and the following disclaimer.
103135 + * * Redistributions in binary form must reproduce the above copyright
103136 + * notice, this list of conditions and the following disclaimer in the
103137 + * documentation and/or other materials provided with the distribution.
103138 + * * Neither the name of Freescale Semiconductor nor the
103139 + * names of its contributors may be used to endorse or promote products
103140 + * derived from this software without specific prior written permission.
103141 + *
103142 + *
103143 + * ALTERNATIVELY, this software may be distributed under the terms of the
103144 + * GNU General Public License ("GPL") as published by the Free Software
103145 + * Foundation, either version 2 of that License or (at your option) any
103146 + * later version.
103147 + *
103148 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103149 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103150 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103151 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103152 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103153 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103154 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103155 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103156 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103157 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103158 + */
103159 +
103160 +
103161 +#ifndef __STDARG_EXT_H
103162 +#define __STDARG_EXT_H
103163 +
103164 +
103165 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
103166 +#include <stdarg.h>
103167 +
103168 +#else
103169 +#include <stdarg.h>
103170 +
103171 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
103172 +
103173 +#include "std_ext.h"
103174 +
103175 +
103176 +#endif /* __STDARG_EXT_H */
103177 --- /dev/null
103178 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
103179 @@ -0,0 +1,162 @@
103180 +/*
103181 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103182 + *
103183 + * Redistribution and use in source and binary forms, with or without
103184 + * modification, are permitted provided that the following conditions are met:
103185 + * * Redistributions of source code must retain the above copyright
103186 + * notice, this list of conditions and the following disclaimer.
103187 + * * Redistributions in binary form must reproduce the above copyright
103188 + * notice, this list of conditions and the following disclaimer in the
103189 + * documentation and/or other materials provided with the distribution.
103190 + * * Neither the name of Freescale Semiconductor nor the
103191 + * names of its contributors may be used to endorse or promote products
103192 + * derived from this software without specific prior written permission.
103193 + *
103194 + *
103195 + * ALTERNATIVELY, this software may be distributed under the terms of the
103196 + * GNU General Public License ("GPL") as published by the Free Software
103197 + * Foundation, either version 2 of that License or (at your option) any
103198 + * later version.
103199 + *
103200 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103201 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103202 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103203 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103204 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103205 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103206 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103207 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103208 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103209 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103210 + */
103211 +
103212 +
103213 +
103214 +#ifndef __STDLIB_EXT_H
103215 +#define __STDLIB_EXT_H
103216 +
103217 +
103218 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
103219 +#include "stdarg_ext.h"
103220 +#include "std_ext.h"
103221 +
103222 +
103223 +/**
103224 + * strtoul - convert a string to an uint32_t
103225 + * @cp: The start of the string
103226 + * @endp: A pointer to the end of the parsed string will be placed here
103227 + * @base: The number base to use
103228 + */
103229 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
103230 +
103231 +/**
103232 + * strtol - convert a string to a int32_t
103233 + * @cp: The start of the string
103234 + * @endp: A pointer to the end of the parsed string will be placed here
103235 + * @base: The number base to use
103236 + */
103237 +long strtol(const char *cp,char **endp,uint32_t base);
103238 +
103239 +/**
103240 + * strtoull - convert a string to an uint64_t
103241 + * @cp: The start of the string
103242 + * @endp: A pointer to the end of the parsed string will be placed here
103243 + * @base: The number base to use
103244 + */
103245 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
103246 +
103247 +/**
103248 + * strtoll - convert a string to a int64 long
103249 + * @cp: The start of the string
103250 + * @endp: A pointer to the end of the parsed string will be placed here
103251 + * @base: The number base to use
103252 + */
103253 +long long strtoll(const char *cp,char **endp,uint32_t base);
103254 +
103255 +/**
103256 + * atoi - convert a character to a int
103257 + * @s: The start of the string
103258 + */
103259 +int atoi(const char *s);
103260 +
103261 +/**
103262 + * strnlen - Find the length of a length-limited string
103263 + * @s: The string to be sized
103264 + * @count: The maximum number of bytes to search
103265 + */
103266 +size_t strnlen(const char * s, size_t count);
103267 +
103268 +/**
103269 + * strlen - Find the length of a string
103270 + * @s: The string to be sized
103271 + */
103272 +size_t strlen(const char * s);
103273 +
103274 +/**
103275 + * strtok - Split a string into tokens
103276 + * @s: The string to be searched
103277 + * @ct: The characters to search for
103278 + *
103279 + * WARNING: strtok is deprecated, use strsep instead.
103280 + */
103281 +char * strtok(char * s,const char * ct);
103282 +
103283 +/**
103284 + * strncpy - Copy a length-limited, %NUL-terminated string
103285 + * @dest: Where to copy the string to
103286 + * @src: Where to copy the string from
103287 + * @count: The maximum number of bytes to copy
103288 + *
103289 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
103290 + * However, the result is not %NUL-terminated if the source exceeds
103291 + * @count bytes.
103292 + */
103293 +char * strncpy(char * dest,const char *src,size_t count);
103294 +
103295 +/**
103296 + * strcpy - Copy a %NUL terminated string
103297 + * @dest: Where to copy the string to
103298 + * @src: Where to copy the string from
103299 + */
103300 +char * strcpy(char * dest,const char *src);
103301 +
103302 +/**
103303 + * vsscanf - Unformat a buffer into a list of arguments
103304 + * @buf: input buffer
103305 + * @fmt: format of buffer
103306 + * @args: arguments
103307 + */
103308 +int vsscanf(const char * buf, const char * fmt, va_list args);
103309 +
103310 +/**
103311 + * vsnprintf - Format a string and place it in a buffer
103312 + * @buf: The buffer to place the result into
103313 + * @size: The size of the buffer, including the trailing null space
103314 + * @fmt: The format string to use
103315 + * @args: Arguments for the format string
103316 + *
103317 + * Call this function if you are already dealing with a va_list.
103318 + * You probably want snprintf instead.
103319 + */
103320 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
103321 +
103322 +/**
103323 + * vsprintf - Format a string and place it in a buffer
103324 + * @buf: The buffer to place the result into
103325 + * @fmt: The format string to use
103326 + * @args: Arguments for the format string
103327 + *
103328 + * Call this function if you are already dealing with a va_list.
103329 + * You probably want sprintf instead.
103330 + */
103331 +int vsprintf(char *buf, const char *fmt, va_list args);
103332 +
103333 +#else
103334 +#include <stdlib.h>
103335 +#include <stdio.h>
103336 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
103337 +
103338 +#include "std_ext.h"
103339 +
103340 +
103341 +#endif /* __STDLIB_EXT_H */
103342 --- /dev/null
103343 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
103344 @@ -0,0 +1,56 @@
103345 +/*
103346 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103347 + *
103348 + * Redistribution and use in source and binary forms, with or without
103349 + * modification, are permitted provided that the following conditions are met:
103350 + * * Redistributions of source code must retain the above copyright
103351 + * notice, this list of conditions and the following disclaimer.
103352 + * * Redistributions in binary form must reproduce the above copyright
103353 + * notice, this list of conditions and the following disclaimer in the
103354 + * documentation and/or other materials provided with the distribution.
103355 + * * Neither the name of Freescale Semiconductor nor the
103356 + * names of its contributors may be used to endorse or promote products
103357 + * derived from this software without specific prior written permission.
103358 + *
103359 + *
103360 + * ALTERNATIVELY, this software may be distributed under the terms of the
103361 + * GNU General Public License ("GPL") as published by the Free Software
103362 + * Foundation, either version 2 of that License or (at your option) any
103363 + * later version.
103364 + *
103365 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103366 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103367 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103368 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103369 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103370 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103371 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103372 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103373 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103374 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103375 + */
103376 +
103377 +
103378 +#ifndef __STRING_EXT_H
103379 +#define __STRING_EXT_H
103380 +
103381 +
103382 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
103383 +#include <linux/kernel.h>
103384 +#include <linux/string.h>
103385 +extern char * strtok ( char * str, const char * delimiters );
103386 +
103387 +#elif defined(__KERNEL__)
103388 +#include "linux/types.h"
103389 +#include "linux/posix_types.h"
103390 +#include "linux/string.h"
103391 +
103392 +#else
103393 +#include <string.h>
103394 +
103395 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
103396 +
103397 +#include "std_ext.h"
103398 +
103399 +
103400 +#endif /* __STRING_EXT_H */
103401 --- /dev/null
103402 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
103403 @@ -0,0 +1,62 @@
103404 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
103405 + * All rights reserved.
103406 + *
103407 + * Redistribution and use in source and binary forms, with or without
103408 + * modification, are permitted provided that the following conditions are met:
103409 + * * Redistributions of source code must retain the above copyright
103410 + * notice, this list of conditions and the following disclaimer.
103411 + * * Redistributions in binary form must reproduce the above copyright
103412 + * notice, this list of conditions and the following disclaimer in the
103413 + * documentation and/or other materials provided with the distribution.
103414 + * * Neither the name of Freescale Semiconductor nor the
103415 + * names of its contributors may be used to endorse or promote products
103416 + * derived from this software without specific prior written permission.
103417 + *
103418 + *
103419 + * ALTERNATIVELY, this software may be distributed under the terms of the
103420 + * GNU General Public License ("GPL") as published by the Free Software
103421 + * Foundation, either version 2 of that License or (at your option) any
103422 + * later version.
103423 + *
103424 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103425 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103426 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103427 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103428 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103429 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103430 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103431 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103432 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103433 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103434 + */
103435 +
103436 +
103437 +/**************************************************************************//**
103438 + @File types_ext.h
103439 +
103440 + @Description General types Standard Definitions
103441 +*//***************************************************************************/
103442 +
103443 +#ifndef __TYPES_EXT_H
103444 +#define __TYPES_EXT_H
103445 +
103446 +#if defined(NCSW_LINUX)
103447 +#include "types_linux.h"
103448 +
103449 +#elif defined(NCSW_VXWORKS)
103450 +#include "types_vxworks.h"
103451 +
103452 +#elif defined(__GNUC__) && defined(__cplusplus)
103453 +#include "types_bb_gpp.h"
103454 +
103455 +#elif defined(__GNUC__)
103456 +#include "types_bb_gcc.h"
103457 +
103458 +#elif defined(__ghs__)
103459 +#include "types_ghs.h"
103460 +
103461 +#else
103462 +#include "types_dflt.h"
103463 +#endif /* defined (__ROCOO__) */
103464 +
103465 +#endif /* __TYPES_EXT_H */
103466 --- /dev/null
103467 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
103468 @@ -0,0 +1,56 @@
103469 +/*
103470 + * Copyright 2012 Freescale Semiconductor Inc.
103471 + *
103472 + * Redistribution and use in source and binary forms, with or without
103473 + * modification, are permitted provided that the following conditions are met:
103474 + * * Redistributions of source code must retain the above copyright
103475 + * notice, this list of conditions and the following disclaimer.
103476 + * * Redistributions in binary form must reproduce the above copyright
103477 + * notice, this list of conditions and the following disclaimer in the
103478 + * documentation and/or other materials provided with the distribution.
103479 + * * Neither the name of Freescale Semiconductor nor the
103480 + * names of its contributors may be used to endorse or promote products
103481 + * derived from this software without specific prior written permission.
103482 + *
103483 + *
103484 + * ALTERNATIVELY, this software may be distributed under the terms of the
103485 + * GNU General Public License ("GPL") as published by the Free Software
103486 + * Foundation, either version 2 of that License or (at your option) any
103487 + * later version.
103488 + *
103489 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103490 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103491 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103492 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103493 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103494 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103495 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103496 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103497 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103498 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103499 + */
103500 +
103501 +
103502 +/**************************************************************************//**
103503 + @File debug_ext.h
103504 +
103505 + @Description Debug mode definitions.
103506 +*//***************************************************************************/
103507 +
103508 +#ifndef __XX_COMMON_H
103509 +#define __XX_COMMON_H
103510 +
103511 +/*****************************************************************************
103512 + * UNIFIED MODULE CODES
103513 + *****************************************************************************/
103514 +#define MODULE_UNKNOWN 0x00000000
103515 +#define MODULE_FM 0x00010000
103516 +#define MODULE_FM_MURAM 0x00020000
103517 +#define MODULE_FM_PCD 0x00030000
103518 +#define MODULE_FM_RTC 0x00040000
103519 +#define MODULE_FM_MAC 0x00050000
103520 +#define MODULE_FM_PORT 0x00060000
103521 +#define MODULE_MM 0x00070000
103522 +#define MODULE_FM_SP 0x00080000
103523 +#define MODULE_FM_MACSEC 0x00090000
103524 +#endif /* __XX_COMMON_H */
103525 --- /dev/null
103526 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
103527 @@ -0,0 +1,791 @@
103528 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
103529 + * All rights reserved.
103530 + *
103531 + * Redistribution and use in source and binary forms, with or without
103532 + * modification, are permitted provided that the following conditions are met:
103533 + * * Redistributions of source code must retain the above copyright
103534 + * notice, this list of conditions and the following disclaimer.
103535 + * * Redistributions in binary form must reproduce the above copyright
103536 + * notice, this list of conditions and the following disclaimer in the
103537 + * documentation and/or other materials provided with the distribution.
103538 + * * Neither the name of Freescale Semiconductor nor the
103539 + * names of its contributors may be used to endorse or promote products
103540 + * derived from this software without specific prior written permission.
103541 + *
103542 + *
103543 + * ALTERNATIVELY, this software may be distributed under the terms of the
103544 + * GNU General Public License ("GPL") as published by the Free Software
103545 + * Foundation, either version 2 of that License or (at your option) any
103546 + * later version.
103547 + *
103548 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103549 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103550 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103551 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103552 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103553 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103554 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103555 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103556 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103557 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103558 + */
103559 +
103560 +
103561 +/**************************************************************************//**
103562 + @File xx_ext.h
103563 +
103564 + @Description Prototypes, externals and typedefs for system-supplied
103565 + (external) routines
103566 +*//***************************************************************************/
103567 +
103568 +#ifndef __XX_EXT_H
103569 +#define __XX_EXT_H
103570 +
103571 +#include "std_ext.h"
103572 +#include "xx_common.h"
103573 +#include "part_ext.h"
103574 +
103575 +
103576 +
103577 +/**************************************************************************//**
103578 + @Group xx_id XX Interface (System call hooks)
103579 +
103580 + @Description Prototypes, externals and typedefs for system-supplied
103581 + (external) routines
103582 +
103583 + @{
103584 +*//***************************************************************************/
103585 +
103586 +#ifdef DEBUG_XX_MALLOC
103587 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
103588 +
103589 +void * XX_MallocSmartDebug(uint32_t size,
103590 + int memPartitionId,
103591 + uint32_t alignment,
103592 + char *fname,
103593 + int line);
103594 +
103595 +#define XX_Malloc(sz) \
103596 + XX_MallocDebug((sz), __FILE__, __LINE__)
103597 +
103598 +#define XX_MallocSmart(sz, memt, al) \
103599 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
103600 +
103601 +#else /* not DEBUG_XX_MALLOC */
103602 +/**************************************************************************//**
103603 + @Function XX_Malloc
103604 +
103605 + @Description allocates contiguous block of memory.
103606 +
103607 + @Param[in] size - Number of bytes to allocate.
103608 +
103609 + @Return The address of the newly allocated block on success, NULL on failure.
103610 +*//***************************************************************************/
103611 +void * XX_Malloc(uint32_t size);
103612 +
103613 +/**************************************************************************//**
103614 + @Function XX_MallocSmart
103615 +
103616 + @Description Allocates contiguous block of memory in a specified
103617 + alignment and from the specified segment.
103618 +
103619 + @Param[in] size - Number of bytes to allocate.
103620 + @Param[in] memPartitionId - Memory partition ID; The value zero must
103621 + be mapped to the default heap partition.
103622 + @Param[in] alignment - Required memory alignment (in bytes).
103623 +
103624 + @Return The address of the newly allocated block on success, NULL on failure.
103625 +*//***************************************************************************/
103626 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
103627 +#endif /* not DEBUG_XX_MALLOC */
103628 +
103629 +/**************************************************************************//**
103630 + @Function XX_FreeSmart
103631 +
103632 + @Description Frees the memory block pointed to by "p".
103633 + Only for memory allocated by XX_MallocSmart
103634 +
103635 + @Param[in] p_Memory - pointer to the memory block.
103636 +
103637 + @Return None.
103638 +*//***************************************************************************/
103639 +void XX_FreeSmart(void *p_Memory);
103640 +
103641 +/**************************************************************************//**
103642 + @Function XX_Free
103643 +
103644 + @Description frees the memory block pointed to by "p".
103645 +
103646 + @Param[in] p_Memory - pointer to the memory block.
103647 +
103648 + @Return None.
103649 +*//***************************************************************************/
103650 +void XX_Free(void *p_Memory);
103651 +
103652 +/**************************************************************************//**
103653 + @Function XX_Print
103654 +
103655 + @Description print a string.
103656 +
103657 + @Param[in] str - string to print.
103658 +
103659 + @Return None.
103660 +*//***************************************************************************/
103661 +void XX_Print(char *str, ...);
103662 +
103663 +/**************************************************************************//**
103664 + @Function XX_SetIntr
103665 +
103666 + @Description Set an interrupt service routine for a specific interrupt source.
103667 +
103668 + @Param[in] irq - Interrupt ID (system-specific number).
103669 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
103670 + @Param[in] handle - The argument for the user callback routine.
103671 +
103672 + @Return E_OK on success; error code otherwise..
103673 +*//***************************************************************************/
103674 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
103675 +
103676 +/**************************************************************************//**
103677 + @Function XX_FreeIntr
103678 +
103679 + @Description Free a specific interrupt and a specific callback routine.
103680 +
103681 + @Param[in] irq - Interrupt ID (system-specific number).
103682 +
103683 + @Return E_OK on success; error code otherwise..
103684 +*//***************************************************************************/
103685 +t_Error XX_FreeIntr(int irq);
103686 +
103687 +/**************************************************************************//**
103688 + @Function XX_EnableIntr
103689 +
103690 + @Description Enable a specific interrupt.
103691 +
103692 + @Param[in] irq - Interrupt ID (system-specific number).
103693 +
103694 + @Return E_OK on success; error code otherwise..
103695 +*//***************************************************************************/
103696 +t_Error XX_EnableIntr(int irq);
103697 +
103698 +/**************************************************************************//**
103699 + @Function XX_DisableIntr
103700 +
103701 + @Description Disable a specific interrupt.
103702 +
103703 + @Param[in] irq - Interrupt ID (system-specific number).
103704 +
103705 + @Return E_OK on success; error code otherwise..
103706 +*//***************************************************************************/
103707 +t_Error XX_DisableIntr(int irq);
103708 +
103709 +/**************************************************************************//**
103710 + @Function XX_DisableAllIntr
103711 +
103712 + @Description Disable all interrupts by masking them at the CPU.
103713 +
103714 + @Return A value that represents the interrupts state before the
103715 + operation, and should be passed to the matching
103716 + XX_RestoreAllIntr() call.
103717 +*//***************************************************************************/
103718 +uint32_t XX_DisableAllIntr(void);
103719 +
103720 +/**************************************************************************//**
103721 + @Function XX_RestoreAllIntr
103722 +
103723 + @Description Restore previous state of interrupts level at the CPU.
103724 +
103725 + @Param[in] flags - A value that represents the interrupts state to restore,
103726 + as returned by the matching call for XX_DisableAllIntr().
103727 +
103728 + @Return None.
103729 +*//***************************************************************************/
103730 +void XX_RestoreAllIntr(uint32_t flags);
103731 +
103732 +
103733 +/**************************************************************************//**
103734 + @Function XX_Exit
103735 +
103736 + @Description Stop execution and report status (where it is applicable)
103737 +
103738 + @Param[in] status - exit status
103739 +*//***************************************************************************/
103740 +void XX_Exit(int status);
103741 +
103742 +
103743 +/*****************************************************************************/
103744 +/* Tasklet Service Routines */
103745 +/*****************************************************************************/
103746 +typedef t_Handle t_TaskletHandle;
103747 +
103748 +/**************************************************************************//**
103749 + @Function XX_InitTasklet
103750 +
103751 + @Description Create and initialize a tasklet object.
103752 +
103753 + @Param[in] routine - A routine to be ran as a tasklet.
103754 + @Param[in] data - An argument to pass to the tasklet.
103755 +
103756 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
103757 +*//***************************************************************************/
103758 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
103759 +
103760 +/**************************************************************************//**
103761 + @Function XX_FreeTasklet
103762 +
103763 + @Description Free a tasklet object.
103764 +
103765 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
103766 +
103767 + @Return None.
103768 +*//***************************************************************************/
103769 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
103770 +
103771 +/**************************************************************************//**
103772 + @Function XX_ScheduleTask
103773 +
103774 + @Description Schedule a tasklet object.
103775 +
103776 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
103777 + @Param[in] immediate - Indicate whether to schedule this tasklet on
103778 + the immediate queue or on the delayed one.
103779 +
103780 + @Return 0 - on success. Error code - otherwise.
103781 +*//***************************************************************************/
103782 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
103783 +
103784 +/**************************************************************************//**
103785 + @Function XX_FlushScheduledTasks
103786 +
103787 + @Description Flush all tasks there are in the scheduled tasks queue.
103788 +
103789 + @Return None.
103790 +*//***************************************************************************/
103791 +void XX_FlushScheduledTasks(void);
103792 +
103793 +/**************************************************************************//**
103794 + @Function XX_TaskletIsQueued
103795 +
103796 + @Description Check if task is queued.
103797 +
103798 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
103799 +
103800 + @Return 1 - task is queued. 0 - otherwise.
103801 +*//***************************************************************************/
103802 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
103803 +
103804 +/**************************************************************************//**
103805 + @Function XX_SetTaskletData
103806 +
103807 + @Description Set data to a scheduled task. Used to change data of already
103808 + scheduled task.
103809 +
103810 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
103811 + @Param[in] data - Data to be set.
103812 +*//***************************************************************************/
103813 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
103814 +
103815 +/**************************************************************************//**
103816 + @Function XX_GetTaskletData
103817 +
103818 + @Description Get the data of scheduled task.
103819 +
103820 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
103821 +
103822 + @Return handle to the data of the task.
103823 +*//***************************************************************************/
103824 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
103825 +
103826 +/**************************************************************************//**
103827 + @Function XX_BottomHalf
103828 +
103829 + @Description Bottom half implementation, invoked by the interrupt handler.
103830 +
103831 + This routine handles all bottom-half tasklets with interrupts
103832 + enabled.
103833 +
103834 + @Return None.
103835 +*//***************************************************************************/
103836 +void XX_BottomHalf(void);
103837 +
103838 +
103839 +/*****************************************************************************/
103840 +/* Spinlock Service Routines */
103841 +/*****************************************************************************/
103842 +
103843 +/**************************************************************************//**
103844 + @Function XX_InitSpinlock
103845 +
103846 + @Description Creates a spinlock.
103847 +
103848 + @Return Spinlock handle is returned on success; NULL otherwise.
103849 +*//***************************************************************************/
103850 +t_Handle XX_InitSpinlock(void);
103851 +
103852 +/**************************************************************************//**
103853 + @Function XX_FreeSpinlock
103854 +
103855 + @Description Frees the memory allocated for the spinlock creation.
103856 +
103857 + @Param[in] h_Spinlock - A handle to a spinlock.
103858 +
103859 + @Return None.
103860 +*//***************************************************************************/
103861 +void XX_FreeSpinlock(t_Handle h_Spinlock);
103862 +
103863 +/**************************************************************************//**
103864 + @Function XX_LockSpinlock
103865 +
103866 + @Description Locks a spinlock.
103867 +
103868 + @Param[in] h_Spinlock - A handle to a spinlock.
103869 +
103870 + @Return None.
103871 +*//***************************************************************************/
103872 +void XX_LockSpinlock(t_Handle h_Spinlock);
103873 +
103874 +/**************************************************************************//**
103875 + @Function XX_UnlockSpinlock
103876 +
103877 + @Description Unlocks a spinlock.
103878 +
103879 + @Param[in] h_Spinlock - A handle to a spinlock.
103880 +
103881 + @Return None.
103882 +*//***************************************************************************/
103883 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
103884 +
103885 +/**************************************************************************//**
103886 + @Function XX_LockIntrSpinlock
103887 +
103888 + @Description Locks a spinlock (interrupt safe).
103889 +
103890 + @Param[in] h_Spinlock - A handle to a spinlock.
103891 +
103892 + @Return A value that represents the interrupts state before the
103893 + operation, and should be passed to the matching
103894 + XX_UnlockIntrSpinlock() call.
103895 +*//***************************************************************************/
103896 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
103897 +
103898 +/**************************************************************************//**
103899 + @Function XX_UnlockIntrSpinlock
103900 +
103901 + @Description Unlocks a spinlock (interrupt safe).
103902 +
103903 + @Param[in] h_Spinlock - A handle to a spinlock.
103904 + @Param[in] intrFlags - A value that represents the interrupts state to
103905 + restore, as returned by the matching call for
103906 + XX_LockIntrSpinlock().
103907 +
103908 + @Return None.
103909 +*//***************************************************************************/
103910 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
103911 +
103912 +
103913 +/*****************************************************************************/
103914 +/* Timers Service Routines */
103915 +/*****************************************************************************/
103916 +
103917 +/**************************************************************************//**
103918 + @Function XX_CurrentTime
103919 +
103920 + @Description Returns current system time.
103921 +
103922 + @Return Current system time (in milliseconds).
103923 +*//***************************************************************************/
103924 +uint32_t XX_CurrentTime(void);
103925 +
103926 +/**************************************************************************//**
103927 + @Function XX_CreateTimer
103928 +
103929 + @Description Creates a timer.
103930 +
103931 + @Return Timer handle is returned on success; NULL otherwise.
103932 +*//***************************************************************************/
103933 +t_Handle XX_CreateTimer(void);
103934 +
103935 +/**************************************************************************//**
103936 + @Function XX_FreeTimer
103937 +
103938 + @Description Frees the memory allocated for the timer creation.
103939 +
103940 + @Param[in] h_Timer - A handle to a timer.
103941 +
103942 + @Return None.
103943 +*//***************************************************************************/
103944 +void XX_FreeTimer(t_Handle h_Timer);
103945 +
103946 +/**************************************************************************//**
103947 + @Function XX_StartTimer
103948 +
103949 + @Description Starts a timer.
103950 +
103951 + The user can select to start the timer as periodic timer or as
103952 + one-shot timer. The user should provide a callback routine that
103953 + will be called when the timer expires.
103954 +
103955 + @Param[in] h_Timer - A handle to a timer.
103956 + @Param[in] msecs - Timer expiration period (in milliseconds).
103957 + @Param[in] periodic - TRUE for a periodic timer;
103958 + FALSE for a one-shot timer..
103959 + @Param[in] f_TimerExpired - A callback routine to be called when the
103960 + timer expires.
103961 + @Param[in] h_Arg - The argument to pass in the timer-expired
103962 + callback routine.
103963 +
103964 + @Return None.
103965 +*//***************************************************************************/
103966 +void XX_StartTimer(t_Handle h_Timer,
103967 + uint32_t msecs,
103968 + bool periodic,
103969 + void (*f_TimerExpired)(t_Handle h_Arg),
103970 + t_Handle h_Arg);
103971 +
103972 +/**************************************************************************//**
103973 + @Function XX_StopTimer
103974 +
103975 + @Description Frees the memory allocated for the timer creation.
103976 +
103977 + @Param[in] h_Timer - A handle to a timer.
103978 +
103979 + @Return None.
103980 +*//***************************************************************************/
103981 +void XX_StopTimer(t_Handle h_Timer);
103982 +
103983 +/**************************************************************************//**
103984 + @Function XX_ModTimer
103985 +
103986 + @Description Updates the expiration time of a timer.
103987 +
103988 + This routine adds the given time to the current system time,
103989 + and sets this value as the new expiration time of the timer.
103990 +
103991 + @Param[in] h_Timer - A handle to a timer.
103992 + @Param[in] msecs - The new interval until timer expiration
103993 + (in milliseconds).
103994 +
103995 + @Return None.
103996 +*//***************************************************************************/
103997 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
103998 +
103999 +/**************************************************************************//**
104000 + @Function XX_Sleep
104001 +
104002 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
104003 +
104004 + @Param[in] msecs - The requested sleep time (in milliseconds).
104005 +
104006 + @Return Zero if the requested time has elapsed; Otherwise, the value
104007 + returned will be the unslept amount) in milliseconds.
104008 +
104009 + @Cautions This routine enables interrupts during its wait time.
104010 +*//***************************************************************************/
104011 +uint32_t XX_Sleep(uint32_t msecs);
104012 +
104013 +/**************************************************************************//**
104014 + @Function XX_UDelay
104015 +
104016 + @Description Busy-wait until the desired time (in microseconds) has passed.
104017 +
104018 + @Param[in] usecs - The requested delay time (in microseconds).
104019 +
104020 + @Return None.
104021 +
104022 + @Cautions It is highly unrecommended to call this routine during interrupt
104023 + time, because the system time may not be updated properly during
104024 + the delay loop. The behavior of this routine during interrupt
104025 + time is unexpected.
104026 +*//***************************************************************************/
104027 +void XX_UDelay(uint32_t usecs);
104028 +
104029 +
104030 +/*****************************************************************************/
104031 +/* Other Service Routines */
104032 +/*****************************************************************************/
104033 +
104034 +/**************************************************************************//**
104035 + @Function XX_PhysToVirt
104036 +
104037 + @Description Translates a physical address to the matching virtual address.
104038 +
104039 + @Param[in] addr - The physical address to translate.
104040 +
104041 + @Return Virtual address.
104042 +*//***************************************************************************/
104043 +void * XX_PhysToVirt(physAddress_t addr);
104044 +
104045 +/**************************************************************************//**
104046 + @Function XX_VirtToPhys
104047 +
104048 + @Description Translates a virtual address to the matching physical address.
104049 +
104050 + @Param[in] addr - The virtual address to translate.
104051 +
104052 + @Return Physical address.
104053 +*//***************************************************************************/
104054 +physAddress_t XX_VirtToPhys(void *addr);
104055 +
104056 +
104057 +/**************************************************************************//**
104058 + @Group xx_ipc XX Inter-Partition-Communication API
104059 +
104060 + @Description The following API is to be used when working with multiple
104061 + partitions configuration.
104062 +
104063 + @{
104064 +*//***************************************************************************/
104065 +
104066 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
104067 + The IPC service can use this constant to limit
104068 + the storage space for IPC endpoint names. */
104069 +
104070 +
104071 +/**************************************************************************//**
104072 + @Function t_IpcMsgCompletion
104073 +
104074 + @Description Callback function used upon IPC non-blocking transaction completion
104075 + to return message buffer to the caller and to forward reply if available.
104076 +
104077 + This callback function may be attached by the source endpoint to any outgoing
104078 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
104079 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
104080 + the IPC service invokes this callback routine to return the message buffer to the sender
104081 + and to provide the received reply, if requested.
104082 +
104083 + User provides this function. Driver invokes it.
104084 +
104085 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
104086 + in the XX_IpcSendMessage() function; This handle is typically used to point
104087 + to the internal data structure of the source endpoint.
104088 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
104089 + The source endpoint can free (or reuse) this buffer when message
104090 + completion callback is called.
104091 + @Param[in] p_Reply - Pointer to (received) reply buffer;
104092 + This pointer is the same as was provided by the source endpoint in
104093 + XX_IpcSendMessage().
104094 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
104095 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
104096 + timeout.
104097 +
104098 + @Return None
104099 + *//***************************************************************************/
104100 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
104101 + uint8_t *p_Msg,
104102 + uint8_t *p_Reply,
104103 + uint32_t replyLength,
104104 + t_Error status);
104105 +
104106 +/**************************************************************************//**
104107 + @Function t_IpcMsgHandler
104108 +
104109 + @Description Callback function used as IPC message handler.
104110 +
104111 + The IPC service invokes message handlers for each IPC message received.
104112 + The actual function pointer should be registered by each destination endpoint
104113 + via the XX_IpcRegisterMsgHandler() routine.
104114 +
104115 + User provides this function. Driver invokes it.
104116 +
104117 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
104118 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
104119 + typically used to point to the internal data structure of the destination
104120 + endpoint.
104121 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
104122 + @Param[in] msgLength - Length (in bytes) of message data.
104123 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
104124 + by the IPC service;
104125 + The reply buffer is allocated by the IPC service with size equals to the
104126 + replyLength parameter provided in message handler registration (see
104127 + XX_IpcRegisterMsgHandler() function);
104128 + If replyLength was initially specified as zero during message handler registration,
104129 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
104130 + The IPC service is also responsible for freeing the reply buffer after the
104131 + reply has been sent or dismissed.
104132 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
104133 + [In] equals the replyLength parameter provided in message handler
104134 + registration (see XX_IpcRegisterMsgHandler() function), and
104135 + [Out] should be updated by message handler to the actual reply length; if
104136 + this value is set to zero, the IPC service must assume that a reply should
104137 + not be sent;
104138 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
104139 +
104140 + @Return E_OK on success; Error code otherwise.
104141 + *//***************************************************************************/
104142 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
104143 + uint8_t *p_Msg,
104144 + uint32_t msgLength,
104145 + uint8_t *p_Reply,
104146 + uint32_t *p_ReplyLength);
104147 +
104148 +/**************************************************************************//**
104149 + @Function XX_IpcRegisterMsgHandler
104150 +
104151 + @Description IPC mailbox registration.
104152 +
104153 + This function is used for registering an IPC message handler in the IPC service.
104154 + This function is called by each destination endpoint to indicate that it is ready
104155 + to handle incoming messages. The IPC service invokes the message handler upon receiving
104156 + a message addressed to the specified destination endpoint.
104157 +
104158 + @Param[in] addr - The address name string associated with the destination endpoint;
104159 + This address must be unique across the IPC service domain to ensure
104160 + correct message routing.
104161 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
104162 + message; invoked by the IPC service upon receiving a message
104163 + addressed to the destination endpoint specified by the addr
104164 + parameter.
104165 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
104166 + to f_MsgHandler callback function.
104167 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
104168 + may generate; the IPC service provides the message handler with buffer
104169 + for reply according to the length specified here (refer also to the description
104170 + of #t_IpcMsgHandler callback function type);
104171 + This size shall be zero if the message handler never generates replies.
104172 +
104173 + @Return E_OK on success; Error code otherwise.
104174 +*//***************************************************************************/
104175 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
104176 + t_IpcMsgHandler *f_MsgHandler,
104177 + t_Handle h_Module,
104178 + uint32_t replyLength);
104179 +
104180 +/**************************************************************************//**
104181 + @Function XX_IpcUnregisterMsgHandler
104182 +
104183 + @Description Release IPC mailbox routine.
104184 +
104185 + This function is used for unregistering an IPC message handler from the IPC service.
104186 + This function is called by each destination endpoint to indicate that it is no longer
104187 + capable of handling incoming messages.
104188 +
104189 + @Param[in] addr - The address name string associated with the destination endpoint;
104190 + This address is the same as was used when the message handler was
104191 + registered via XX_IpcRegisterMsgHandler().
104192 +
104193 + @Return E_OK on success; Error code otherwise.
104194 +*//***************************************************************************/
104195 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
104196 +
104197 +/**************************************************************************//**
104198 + @Function XX_IpcInitSession
104199 +
104200 + @Description This function is used for creating an IPC session between the source endpoint
104201 + and the destination endpoint.
104202 +
104203 + The actual implementation and representation of a session is left for the IPC service.
104204 + The function returns an abstract handle to the created session. This handle shall be used
104205 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
104206 + The IPC service assumes that before this function is called, no messages are sent from
104207 + the specified source endpoint to the specified destination endpoint.
104208 +
104209 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
104210 + as described below.
104211 +
104212 + @par Connection-Oriented Approach
104213 +
104214 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
104215 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
104216 + and a destination-to-source channel for replies. The returned handle should represent the internal
104217 + representation of these channels.
104218 +
104219 + @par Connectionless Approach
104220 +
104221 + The IPC service may implement a session in a connectionless approach - when this function is called, the
104222 + IPC service should not perform any particular steps, but it must store the pair of source and destination
104223 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
104224 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
104225 + through the connectionless medium.
104226 +
104227 + @Param[in] destAddr - The address name string associated with the destination endpoint.
104228 + @Param[in] srcAddr - The address name string associated with the source endpoint.
104229 +
104230 + @Return Abstract handle to the initialized session, or NULL on error.
104231 +*//***************************************************************************/
104232 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
104233 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
104234 +
104235 +/**************************************************************************//**
104236 + @Function XX_IpcFreeSession
104237 +
104238 + @Description This function is used for terminating an existing IPC session between a source endpoint
104239 + and a destination endpoint.
104240 +
104241 + The IPC service assumes that after this function is called, no messages shall be sent from
104242 + the associated source endpoint to the associated destination endpoint.
104243 +
104244 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
104245 + returned by the XX_IpcInitSession() function.
104246 +
104247 + @Return E_OK on success; Error code otherwise.
104248 +*//***************************************************************************/
104249 +t_Error XX_IpcFreeSession(t_Handle h_Session);
104250 +
104251 +/**************************************************************************//**
104252 + @Function XX_IpcSendMessage
104253 +
104254 + @Description IPC message send routine.
104255 +
104256 + This function may be used by a source endpoint to send an IPC message to a destination
104257 + endpoint. The source endpoint cannot send a message to the destination endpoint without
104258 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
104259 +
104260 + The source endpoint must provide the buffer pointer and length of the outgoing message.
104261 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
104262 + transaction is not considered complete by the IPC service until the reply has been received.
104263 + If the source endpoint does not provide a reply buffer, the transaction is considered
104264 + complete after the message has been sent. The source endpoint must keep the message (and
104265 + optional reply) buffers valid until the transaction is complete.
104266 +
104267 + @par Non-blocking mode
104268 +
104269 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
104270 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
104271 + message and an optional reply), the IPC service invokes this callback routine to return the message
104272 + buffer to the sender and to provide the received reply, if requested.
104273 +
104274 + @par Blocking mode
104275 +
104276 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
104277 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
104278 + was requested) the message has been sent.
104279 +
104280 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
104281 + returned by the XX_IpcInitSession() function.
104282 + @Param[in] p_Msg - Pointer to message buffer to send.
104283 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
104284 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
104285 + fills this buffer with the received reply data;
104286 + In blocking mode, the reply data must be valid when the function returns;
104287 + In non-blocking mode, the reply data is valid when f_Completion is called;
104288 + If this pointer is NULL, no reply is expected.
104289 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
104290 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
104291 + p_Reply, and
104292 + [Out] in non-blocking mode this value is updated by the IPC service to the
104293 + actual reply length (in bytes).
104294 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
104295 + The completion callback is invoked by the IPC service upon
104296 + completion of the IPC transaction (consisting of a message and an optional
104297 + reply);
104298 + If this pointer is NULL, the function is expected to block until the IPC
104299 + transaction is complete.
104300 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
104301 + callback function as the first argument.
104302 +
104303 + @Return E_OK on success; Error code otherwise.
104304 +*//***************************************************************************/
104305 +t_Error XX_IpcSendMessage(t_Handle h_Session,
104306 + uint8_t *p_Msg,
104307 + uint32_t msgLength,
104308 + uint8_t *p_Reply,
104309 + uint32_t *p_ReplyLength,
104310 + t_IpcMsgCompletion *f_Completion,
104311 + t_Handle h_Arg);
104312 +
104313 +
104314 +/** @} */ /* end of xx_ipc group */
104315 +/** @} */ /* end of xx_id group */
104316 +
104317 +
104318 +#endif /* __XX_EXT_H */
104319 --- /dev/null
104320 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
104321 @@ -0,0 +1,56 @@
104322 +/*
104323 + * Copyright 2012 Freescale Semiconductor Inc.
104324 + *
104325 + * Redistribution and use in source and binary forms, with or without
104326 + * modification, are permitted provided that the following conditions are met:
104327 + * * Redistributions of source code must retain the above copyright
104328 + * notice, this list of conditions and the following disclaimer.
104329 + * * Redistributions in binary form must reproduce the above copyright
104330 + * notice, this list of conditions and the following disclaimer in the
104331 + * documentation and/or other materials provided with the distribution.
104332 + * * Neither the name of Freescale Semiconductor nor the
104333 + * names of its contributors may be used to endorse or promote products
104334 + * derived from this software without specific prior written permission.
104335 + *
104336 + *
104337 + * ALTERNATIVELY, this software may be distributed under the terms of the
104338 + * GNU General Public License ("GPL") as published by the Free Software
104339 + * Foundation, either version 2 of that License or (at your option) any
104340 + * later version.
104341 + *
104342 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104343 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104344 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104345 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104346 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104347 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104348 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104349 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104350 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104351 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104352 + */
104353 +
104354 +#ifndef __dflags_h
104355 +#define __dflags_h
104356 +
104357 +
104358 +#define NCSW_LINUX
104359 +
104360 +#define LS1043
104361 +
104362 +#define DEBUG_ERRORS 1
104363 +
104364 +#if defined(DEBUG)
104365 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
104366 +
104367 +#define DEBUG_XX_MALLOC
104368 +#define DEBUG_MEM_LEAKS
104369 +
104370 +#else
104371 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
104372 +#endif /* (DEBUG) */
104373 +
104374 +#define REPORT_EVENTS 1
104375 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
104376 +
104377 +#endif /* __dflags_h */
104378 --- /dev/null
104379 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104380 @@ -0,0 +1,53 @@
104381 +#
104382 +# Makefile config for the Freescale NetcommSW
104383 +#
104384 +NET_DPA = $(srctree)/drivers/net
104385 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
104386 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
104387 +
104388 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
104389 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
104390 +endif
104391 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
104392 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
104393 +endif
104394 +ifdef CONFIG_FMAN_V3H
104395 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
104396 +endif
104397 +ifdef CONFIG_FMAN_V3L
104398 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
104399 +endif
104400 +ifdef CONFIG_FMAN_ARM
104401 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
104402 +endif
104403 +
104404 +ccflags-y += -I$(DRV_DPA)/
104405 +ccflags-y += -I$(FMAN)/inc
104406 +ccflags-y += -I$(FMAN)/inc/cores
104407 +ccflags-y += -I$(FMAN)/inc/etc
104408 +ccflags-y += -I$(FMAN)/inc/Peripherals
104409 +ccflags-y += -I$(FMAN)/inc/flib
104410 +
104411 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
104412 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
104413 +endif
104414 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
104415 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
104416 +endif
104417 +ifdef CONFIG_FMAN_V3H
104418 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
104419 +endif
104420 +ifdef CONFIG_FMAN_V3L
104421 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
104422 +endif
104423 +ifdef CONFIG_FMAN_ARM
104424 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
104425 +endif
104426 +
104427 +ccflags-y += -I$(FMAN)/src/inc
104428 +ccflags-y += -I$(FMAN)/src/inc/system
104429 +ccflags-y += -I$(FMAN)/src/inc/wrapper
104430 +ccflags-y += -I$(FMAN)/src/inc/xx
104431 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
104432 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
104433 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
104434 --- /dev/null
104435 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
104436 @@ -0,0 +1,65 @@
104437 +/*
104438 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104439 + *
104440 + * Redistribution and use in source and binary forms, with or without
104441 + * modification, are permitted provided that the following conditions are met:
104442 + * * Redistributions of source code must retain the above copyright
104443 + * notice, this list of conditions and the following disclaimer.
104444 + * * Redistributions in binary form must reproduce the above copyright
104445 + * notice, this list of conditions and the following disclaimer in the
104446 + * documentation and/or other materials provided with the distribution.
104447 + * * Neither the name of Freescale Semiconductor nor the
104448 + * names of its contributors may be used to endorse or promote products
104449 + * derived from this software without specific prior written permission.
104450 + *
104451 + *
104452 + * ALTERNATIVELY, this software may be distributed under the terms of the
104453 + * GNU General Public License ("GPL") as published by the Free Software
104454 + * Foundation, either version 2 of that License or (at your option) any
104455 + * later version.
104456 + *
104457 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104458 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104459 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104460 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104461 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104462 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104463 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104464 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104465 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104466 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104467 + */
104468 +
104469 +#ifndef __dflags_h
104470 +#define __dflags_h
104471 +
104472 +
104473 +#define NCSW_LINUX
104474 +#if 0
104475 +#define DEBUG
104476 +#endif
104477 +
104478 +#define P1023
104479 +#define NCSW_PPC_CORE
104480 +
104481 +#define DEBUG_ERRORS 1
104482 +
104483 +#if defined(DEBUG)
104484 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
104485 +
104486 +#define DEBUG_XX_MALLOC
104487 +#define DEBUG_MEM_LEAKS
104488 +
104489 +#else
104490 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
104491 +#endif /* (DEBUG) */
104492 +
104493 +#define REPORT_EVENTS 1
104494 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
104495 +
104496 +#ifdef CONFIG_P4080_SIM
104497 +#error "Do not define CONFIG_P4080_SIM..."
104498 +#endif
104499 +
104500 +
104501 +#endif /* __dflags_h */
104502 --- /dev/null
104503 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
104504 @@ -0,0 +1,62 @@
104505 +/*
104506 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104507 + *
104508 + * Redistribution and use in source and binary forms, with or without
104509 + * modification, are permitted provided that the following conditions are met:
104510 + * * Redistributions of source code must retain the above copyright
104511 + * notice, this list of conditions and the following disclaimer.
104512 + * * Redistributions in binary form must reproduce the above copyright
104513 + * notice, this list of conditions and the following disclaimer in the
104514 + * documentation and/or other materials provided with the distribution.
104515 + * * Neither the name of Freescale Semiconductor nor the
104516 + * names of its contributors may be used to endorse or promote products
104517 + * derived from this software without specific prior written permission.
104518 + *
104519 + *
104520 + * ALTERNATIVELY, this software may be distributed under the terms of the
104521 + * GNU General Public License ("GPL") as published by the Free Software
104522 + * Foundation, either version 2 of that License or (at your option) any
104523 + * later version.
104524 + *
104525 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104526 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104527 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104528 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104529 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104530 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104531 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104532 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104533 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104534 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104535 + */
104536 +
104537 +#ifndef __dflags_h
104538 +#define __dflags_h
104539 +
104540 +
104541 +#define NCSW_LINUX
104542 +
104543 +#define P4080
104544 +#define NCSW_PPC_CORE
104545 +
104546 +#define DEBUG_ERRORS 1
104547 +
104548 +#if defined(DEBUG)
104549 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
104550 +
104551 +#define DEBUG_XX_MALLOC
104552 +#define DEBUG_MEM_LEAKS
104553 +
104554 +#else
104555 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
104556 +#endif /* (DEBUG) */
104557 +
104558 +#define REPORT_EVENTS 1
104559 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
104560 +
104561 +#ifdef CONFIG_P4080_SIM
104562 +#define SIMULATOR
104563 +#endif /* CONFIG_P4080_SIM */
104564 +
104565 +
104566 +#endif /* __dflags_h */
104567 --- /dev/null
104568 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
104569 @@ -0,0 +1,11 @@
104570 +#
104571 +# Makefile for the Freescale Ethernet controllers
104572 +#
104573 +ccflags-y += -DVERSION=\"\"
104574 +#
104575 +#Include netcomm SW specific definitions
104576 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104577 +#
104578 +obj-y += system/
104579 +obj-y += wrapper/
104580 +obj-y += xx/
104581 --- /dev/null
104582 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
104583 @@ -0,0 +1,118 @@
104584 +/*
104585 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104586 + *
104587 + * Redistribution and use in source and binary forms, with or without
104588 + * modification, are permitted provided that the following conditions are met:
104589 + * * Redistributions of source code must retain the above copyright
104590 + * notice, this list of conditions and the following disclaimer.
104591 + * * Redistributions in binary form must reproduce the above copyright
104592 + * notice, this list of conditions and the following disclaimer in the
104593 + * documentation and/or other materials provided with the distribution.
104594 + * * Neither the name of Freescale Semiconductor nor the
104595 + * names of its contributors may be used to endorse or promote products
104596 + * derived from this software without specific prior written permission.
104597 + *
104598 + *
104599 + * ALTERNATIVELY, this software may be distributed under the terms of the
104600 + * GNU General Public License ("GPL") as published by the Free Software
104601 + * Foundation, either version 2 of that License or (at your option) any
104602 + * later version.
104603 + *
104604 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104605 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104606 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104607 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104608 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104609 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104610 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104611 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104612 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104613 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104614 + */
104615 +
104616 +#ifndef __SYS_EXT_H
104617 +#define __SYS_EXT_H
104618 +
104619 +#include "std_ext.h"
104620 +
104621 +
104622 +/**************************************************************************//**
104623 + @Group sys_grp System Interfaces
104624 +
104625 + @Description Linux system programming interfaces.
104626 +
104627 + @{
104628 +*//***************************************************************************/
104629 +
104630 +/**************************************************************************//**
104631 + @Group sys_gen_grp System General Interface
104632 +
104633 + @Description General definitions, structures and routines of the linux
104634 + system programming interface.
104635 +
104636 + @{
104637 +*//***************************************************************************/
104638 +
104639 +/**************************************************************************//**
104640 + @Collection Macros for Advanced Configuration Requests
104641 + @{
104642 +*//***************************************************************************/
104643 +#define SYS_MAX_ADV_CONFIG_ARGS 4
104644 + /**< Maximum number of arguments in
104645 + an advanced configuration entry */
104646 +/* @} */
104647 +
104648 +/**************************************************************************//**
104649 + @Description System Object Advanced Configuration Entry
104650 +
104651 + This structure represents a single request for an advanced
104652 + configuration call on the initialized object. An array of such
104653 + requests may be contained in the settings structure of the
104654 + corresponding object.
104655 +
104656 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
104657 +*//***************************************************************************/
104658 +typedef struct t_SysObjectAdvConfigEntry
104659 +{
104660 + void *p_Function; /**< Pointer to advanced configuration routine */
104661 +
104662 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
104663 + /**< Array of arguments for the specified routine;
104664 + All arguments should be casted to uint32_t. */
104665 +} t_SysObjectAdvConfigEntry;
104666 +
104667 +
104668 +/** @} */ /* end of sys_gen_grp */
104669 +/** @} */ /* end of sys_grp */
104670 +
104671 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
104672 +
104673 +#define ADV_CONFIG_PARAMS_1(_type) \
104674 + , (_type)p_Entry->args[0]
104675 +
104676 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
104677 + p_Entry->args[0] = (uintptr_t )(_arg0); \
104678 +
104679 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
104680 +
104681 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
104682 + { \
104683 + t_SysObjectAdvConfigEntry *p_Entry; \
104684 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
104685 + int i=0, max = (_maxEntries); \
104686 +
104687 +#define ADD_ADV_CONFIG_END \
104688 + }
104689 +
104690 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
104691 + { \
104692 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
104693 + t_Error errCode; \
104694 +
104695 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
104696 + if (p_Entry->p_Function == _func) \
104697 + { \
104698 + errCode = _func(_handle _params); \
104699 + } else
104700 +
104701 +#endif /* __SYS_EXT_H */
104702 --- /dev/null
104703 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
104704 @@ -0,0 +1,46 @@
104705 +/*
104706 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104707 + *
104708 + * Redistribution and use in source and binary forms, with or without
104709 + * modification, are permitted provided that the following conditions are met:
104710 + * * Redistributions of source code must retain the above copyright
104711 + * notice, this list of conditions and the following disclaimer.
104712 + * * Redistributions in binary form must reproduce the above copyright
104713 + * notice, this list of conditions and the following disclaimer in the
104714 + * documentation and/or other materials provided with the distribution.
104715 + * * Neither the name of Freescale Semiconductor nor the
104716 + * names of its contributors may be used to endorse or promote products
104717 + * derived from this software without specific prior written permission.
104718 + *
104719 + *
104720 + * ALTERNATIVELY, this software may be distributed under the terms of the
104721 + * GNU General Public License ("GPL") as published by the Free Software
104722 + * Foundation, either version 2 of that License or (at your option) any
104723 + * later version.
104724 + *
104725 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104726 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104727 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104728 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104729 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104730 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104731 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104732 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104733 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104734 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104735 + */
104736 +
104737 +#ifndef __SYS_IO_EXT_H
104738 +#define __SYS_IO_EXT_H
104739 +
104740 +#include "std_ext.h"
104741 +#include "error_ext.h"
104742 +
104743 +
104744 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
104745 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
104746 +uint64_t SYS_PhysToVirt (uint64_t addr);
104747 +uint64_t SYS_VirtToPhys (uint64_t addr);
104748 +
104749 +
104750 +#endif /* __SYS_IO_EXT_H */
104751 --- /dev/null
104752 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
104753 @@ -0,0 +1,208 @@
104754 +/*
104755 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104756 + *
104757 + * Redistribution and use in source and binary forms, with or without
104758 + * modification, are permitted provided that the following conditions are met:
104759 + * * Redistributions of source code must retain the above copyright
104760 + * notice, this list of conditions and the following disclaimer.
104761 + * * Redistributions in binary form must reproduce the above copyright
104762 + * notice, this list of conditions and the following disclaimer in the
104763 + * documentation and/or other materials provided with the distribution.
104764 + * * Neither the name of Freescale Semiconductor nor the
104765 + * names of its contributors may be used to endorse or promote products
104766 + * derived from this software without specific prior written permission.
104767 + *
104768 + *
104769 + * ALTERNATIVELY, this software may be distributed under the terms of the
104770 + * GNU General Public License ("GPL") as published by the Free Software
104771 + * Foundation, either version 2 of that License or (at your option) any
104772 + * later version.
104773 + *
104774 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104775 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104776 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104777 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104778 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104779 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104780 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104781 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104782 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104783 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104784 + */
104785 +
104786 +#ifndef __TYPES_LINUX_H__
104787 +#define __TYPES_LINUX_H__
104788 +
104789 +#include <linux/version.h>
104790 +
104791 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
104792 +#define MODVERSIONS
104793 +#endif
104794 +#ifdef MODVERSIONS
104795 +#include <config/modversions.h>
104796 +#endif /* MODVERSIONS */
104797 +
104798 +#include <linux/kernel.h>
104799 +#include <linux/types.h>
104800 +#include <asm/io.h>
104801 +#include <linux/delay.h>
104802 +
104803 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
104804 + #error "This kernel is probably not supported!!!"
104805 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
104806 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
104807 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
104808 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
104809 +#endif /* LINUX_VERSION_CODE */
104810 +
104811 +
104812 +typedef float float_t; /* Single precision floating point */
104813 +typedef double double_t; /* Double precision floating point */
104814 +
104815 +
104816 +#define _Packed
104817 +#define _PackedType __attribute__ ((packed))
104818 +
104819 +typedef phys_addr_t physAddress_t;
104820 +
104821 +#define UINT8_MAX 0xFF
104822 +#define UINT8_MIN 0
104823 +#define UINT16_MAX 0xFFFF
104824 +#define UINT16_MIN 0
104825 +#define UINT32_MAX 0xFFFFFFFF
104826 +#define UINT32_MIN 0
104827 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
104828 +#define UINT64_MIN 0
104829 +#define INT8_MAX 0x7F
104830 +#define INT8_MIN 0x80
104831 +#define INT16_MAX 0x7FFF
104832 +#define INT16_MIN 0x8000
104833 +#define INT32_MAX 0x7FFFFFFF
104834 +#define INT32_MIN 0x80000000
104835 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
104836 +#define INT64_MIN 0x8000000000000000LL
104837 +
104838 +#define ON 1
104839 +#define OFF 0
104840 +
104841 +#define FALSE false
104842 +#define TRUE true
104843 +
104844 +
104845 +/************************/
104846 +/* memory access macros */
104847 +/************************/
104848 +#ifdef CONFIG_FMAN_ARM
104849 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
104850 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
104851 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
104852 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
104853 +#endif
104854 +
104855 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
104856 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
104857 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
104858 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
104859 +
104860 +#ifdef VERBOSE_WRITE
104861 +void XX_Print(char *str, ...);
104862 +#define WRITE_UINT8(arg, data) \
104863 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
104864 +#define WRITE_UINT16(arg, data) \
104865 + 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)
104866 +#define WRITE_UINT32(arg, data) \
104867 + 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)
104868 +#define WRITE_UINT64(arg, data) \
104869 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
104870 +
104871 +#else /* not VERBOSE_WRITE */
104872 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
104873 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
104874 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
104875 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
104876 +#endif /* not VERBOSE_WRITE */
104877 +
104878 +
104879 +/*****************************************************************************/
104880 +/* General stuff */
104881 +/*****************************************************************************/
104882 +#ifdef ARRAY_SIZE
104883 +#undef ARRAY_SIZE
104884 +#endif /* ARRAY_SIZE */
104885 +
104886 +#ifdef MAJOR
104887 +#undef MAJOR
104888 +#endif /* MAJOR */
104889 +
104890 +#ifdef MINOR
104891 +#undef MINOR
104892 +#endif /* MINOR */
104893 +
104894 +#ifdef QE_SIZEOF_BD
104895 +#undef QE_SIZEOF_BD
104896 +#endif /* QE_SIZEOF_BD */
104897 +
104898 +#ifdef BD_BUFFER_CLEAR
104899 +#undef BD_BUFFER_CLEAR
104900 +#endif /* BD_BUFFER_CLEAR */
104901 +
104902 +#ifdef BD_BUFFER
104903 +#undef BD_BUFFER
104904 +#endif /* BD_BUFFER */
104905 +
104906 +#ifdef BD_STATUS_AND_LENGTH_SET
104907 +#undef BD_STATUS_AND_LENGTH_SET
104908 +#endif /* BD_STATUS_AND_LENGTH_SET */
104909 +
104910 +#ifdef BD_STATUS_AND_LENGTH
104911 +#undef BD_STATUS_AND_LENGTH
104912 +#endif /* BD_STATUS_AND_LENGTH */
104913 +
104914 +#ifdef BD_BUFFER_ARG
104915 +#undef BD_BUFFER_ARG
104916 +#endif /* BD_BUFFER_ARG */
104917 +
104918 +#ifdef BD_GET_NEXT
104919 +#undef BD_GET_NEXT
104920 +#endif /* BD_GET_NEXT */
104921 +
104922 +#ifdef QE_SDEBCR_BA_MASK
104923 +#undef QE_SDEBCR_BA_MASK
104924 +#endif /* QE_SDEBCR_BA_MASK */
104925 +
104926 +#ifdef BD_BUFFER_SET
104927 +#undef BD_BUFFER_SET
104928 +#endif /* BD_BUFFER_SET */
104929 +
104930 +#ifdef UPGCR_PROTOCOL
104931 +#undef UPGCR_PROTOCOL
104932 +#endif /* UPGCR_PROTOCOL */
104933 +
104934 +#ifdef UPGCR_TMS
104935 +#undef UPGCR_TMS
104936 +#endif /* UPGCR_TMS */
104937 +
104938 +#ifdef UPGCR_RMS
104939 +#undef UPGCR_RMS
104940 +#endif /* UPGCR_RMS */
104941 +
104942 +#ifdef UPGCR_ADDR
104943 +#undef UPGCR_ADDR
104944 +#endif /* UPGCR_ADDR */
104945 +
104946 +#ifdef UPGCR_DIAG
104947 +#undef UPGCR_DIAG
104948 +#endif /* UPGCR_DIAG */
104949 +
104950 +#ifdef NCSW_PARAMS
104951 +#undef NCSW_PARAMS
104952 +#endif /* NCSW_PARAMS */
104953 +
104954 +#ifdef NO_IRQ
104955 +#undef NO_IRQ
104956 +#endif /* NO_IRQ */
104957 +
104958 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
104959 +
104960 +
104961 +#endif /* __TYPES_LINUX_H__ */
104962 --- /dev/null
104963 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
104964 @@ -0,0 +1,84 @@
104965 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
104966 + * All rights reserved.
104967 + *
104968 + * Redistribution and use in source and binary forms, with or without
104969 + * modification, are permitted provided that the following conditions are met:
104970 + * * Redistributions of source code must retain the above copyright
104971 + * notice, this list of conditions and the following disclaimer.
104972 + * * Redistributions in binary form must reproduce the above copyright
104973 + * notice, this list of conditions and the following disclaimer in the
104974 + * documentation and/or other materials provided with the distribution.
104975 + * * Neither the name of Freescale Semiconductor nor the
104976 + * names of its contributors may be used to endorse or promote products
104977 + * derived from this software without specific prior written permission.
104978 + *
104979 + *
104980 + * ALTERNATIVELY, this software may be distributed under the terms of the
104981 + * GNU General Public License ("GPL") as published by the Free Software
104982 + * Foundation, either version 2 of that License or (at your option) any
104983 + * later version.
104984 + *
104985 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104986 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104987 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104988 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104989 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104990 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104991 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104992 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104993 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104994 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104995 + */
104996 +
104997 +/******************************************************************************
104998 + @File fsl_fman_test.h
104999 +
105000 + @Description
105001 +*//***************************************************************************/
105002 +
105003 +#ifndef __FSL_FMAN_TEST_H
105004 +#define __FSL_FMAN_TEST_H
105005 +
105006 +#include <linux/types.h>
105007 +#include <linux/smp.h> /* raw_smp_processor_id() */
105008 +
105009 +//#define FMT_K_DBG
105010 +//#define FMT_K_DBG_RUNTIME
105011 +
105012 +#define _fmt_prk(stage, format, arg...) \
105013 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
105014 +
105015 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
105016 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
105017 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
105018 +
105019 +/* there are two macros for debugging: for runtime and generic.
105020 + * Helps when the runtime functions are not targeted for debugging,
105021 + * thus all the unnecessary information will be skipped.
105022 + */
105023 +/* used for generic debugging */
105024 +#if defined(FMT_K_DBG)
105025 + #define _fmt_dbg(format, arg...) \
105026 + printk("fmt [%s:%u](cpu:%u) - " format, \
105027 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
105028 +#else
105029 +# define _fmt_dbg(arg...)
105030 +#endif
105031 +
105032 +/* used for debugging runtime functions */
105033 +#if defined(FMT_K_DBG_RUNTIME)
105034 + #define _fmt_dbgr(format, arg...) \
105035 + printk("fmt [%s:%u](cpu:%u) - " format, \
105036 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
105037 +#else
105038 +# define _fmt_dbgr(arg...)
105039 +#endif
105040 +
105041 +#define FMT_RX_ERR_Q 0xffffffff
105042 +#define FMT_RX_DFLT_Q 0xfffffffe
105043 +#define FMT_TX_ERR_Q 0xfffffffd
105044 +#define FMT_TX_CONF_Q 0xfffffffc
105045 +
105046 +#define FMAN_TEST_MAX_TX_FQS 8
105047 +
105048 +#endif /* __FSL_FMAN_TEST_H */
105049 --- /dev/null
105050 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
105051 @@ -0,0 +1,130 @@
105052 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
105053 + * All rights reserved.
105054 + *
105055 + * Redistribution and use in source and binary forms, with or without
105056 + * modification, are permitted provided that the following conditions are met:
105057 + * * Redistributions of source code must retain the above copyright
105058 + * notice, this list of conditions and the following disclaimer.
105059 + * * Redistributions in binary form must reproduce the above copyright
105060 + * notice, this list of conditions and the following disclaimer in the
105061 + * documentation and/or other materials provided with the distribution.
105062 + * * Neither the name of Freescale Semiconductor nor the
105063 + * names of its contributors may be used to endorse or promote products
105064 + * derived from this software without specific prior written permission.
105065 + *
105066 + *
105067 + * ALTERNATIVELY, this software may be distributed under the terms of the
105068 + * GNU General Public License ("GPL") as published by the Free Software
105069 + * Foundation, either version 2 of that License or (at your option) any
105070 + * later version.
105071 + *
105072 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105073 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105074 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105075 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105076 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105077 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105078 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105079 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105080 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105081 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105082 + */
105083 +
105084 +/*
105085 + @File lnxwrp_exp_sym.h
105086 + @Description FMan exported routines
105087 +*/
105088 +
105089 +#ifndef __LNXWRP_EXP_SYM_H
105090 +#define __LNXWRP_EXP_SYM_H
105091 +
105092 +#include "fm_port_ext.h"
105093 +#include "fm_pcd_ext.h"
105094 +#include "fm_mac_ext.h"
105095 +
105096 +
105097 +/* FMAN Port exported routines */
105098 +EXPORT_SYMBOL(FM_PORT_Disable);
105099 +EXPORT_SYMBOL(FM_PORT_Enable);
105100 +EXPORT_SYMBOL(FM_PORT_SetPCD);
105101 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
105102 +
105103 +/* Runtime PCD exported routines */
105104 +EXPORT_SYMBOL(FM_PCD_Enable);
105105 +EXPORT_SYMBOL(FM_PCD_Disable);
105106 +EXPORT_SYMBOL(FM_PCD_GetCounter);
105107 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
105108 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
105109 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
105110 +EXPORT_SYMBOL(FM_PCD_SetException);
105111 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
105112 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
105113 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
105114 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
105115 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
105116 +
105117 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
105118 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
105119 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
105120 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
105121 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
105122 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
105123 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
105124 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
105125 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
105126 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
105127 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
105128 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
105129 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
105130 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
105131 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
105132 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
105133 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
105134 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
105135 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
105136 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
105137 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
105138 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
105139 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
105140 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
105141 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
105142 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
105143 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
105144 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
105145 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
105146 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
105147 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
105148 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
105149 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
105150 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
105151 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
105152 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
105153 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
105154 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
105155 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
105156 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
105157 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
105158 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
105159 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
105160 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
105161 +#if (DPAA_VERSION >= 11)
105162 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
105163 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
105164 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
105165 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
105166 +#endif /* DPAA_VERSION >= 11 */
105167 +
105168 +#ifdef FM_CAPWAP_SUPPORT
105169 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
105170 +#endif /* FM_CAPWAP_SUPPORT */
105171 +
105172 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
105173 +
105174 +/* FMAN MAC exported routines */
105175 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
105176 +
105177 +EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters);
105178 +
105179 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
105180 +
105181 +#endif /* __LNXWRP_EXP_SYM_H */
105182 --- /dev/null
105183 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
105184 @@ -0,0 +1,163 @@
105185 +/*
105186 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105187 + *
105188 + * Redistribution and use in source and binary forms, with or without
105189 + * modification, are permitted provided that the following conditions are met:
105190 + * * Redistributions of source code must retain the above copyright
105191 + * notice, this list of conditions and the following disclaimer.
105192 + * * Redistributions in binary form must reproduce the above copyright
105193 + * notice, this list of conditions and the following disclaimer in the
105194 + * documentation and/or other materials provided with the distribution.
105195 + * * Neither the name of Freescale Semiconductor nor the
105196 + * names of its contributors may be used to endorse or promote products
105197 + * derived from this software without specific prior written permission.
105198 + *
105199 + *
105200 + * ALTERNATIVELY, this software may be distributed under the terms of the
105201 + * GNU General Public License ("GPL") as published by the Free Software
105202 + * Foundation, either version 2 of that License or (at your option) any
105203 + * later version.
105204 + *
105205 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105206 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105207 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105208 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105209 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105210 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105211 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105212 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105213 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105214 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105215 + */
105216 +
105217 +/******************************************************************************
105218 + @File lnxwrp_fm_ext.h
105219 +
105220 + @Description TODO
105221 +*//***************************************************************************/
105222 +
105223 +#ifndef __LNXWRP_FM_EXT_H
105224 +#define __LNXWRP_FM_EXT_H
105225 +
105226 +#include "std_ext.h"
105227 +#include "sys_ext.h"
105228 +#include "fm_ext.h"
105229 +#include "fm_muram_ext.h"
105230 +#include "fm_pcd_ext.h"
105231 +#include "fm_port_ext.h"
105232 +#include "fm_mac_ext.h"
105233 +#include "fm_rtc_ext.h"
105234 +
105235 +
105236 +/**************************************************************************//**
105237 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
105238 +
105239 + @Description FM API functions, definitions and enums.
105240 +
105241 + @{
105242 +*//***************************************************************************/
105243 +
105244 +/**************************************************************************//**
105245 + @Group FM_LnxKern_init_grp Initialization Unit
105246 +
105247 + @Description Initialization Unit
105248 +
105249 + Initialization Flow:
105250 + Initialization of the FM Module will be carried out by the Linux
105251 + kernel according to the following sequence:
105252 + a. Calling the initialization routine with no parameters.
105253 + b. The driver will register to the Device-Tree.
105254 + c. The Linux Device-Tree will initiate a call to the driver for
105255 + initialization.
105256 + d. The driver will read the appropriate information from the Device-Tree
105257 + e. [Optional] Calling the advance initialization routines to change
105258 + driver's defaults.
105259 + f. Initialization of the device will be automatically upon using it.
105260 +
105261 + @{
105262 +*//***************************************************************************/
105263 +
105264 +typedef struct t_WrpFmDevSettings
105265 +{
105266 + t_FmParams param;
105267 + t_SysObjectAdvConfigEntry *advConfig;
105268 +} t_WrpFmDevSettings;
105269 +
105270 +typedef struct t_WrpFmPcdDevSettings
105271 +{
105272 + t_FmPcdParams param;
105273 + t_SysObjectAdvConfigEntry *advConfig;
105274 +} t_WrpFmPcdDevSettings;
105275 +
105276 +typedef struct t_WrpFmPortDevSettings
105277 +{
105278 + bool frag_enabled;
105279 + t_FmPortParams param;
105280 + t_SysObjectAdvConfigEntry *advConfig;
105281 +} t_WrpFmPortDevSettings;
105282 +
105283 +typedef struct t_WrpFmMacDevSettings
105284 +{
105285 + t_FmMacParams param;
105286 + t_SysObjectAdvConfigEntry *advConfig;
105287 +} t_WrpFmMacDevSettings;
105288 +
105289 +
105290 +/**************************************************************************//**
105291 + @Function LNXWRP_FM_Init
105292 +
105293 + @Description Initialize the FM linux wrapper.
105294 +
105295 + @Return A handle (descriptor) of the newly created FM Linux wrapper
105296 + structure.
105297 +*//***************************************************************************/
105298 +t_Handle LNXWRP_FM_Init(void);
105299 +
105300 +/**************************************************************************//**
105301 + @Function LNXWRP_FM_Free
105302 +
105303 + @Description Free the FM linux wrapper.
105304 +
105305 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
105306 +
105307 + @Return E_OK on success; Error code otherwise.
105308 +*//***************************************************************************/
105309 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
105310 +
105311 +/**************************************************************************//**
105312 + @Function LNXWRP_FM_GetMacHandle
105313 +
105314 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
105315 +
105316 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
105317 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
105318 + @Param[in] macId - Index of the mac handle.
105319 +
105320 + @Return A handle of the LLD compressor.
105321 +*//***************************************************************************/
105322 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
105323 +
105324 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
105325 +t_Handle LNXWRP_FM_TEST_Init(void);
105326 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
105327 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
105328 +
105329 +/** @} */ /* end of FM_LnxKern_init_grp group */
105330 +
105331 +
105332 +/**************************************************************************//**
105333 + @Group FM_LnxKern_ctrl_grp Control Unit
105334 +
105335 + @Description Control Unit
105336 +
105337 + TODO
105338 + @{
105339 +*//***************************************************************************/
105340 +
105341 +#include "lnxwrp_fsl_fman.h"
105342 +
105343 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
105344 +/** @} */ /* end of FM_LnxKern_grp group */
105345 +
105346 +
105347 +#endif /* __LNXWRP_FM_EXT_H */
105348 --- /dev/null
105349 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
105350 @@ -0,0 +1,921 @@
105351 +/*
105352 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105353 + *
105354 + * Redistribution and use in source and binary forms, with or without
105355 + * modification, are permitted provided that the following conditions are met:
105356 + * * Redistributions of source code must retain the above copyright
105357 + * notice, this list of conditions and the following disclaimer.
105358 + * * Redistributions in binary form must reproduce the above copyright
105359 + * notice, this list of conditions and the following disclaimer in the
105360 + * documentation and/or other materials provided with the distribution.
105361 + * * Neither the name of Freescale Semiconductor nor the
105362 + * names of its contributors may be used to endorse or promote products
105363 + * derived from this software without specific prior written permission.
105364 + *
105365 + *
105366 + * ALTERNATIVELY, this software may be distributed under the terms of the
105367 + * GNU General Public License ("GPL") as published by the Free Software
105368 + * Foundation, either version 2 of that License or (at your option) any
105369 + * later version.
105370 + *
105371 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105372 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105373 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105374 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105375 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105376 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105377 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105378 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105379 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105380 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105381 + */
105382 +
105383 +/******************************************************************************
105384 + @File lnxwrp_fsl_fman.h
105385 +
105386 + @Description Linux internal kernel API
105387 +*//***************************************************************************/
105388 +
105389 +#ifndef __LNXWRP_FSL_FMAN_H
105390 +#define __LNXWRP_FSL_FMAN_H
105391 +
105392 +#include <linux/types.h>
105393 +#include <linux/device.h> /* struct device */
105394 +#include <linux/fsl_qman.h> /* struct qman_fq */
105395 +#include "dpaa_integration_ext.h"
105396 +#include "fm_port_ext.h"
105397 +#include "fm_mac_ext.h"
105398 +#include "fm_macsec_ext.h"
105399 +#include "fm_rtc_ext.h"
105400 +
105401 +/**************************************************************************//**
105402 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
105403 +
105404 + @Description FM API functions, definitions and enums.
105405 +
105406 + @{
105407 +*//***************************************************************************/
105408 +
105409 +/**************************************************************************//**
105410 + @Group FM_LnxKern_ctrl_grp Control Unit
105411 +
105412 + @Description Control Unit
105413 +
105414 + Internal Kernel Control Unit API
105415 + @{
105416 +*//***************************************************************************/
105417 +
105418 +/*****************************************************************************/
105419 +/* Internal Linux kernel routines */
105420 +/*****************************************************************************/
105421 +
105422 +/**************************************************************************//**
105423 + @Description MACSEC Exceptions wrapper
105424 +*//***************************************************************************/
105425 +typedef enum fm_macsec_exception {
105426 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
105427 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
105428 +} fm_macsec_exception;
105429 +
105430 +/**************************************************************************//**
105431 + @Description Unknown sci frame treatment wrapper
105432 +*//***************************************************************************/
105433 +typedef enum fm_macsec_unknown_sci_frame_treatment {
105434 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
105435 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
105436 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
105437 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
105438 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
105439 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
105440 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
105441 +} fm_macsec_unknown_sci_frame_treatment;
105442 +
105443 +/**************************************************************************//**
105444 + @Description Untag frame treatment wrapper
105445 +*//***************************************************************************/
105446 +typedef enum fm_macsec_untag_frame_treatment {
105447 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
105448 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
105449 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
105450 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
105451 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
105452 +} fm_macsec_untag_frame_treatment;
105453 +
105454 +/**************************************************************************//**
105455 +@Description MACSEC SECY Cipher Suite wrapper
105456 +*//***************************************************************************/
105457 +typedef enum fm_macsec_secy_cipher_suite {
105458 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
105459 +#if (DPAA_VERSION >= 11)
105460 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
105461 +#endif /* (DPAA_VERSION >= 11) */
105462 +} fm_macsec_secy_cipher_suite;
105463 +
105464 +/**************************************************************************//**
105465 + @Description MACSEC SECY Exceptions wrapper
105466 +*//***************************************************************************/
105467 +typedef enum fm_macsec_secy_exception {
105468 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
105469 +} fm_macsec_secy_exception;
105470 +
105471 +/**************************************************************************//**
105472 + @Description MACSEC SECY Events wrapper
105473 +*//***************************************************************************/
105474 +typedef enum fm_macsec_secy_event {
105475 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
105476 +} fm_macsec_secy_event;
105477 +
105478 +/**************************************************************************//**
105479 + @Description Valid frame behaviors wrapper
105480 +*//***************************************************************************/
105481 +typedef enum fm_macsec_valid_frame_behavior {
105482 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
105483 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
105484 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
105485 +} fm_macsec_valid_frame_behavior;
105486 +
105487 +/**************************************************************************//**
105488 + @Description SCI insertion modes wrapper
105489 +*//***************************************************************************/
105490 +typedef enum fm_macsec_sci_insertion_mode {
105491 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
105492 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
105493 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
105494 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
105495 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
105496 +} fm_macsec_sci_insertion_mode;
105497 +
105498 +typedef macsecSAKey_t macsec_sa_key_t;
105499 +typedef macsecSCI_t macsec_sci_t;
105500 +typedef macsecAN_t macsec_an_t;
105501 +typedef t_Handle handle_t;
105502 +
105503 +/**************************************************************************//**
105504 + @Function fm_macsec_secy_exception_callback wrapper
105505 + @Description Exceptions user callback routine, will be called upon an
105506 + exception passing the exception identification.
105507 + @Param[in] app_h A handle to an application layer object; This handle
105508 + will be passed by the driver upon calling this callback.
105509 + @Param[in] exception The exception.
105510 +*//***************************************************************************/
105511 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
105512 + fm_macsec_secy_exception exception);
105513 +
105514 +/**************************************************************************//**
105515 + @Function fm_macsec_secy_event_callback wrapper
105516 + @Description Events user callback routine, will be called upon an
105517 + event passing the event identification.
105518 + @Param[in] app_h A handle to an application layer object; This handle
105519 + will be passed by the driver upon calling this callback.
105520 + @Param[in] event The event.
105521 +*//***************************************************************************/
105522 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
105523 + fm_macsec_secy_event event);
105524 +
105525 +/**************************************************************************//**
105526 + @Function fm_macsec_exception_callback wrapper
105527 + @Description Exceptions user callback routine, will be called upon an
105528 + exception passing the exception identification.
105529 + @Param[in] app_h A handle to an application layer object; This handle
105530 + will be passed by the driver upon calling this callback.
105531 + @Param[in] exception The exception.
105532 +*//***************************************************************************/
105533 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
105534 + fm_macsec_exception exception);
105535 +
105536 +/**************************************************************************//**
105537 + @Description MACSEC SecY SC Params wrapper
105538 +*//***************************************************************************/
105539 +struct fm_macsec_secy_sc_params {
105540 + macsec_sci_t sci;
105541 + fm_macsec_secy_cipher_suite cipher_suite;
105542 +};
105543 +
105544 +/**************************************************************************//**
105545 + @Description FM MACSEC SecY config input wrapper
105546 +*//***************************************************************************/
105547 +struct fm_macsec_secy_params {
105548 + handle_t fm_macsec_h;
105549 + struct fm_macsec_secy_sc_params tx_sc_params;
105550 + uint32_t num_receive_channels;
105551 + fm_macsec_secy_exception_callback *exception_f;
105552 + fm_macsec_secy_event_callback *event_f;
105553 + handle_t app_h;
105554 +};
105555 +
105556 +/**************************************************************************//**
105557 + @Description FM MACSEC config input wrapper
105558 +*//***************************************************************************/
105559 +struct fm_macsec_params {
105560 + handle_t fm_h;
105561 + bool guest_mode;
105562 +
105563 + union {
105564 + struct {
105565 + uint8_t fm_mac_id;
105566 + } guest_params;
105567 +
105568 + struct {
105569 + uintptr_t base_addr;
105570 + handle_t fm_mac_h;
105571 + fm_macsec_exception_callback *exception_f;
105572 + handle_t app_h;
105573 + } non_guest_params;
105574 + };
105575 +
105576 +};
105577 +
105578 +/**************************************************************************//**
105579 + @Description FM device opaque structure used for type checking
105580 +*//***************************************************************************/
105581 +struct fm;
105582 +
105583 +/**************************************************************************//**
105584 + @Description FM MAC device opaque structure used for type checking
105585 +*//***************************************************************************/
105586 +struct fm_mac_dev;
105587 +
105588 +/**************************************************************************//**
105589 + @Description FM MACSEC device opaque structure used for type checking
105590 +*//***************************************************************************/
105591 +struct fm_macsec_dev;
105592 +struct fm_macsec_secy_dev;
105593 +
105594 +/**************************************************************************//**
105595 + @Description A structure ..,
105596 +*//***************************************************************************/
105597 +struct fm_port;
105598 +
105599 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
105600 + uint8_t alignment, uint32_t *base_fqid);
105601 +
105602 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
105603 +
105604 +struct fm_port_pcd_param {
105605 + alloc_pcd_fqids cba;
105606 + free_pcd_fqids cbf;
105607 + struct device *dev;
105608 +};
105609 +
105610 +/**************************************************************************//**
105611 + @Description A structure of information about each of the external
105612 + buffer pools used by the port,
105613 +*//***************************************************************************/
105614 +struct fm_port_pool_param {
105615 + uint8_t id; /**< External buffer pool id */
105616 + uint16_t size; /**< External buffer pool buffer size */
105617 +};
105618 +
105619 +/**************************************************************************//**
105620 + @Description structure for additional port parameters
105621 +*//***************************************************************************/
105622 +struct fm_port_params {
105623 + uint32_t errq; /**< Error Queue Id. */
105624 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
105625 + 0 means no Tx conf for processed frames.
105626 + For Rx and OP - default Rx queue. */
105627 + uint8_t num_pools; /**< Number of pools use by this port */
105628 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
105629 + /**< Parameters for each pool */
105630 + uint16_t priv_data_size; /**< Area that user may save for his own
105631 + need (E.g. save the SKB) */
105632 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
105633 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
105634 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
105635 + bool frag_enable; /**< Fragmentation support, for OP only */
105636 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
105637 + if write optimization is used, must be >= 16. */
105638 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
105639 + Note that this field impacts the size of the buffer-prefix
105640 + (i.e. it pushes the data offset); */
105641 +};
105642 +
105643 +/**************************************************************************//**
105644 + @Function fm_bind
105645 +
105646 + @Description Bind to a specific FM device.
105647 +
105648 + @Param[in] fm_dev - the OF handle of the FM device.
105649 +
105650 + @Return A handle of the FM device.
105651 +
105652 + @Cautions Allowed only after the port was created.
105653 +*//***************************************************************************/
105654 +struct fm *fm_bind(struct device *fm_dev);
105655 +
105656 +/**************************************************************************//**
105657 + @Function fm_unbind
105658 +
105659 + @Description Un-bind from a specific FM device.
105660 +
105661 + @Param[in] fm - A handle of the FM device.
105662 +
105663 + @Cautions Allowed only after the port was created.
105664 +*//***************************************************************************/
105665 +void fm_unbind(struct fm *fm);
105666 +
105667 +void *fm_get_handle(struct fm *fm);
105668 +void *fm_get_rtc_handle(struct fm *fm);
105669 +struct resource *fm_get_mem_region(struct fm *fm);
105670 +
105671 +/**************************************************************************//**
105672 + @Function fm_port_bind
105673 +
105674 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
105675 +
105676 + @Param[in] fm_port_dev - the OF handle of the FM port device.
105677 +
105678 + @Return A handle of the FM port device.
105679 +
105680 + @Cautions Allowed only after the port was created.
105681 +*//***************************************************************************/
105682 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
105683 +
105684 +/**************************************************************************//**
105685 + @Function fm_port_unbind
105686 +
105687 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
105688 +
105689 + @Param[in] port - A handle of the FM port device.
105690 +
105691 + @Cautions Allowed only after the port was created.
105692 +*//***************************************************************************/
105693 +void fm_port_unbind(struct fm_port *port);
105694 +
105695 +/**************************************************************************//**
105696 + @Function fm_set_rx_port_params
105697 +
105698 + @Description Configure parameters for a specific Rx FM-port device.
105699 +
105700 + @Param[in] port - A handle of the FM port device.
105701 + @Param[in] params - Rx port parameters
105702 +
105703 + @Cautions Allowed only after the port is binded.
105704 +*//***************************************************************************/
105705 +void fm_set_rx_port_params(struct fm_port *port,
105706 + struct fm_port_params *params);
105707 +
105708 +/**************************************************************************//**
105709 + @Function fm_port_pcd_bind
105710 +
105711 + @Description Bind as a listener on a port PCD.
105712 +
105713 + @Param[in] port - A handle of the FM port device.
105714 + @Param[in] params - PCD port parameters
105715 +
105716 + @Cautions Allowed only after the port is binded.
105717 +*//***************************************************************************/
105718 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
105719 +
105720 +/**************************************************************************//**
105721 + @Function fm_port_get_buff_layout_ext_params
105722 +
105723 + @Description Get data_align and manip_extra_space from the device tree
105724 + chosen node if applied.
105725 + This function will only update these two parameters.
105726 + When this port has no such parameters in the device tree
105727 + values will be set to 0.
105728 +
105729 + @Param[in] port - A handle of the FM port device.
105730 + @Param[in] params - PCD port parameters
105731 +
105732 + @Cautions Allowed only after the port is binded.
105733 +*//***************************************************************************/
105734 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
105735 +
105736 +/**************************************************************************//**
105737 + @Function fm_get_tx_port_channel
105738 +
105739 + @Description Get qman-channel number for this Tx port.
105740 +
105741 + @Param[in] port - A handle of the FM port device.
105742 +
105743 + @Return qman-channel number for this Tx port.
105744 +
105745 + @Cautions Allowed only after the port is binded.
105746 +*//***************************************************************************/
105747 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
105748 +
105749 +/**************************************************************************//**
105750 + @Function fm_set_tx_port_params
105751 +
105752 + @Description Configure parameters for a specific Tx FM-port device
105753 +
105754 + @Param[in] port - A handle of the FM port device.
105755 + @Param[in] params - Tx port parameters
105756 +
105757 + @Cautions Allowed only after the port is binded.
105758 +*//***************************************************************************/
105759 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
105760 +
105761 +
105762 +/**************************************************************************//**
105763 + @Function fm_mac_set_handle
105764 +
105765 + @Description Set mac handle
105766 +
105767 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
105768 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
105769 + @Param[in] mac_id - MAC id.
105770 +*//***************************************************************************/
105771 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
105772 + int mac_id);
105773 +
105774 +/**************************************************************************//**
105775 + @Function fm_port_enable
105776 +
105777 + @Description Enable specific FM-port device (may be Rx or Tx port).
105778 +
105779 + @Param[in] port - A handle of the FM port device.
105780 +
105781 + @Cautions Allowed only after the port is initialized.
105782 +*//***************************************************************************/
105783 +int fm_port_enable(struct fm_port *port);
105784 +
105785 +/**************************************************************************//**
105786 + @Function fm_port_disable
105787 +
105788 + @Description Disable specific FM-port device (may be Rx or Tx port).
105789 +
105790 + @Param[in] port - A handle of the FM port device.
105791 +
105792 + @Cautions Allowed only after the port is initialized.
105793 +*//***************************************************************************/
105794 +int fm_port_disable(struct fm_port *port);
105795 +
105796 +void *fm_port_get_handle(const struct fm_port *port);
105797 +
105798 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
105799 + const void *data);
105800 +
105801 +/**************************************************************************//**
105802 + @Function fm_port_get_base_address
105803 +
105804 + @Description Get base address of this port. Useful for accessing
105805 + port-specific registers (i.e., not common ones).
105806 +
105807 + @Param[in] port - A handle of the FM port device.
105808 +
105809 + @Param[out] base_addr - The port's base addr (virtual address).
105810 +*//***************************************************************************/
105811 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
105812 +
105813 +/**************************************************************************//**
105814 + @Function fm_mutex_lock
105815 +
105816 + @Description Lock function required before any FMD/LLD call.
105817 +*//***************************************************************************/
105818 +void fm_mutex_lock(void);
105819 +
105820 +/**************************************************************************//**
105821 + @Function fm_mutex_unlock
105822 +
105823 + @Description Unlock function required after any FMD/LLD call.
105824 +*//***************************************************************************/
105825 +void fm_mutex_unlock(void);
105826 +
105827 +/**************************************************************************//**
105828 + @Function fm_get_max_frm
105829 +
105830 + @Description Get the maximum frame size
105831 +*//***************************************************************************/
105832 +int fm_get_max_frm(void);
105833 +
105834 +/**************************************************************************//**
105835 + @Function fm_get_rx_extra_headroom
105836 +
105837 + @Description Get the extra headroom size
105838 +*//***************************************************************************/
105839 +int fm_get_rx_extra_headroom(void);
105840 +
105841 +/**************************************************************************//**
105842 +@Function fm_port_set_rate_limit
105843 +
105844 +@Description Configure Shaper parameter on FM-port device (Tx port).
105845 +
105846 +@Param[in] port - A handle of the FM port device.
105847 +@Param[in] max_burst_size - Value of maximum burst size allowed.
105848 +@Param[in] rate_limit - The required rate value.
105849 +
105850 +@Cautions Allowed only after the port is initialized.
105851 +*//***************************************************************************/
105852 +int fm_port_set_rate_limit(struct fm_port *port,
105853 + uint16_t max_burst_size,
105854 + uint32_t rate_limit);
105855 +/**************************************************************************//**
105856 +@Function fm_port_set_rate_limit
105857 +
105858 +@Description Delete Shaper configuration on FM-port device (Tx port).
105859 +
105860 +@Param[in] port - A handle of the FM port device.
105861 +
105862 +@Cautions Allowed only after the port is initialized.
105863 +*//***************************************************************************/
105864 +int fm_port_del_rate_limit(struct fm_port *port);
105865 +
105866 +struct auto_res_tables_sizes
105867 +{
105868 + uint16_t max_num_of_arp_entries;
105869 + uint16_t max_num_of_echo_ipv4_entries;
105870 + uint16_t max_num_of_ndp_entries;
105871 + uint16_t max_num_of_echo_ipv6_entries;
105872 + uint16_t max_num_of_snmp_ipv4_entries;
105873 + uint16_t max_num_of_snmp_ipv6_entries;
105874 + uint16_t max_num_of_snmp_oid_entries;
105875 + uint16_t max_num_of_snmp_char; /* total amount of character needed
105876 + for the snmp table */
105877 + uint16_t max_num_of_ip_prot_filtering;
105878 + uint16_t max_num_of_tcp_port_filtering;
105879 + uint16_t max_num_of_udp_port_filtering;
105880 +};
105881 +/* ARP */
105882 +struct auto_res_arp_entry
105883 +{
105884 + uint32_t ip_address;
105885 + uint8_t mac[6];
105886 + bool is_vlan;
105887 + uint16_t vid;
105888 +};
105889 +struct auto_res_arp_info
105890 +{
105891 + uint8_t table_size;
105892 + struct auto_res_arp_entry *auto_res_table;
105893 + bool enable_conflict_detection; /* when TRUE
105894 + Conflict Detection will be checked and wake the host if
105895 + needed */
105896 +};
105897 +
105898 +/* NDP */
105899 +struct auto_res_ndp_entry
105900 +{
105901 + uint32_t ip_address[4];
105902 + uint8_t mac[6];
105903 + bool is_vlan;
105904 + uint16_t vid;
105905 +};
105906 +struct auto_res_ndp_info
105907 +{
105908 + uint32_t multicast_group;
105909 + uint8_t table_size_assigned;
105910 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
105911 + refer to solicitation IP addresses. Note that all IP adresses
105912 + must be from the same multicast group. This will be checked and
105913 + if not operation will fail. */
105914 + uint8_t table_size_tmp;
105915 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
105916 + refer to temp IP addresses. Note that all temp IP adresses must
105917 + be from the same multicast group. This will be checked and if
105918 + not operation will fail. */
105919 +
105920 + bool enable_conflict_detection; /* when TRUE
105921 + Conflict Detection will be checked and wake the host if
105922 + needed */
105923 +};
105924 +
105925 +/* ICMP ECHO */
105926 +struct auto_res_echo_ipv4_info
105927 +{
105928 + uint8_t table_size;
105929 + struct auto_res_arp_entry *auto_res_table;
105930 +};
105931 +
105932 +struct auto_res_echo_ipv6_info
105933 +{
105934 + uint8_t table_size;
105935 + struct auto_res_ndp_entry *auto_res_table;
105936 +};
105937 +
105938 +/* SNMP */
105939 +struct auto_res_snmp_entry
105940 +{
105941 + uint16_t oidSize;
105942 + uint8_t *oidVal; /* only the oid string */
105943 + uint16_t resSize;
105944 + uint8_t *resVal; /* resVal will be the entire reply,
105945 + i.e. "Type|Length|Value" */
105946 +};
105947 +
105948 +/**************************************************************************//**
105949 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
105950 + Refer to the FMan Controller spec for more details.
105951 +*//***************************************************************************/
105952 +struct auto_res_snmp_ipv4addr_tbl_entry
105953 +{
105954 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
105955 + bool is_vlan;
105956 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
105957 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
105958 +};
105959 +
105960 +/**************************************************************************//**
105961 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
105962 + Refer to the FMan Controller spec for more details.
105963 +*//***************************************************************************/
105964 +struct auto_res_snmp_ipv6addr_tbl_entry
105965 +{
105966 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
105967 + bool isVlan;
105968 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
105969 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
105970 +};
105971 +
105972 +struct auto_res_snmp_info
105973 +{
105974 + uint16_t control; /**< Control bits [0-15]. */
105975 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
105976 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
105977 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
105978 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
105979 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
105980 + char *community_read_write_string;
105981 + char *community_read_only_string;
105982 + struct auto_res_snmp_entry *oid_table;
105983 + uint32_t oid_table_size;
105984 + uint32_t *statistics;
105985 +};
105986 +
105987 +/* Filtering */
105988 +struct auto_res_port_filtering_entry
105989 +{
105990 + uint16_t src_port;
105991 + uint16_t dst_port;
105992 + uint16_t src_port_mask;
105993 + uint16_t dst_port_mask;
105994 +};
105995 +struct auto_res_filtering_info
105996 +{
105997 + /* IP protocol filtering parameters */
105998 + uint8_t ip_prot_table_size;
105999 + uint8_t *ip_prot_table_ptr;
106000 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
106001 + cause the packet to be droped, hit will pass the packet to
106002 + UDP/TCP filters if needed and if not to the classification
106003 + tree. If the classification tree will pass the packet to a
106004 + queue it will cause a wake interupt. When FALSE it the other
106005 + way around. */
106006 + /* UDP port filtering parameters */
106007 + uint8_t udp_ports_table_size;
106008 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
106009 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
106010 + cause the packet to be droped, hit will pass the packet to
106011 + classification tree. If the classification tree will pass the
106012 + packet to a queue it will cause a wake interupt. When FALSE it
106013 + the other way around. */
106014 + /* TCP port filtering parameters */
106015 + uint16_t tcp_flags_mask;
106016 + uint8_t tcp_ports_table_size;
106017 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
106018 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
106019 + cause the packet to be droped, hit will pass the packet to
106020 + classification tree. If the classification tree will pass the
106021 + packet to a queue it will cause a wake interupt. When FALSE it
106022 + the other way around. */
106023 +};
106024 +
106025 +struct auto_res_port_params
106026 +{
106027 + t_Handle h_FmPortTx;
106028 + struct auto_res_arp_info *p_auto_res_arp_info;
106029 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
106030 + struct auto_res_ndp_info *p_auto_res_ndp_info;
106031 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
106032 + struct auto_res_snmp_info *p_auto_res_snmp_info;
106033 + struct auto_res_filtering_info *p_auto_res_filtering_info;
106034 +};
106035 +
106036 +struct auto_res_port_stats
106037 +{
106038 + uint32_t arp_ar_cnt;
106039 + uint32_t echo_icmpv4_ar_cnt;
106040 + uint32_t ndp_ar_cnt;
106041 + uint32_t echo_icmpv6_ar_cnt;
106042 +};
106043 +
106044 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
106045 + struct auto_res_tables_sizes *params);
106046 +
106047 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
106048 + struct auto_res_port_params *params);
106049 +
106050 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
106051 + struct fm_port *port_tx);
106052 +
106053 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
106054 +
106055 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
106056 + struct fm_port *port);
106057 +
106058 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
106059 + *stats);
106060 +
106061 +int fm_port_resume(struct fm_port *port);
106062 +
106063 +int fm_port_suspend(struct fm_port *port);
106064 +
106065 +#ifdef CONFIG_FMAN_PFC
106066 +/**************************************************************************//**
106067 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
106068 +
106069 +@Description Associate a QMan Work Queue with a PFC priority on this
106070 + FM-port device (Tx port).
106071 +
106072 +@Param[in] port - A handle of the FM port device.
106073 +
106074 +@Param[in] prio - The PFC priority.
106075 +
106076 +@Param[in] wq - The Work Queue associated with the PFC priority.
106077 +
106078 +@Cautions Allowed only after the port is initialized.
106079 +*//***************************************************************************/
106080 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
106081 + uint8_t prio, uint8_t wq);
106082 +#endif
106083 +
106084 +/**************************************************************************//**
106085 +@Function fm_mac_set_exception
106086 +
106087 +@Description Set MAC exception state.
106088 +
106089 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
106090 +@Param[in] exception - FM MAC exception type.
106091 +@Param[in] enable - new state.
106092 +
106093 +*//***************************************************************************/
106094 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
106095 + e_FmMacExceptions exception, bool enable);
106096 +
106097 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
106098 +
106099 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
106100 +
106101 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
106102 + int len);
106103 +
106104 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
106105 +
106106 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
106107 +
106108 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
106109 +
106110 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
106111 +
106112 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
106113 +
106114 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
106115 +
106116 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
106117 +
106118 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
106119 +
106120 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
106121 + bool enable);
106122 +
106123 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
106124 + t_EnetAddr *mac_addr);
106125 +
106126 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
106127 + t_EnetAddr *mac_addr);
106128 +
106129 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
106130 + uint8_t *addr);
106131 +
106132 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
106133 + bool link, int speed, bool duplex);
106134 +
106135 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
106136 +
106137 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
106138 +
106139 +int fm_mac_set_rx_pause_frames(
106140 + struct fm_mac_dev *fm_mac_dev, bool en);
106141 +
106142 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
106143 + bool en);
106144 +
106145 +int fm_rtc_enable(struct fm *fm_dev);
106146 +
106147 +int fm_rtc_disable(struct fm *fm_dev);
106148 +
106149 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
106150 +
106151 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
106152 +
106153 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
106154 +
106155 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
106156 +
106157 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
106158 + uint64_t time);
106159 +
106160 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
106161 + uint64_t fiper);
106162 +
106163 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
106164 + bool en);
106165 +
106166 +/**************************************************************************//**
106167 +@Function fm_macsec_set_exception
106168 +
106169 +@Description Set MACSEC exception state.
106170 +
106171 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
106172 +@Param[in] exception - FM MACSEC exception type.
106173 +@Param[in] enable - new state.
106174 +
106175 +*//***************************************************************************/
106176 +
106177 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
106178 + fm_macsec_exception exception, bool enable);
106179 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
106180 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
106181 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
106182 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
106183 + *fm_macsec_dev,
106184 + fm_macsec_unknown_sci_frame_treatment treat_mode);
106185 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
106186 + bool deliver_uncontrolled);
106187 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
106188 + bool discard_uncontrolled);
106189 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
106190 + fm_macsec_untag_frame_treatment treat_mode);
106191 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
106192 + uint32_t pnExhThr);
106193 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
106194 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
106195 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
106196 + fm_macsec_exception exception, bool enable);
106197 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
106198 + int *macsec_revision);
106199 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
106200 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
106201 +
106202 +
106203 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106204 + fm_macsec_secy_exception exception,
106205 + bool enable);
106206 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
106207 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
106208 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
106209 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106210 + fm_macsec_sci_insertion_mode sci_insertion_mode);
106211 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106212 + bool protect_frames);
106213 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106214 + bool replay_protect, uint32_t replay_window);
106215 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106216 + fm_macsec_valid_frame_behavior validate_frames);
106217 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106218 + bool confidentiality_enable,
106219 + uint32_t confidentiality_offset);
106220 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
106221 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106222 + fm_macsec_secy_event event,
106223 + bool enable);
106224 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106225 + struct fm_macsec_secy_sc_params *params);
106226 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106227 + struct rx_sc_dev *sc);
106228 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106229 + struct rx_sc_dev *sc, macsec_an_t an,
106230 + uint32_t lowest_pn, macsec_sa_key_t key);
106231 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106232 + struct rx_sc_dev *sc, macsec_an_t an);
106233 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106234 + struct rx_sc_dev *sc,
106235 + macsec_an_t an);
106236 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106237 + struct rx_sc_dev *sc,
106238 + macsec_an_t an);
106239 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106240 + struct rx_sc_dev *sc,
106241 + macsec_an_t an, uint32_t updt_next_pn);
106242 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106243 + struct rx_sc_dev *sc,
106244 + macsec_an_t an, uint32_t updt_lowest_pn);
106245 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106246 + struct rx_sc_dev *sc,
106247 + macsec_an_t an, macsec_sa_key_t key);
106248 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106249 + macsec_an_t an, macsec_sa_key_t key);
106250 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106251 + macsec_an_t an);
106252 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106253 + macsec_an_t next_active_an,
106254 + macsec_sa_key_t key);
106255 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106256 + macsec_an_t an);
106257 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106258 + macsec_an_t *p_an);
106259 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106260 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
106261 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106262 + uint32_t *sc_phys_id);
106263 +
106264 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
106265 +/** @} */ /* end of FM_LnxKern_grp group */
106266 +
106267 +/* default values for initializing PTP 1588 timer clock */
106268 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
106269 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
106270 +
106271 +#endif /* __LNXWRP_FSL_FMAN_H */
106272 --- /dev/null
106273 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
106274 @@ -0,0 +1,50 @@
106275 +/*
106276 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106277 + *
106278 + * Redistribution and use in source and binary forms, with or without
106279 + * modification, are permitted provided that the following conditions are met:
106280 + * * Redistributions of source code must retain the above copyright
106281 + * notice, this list of conditions and the following disclaimer.
106282 + * * Redistributions in binary form must reproduce the above copyright
106283 + * notice, this list of conditions and the following disclaimer in the
106284 + * documentation and/or other materials provided with the distribution.
106285 + * * Neither the name of Freescale Semiconductor nor the
106286 + * names of its contributors may be used to endorse or promote products
106287 + * derived from this software without specific prior written permission.
106288 + *
106289 + *
106290 + * ALTERNATIVELY, this software may be distributed under the terms of the
106291 + * GNU General Public License ("GPL") as published by the Free Software
106292 + * Foundation, either version 2 of that License or (at your option) any
106293 + * later version.
106294 + *
106295 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106296 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106297 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106298 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106299 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106300 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106301 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106302 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106303 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106304 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106305 + */
106306 +
106307 +#ifndef __XX_H
106308 +#define __XX_H
106309 +
106310 +#include "xx_ext.h"
106311 +
106312 +void * xx_Malloc(uint32_t n);
106313 +void xx_Free(void *p);
106314 +
106315 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
106316 +void xx_FreeSmart(void *p);
106317 +
106318 +/* never used: */
106319 +#define GetDeviceName(irq) ((char *)NULL)
106320 +
106321 +int GetDeviceIrqNum(int irq);
106322 +
106323 +
106324 +#endif /* __XX_H */
106325 --- /dev/null
106326 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
106327 @@ -0,0 +1,10 @@
106328 +#
106329 +# Makefile for the Freescale Ethernet controllers
106330 +#
106331 +ccflags-y += -DVERSION=\"\"
106332 +#
106333 +#Include netcomm SW specific definitions
106334 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
106335 +#
106336 +
106337 +obj-y += sys_io.o
106338 --- /dev/null
106339 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
106340 @@ -0,0 +1,171 @@
106341 +/*
106342 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106343 + *
106344 + * Redistribution and use in source and binary forms, with or without
106345 + * modification, are permitted provided that the following conditions are met:
106346 + * * Redistributions of source code must retain the above copyright
106347 + * notice, this list of conditions and the following disclaimer.
106348 + * * Redistributions in binary form must reproduce the above copyright
106349 + * notice, this list of conditions and the following disclaimer in the
106350 + * documentation and/or other materials provided with the distribution.
106351 + * * Neither the name of Freescale Semiconductor nor the
106352 + * names of its contributors may be used to endorse or promote products
106353 + * derived from this software without specific prior written permission.
106354 + *
106355 + *
106356 + * ALTERNATIVELY, this software may be distributed under the terms of the
106357 + * GNU General Public License ("GPL") as published by the Free Software
106358 + * Foundation, either version 2 of that License or (at your option) any
106359 + * later version.
106360 + *
106361 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106362 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106363 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106364 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106365 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106366 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106367 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106368 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106369 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106370 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106371 + */
106372 +
106373 +#include <linux/version.h>
106374 +
106375 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
106376 +#define MODVERSIONS
106377 +#endif
106378 +#ifdef MODVERSIONS
106379 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
106380 +#include <linux/modversions.h>
106381 +#else
106382 +#include <config/modversions.h>
106383 +#endif /* LINUX_VERSION_CODE */
106384 +#endif /* MODVERSIONS */
106385 +
106386 +#include <linux/module.h>
106387 +#include <linux/kernel.h>
106388 +
106389 +#include <asm/io.h>
106390 +
106391 +#include "std_ext.h"
106392 +#include "error_ext.h"
106393 +#include "string_ext.h"
106394 +#include "list_ext.h"
106395 +#include "sys_io_ext.h"
106396 +
106397 +
106398 +#define __ERR_MODULE__ MODULE_UNKNOWN
106399 +
106400 +
106401 +typedef struct {
106402 + uint64_t virtAddr;
106403 + uint64_t physAddr;
106404 + uint32_t size;
106405 + t_List node;
106406 +} t_IoMap;
106407 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
106408 +
106409 +LIST(mapsList);
106410 +
106411 +
106412 +static void EnqueueIoMap(t_IoMap *p_IoMap)
106413 +{
106414 + uint32_t intFlags;
106415 +
106416 + intFlags = XX_DisableAllIntr();
106417 + LIST_AddToTail(&p_IoMap->node, &mapsList);
106418 + XX_RestoreAllIntr(intFlags);
106419 +}
106420 +
106421 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
106422 +{
106423 + t_IoMap *p_IoMap;
106424 + t_List *p_Pos;
106425 +
106426 + LIST_FOR_EACH(p_Pos, &mapsList)
106427 + {
106428 + p_IoMap = IOMAP_OBJECT(p_Pos);
106429 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
106430 + return p_IoMap;
106431 + }
106432 +
106433 + return NULL;
106434 +}
106435 +
106436 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
106437 +{
106438 + t_IoMap *p_IoMap;
106439 + t_List *p_Pos;
106440 +
106441 + LIST_FOR_EACH(p_Pos, &mapsList)
106442 + {
106443 + p_IoMap = IOMAP_OBJECT(p_Pos);
106444 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
106445 + return p_IoMap;
106446 + }
106447 +
106448 + return NULL;
106449 +}
106450 +
106451 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
106452 +{
106453 + t_IoMap *p_IoMap;
106454 +
106455 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
106456 + if (!p_IoMap)
106457 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
106458 + memset(p_IoMap, 0, sizeof(t_IoMap));
106459 +
106460 + p_IoMap->virtAddr = virtAddr;
106461 + p_IoMap->physAddr = physAddr;
106462 + p_IoMap->size = size;
106463 +
106464 + INIT_LIST(&p_IoMap->node);
106465 + EnqueueIoMap(p_IoMap);
106466 +
106467 + return E_OK;
106468 +}
106469 +
106470 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
106471 +{
106472 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
106473 + if (!p_IoMap)
106474 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
106475 +
106476 + LIST_Del(&p_IoMap->node);
106477 + XX_Free(p_IoMap);
106478 +
106479 + return E_OK;
106480 +}
106481 +
106482 +uint64_t SYS_PhysToVirt(uint64_t addr)
106483 +{
106484 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
106485 + if (p_IoMap)
106486 + {
106487 + /* This is optimization - put the latest in the list-head - like a cache */
106488 + if (mapsList.p_Next != &p_IoMap->node)
106489 + {
106490 + uint32_t intFlags = XX_DisableAllIntr();
106491 + LIST_DelAndInit(&p_IoMap->node);
106492 + LIST_Add(&p_IoMap->node, &mapsList);
106493 + XX_RestoreAllIntr(intFlags);
106494 + }
106495 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
106496 + }
106497 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
106498 +}
106499 +
106500 +uint64_t SYS_VirtToPhys(uint64_t addr)
106501 +{
106502 + t_IoMap *p_IoMap;
106503 +
106504 + if (addr == 0)
106505 + return 0;
106506 +
106507 + p_IoMap = FindIoMapByVirtAddr(addr);
106508 + if (p_IoMap)
106509 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
106510 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
106511 +}
106512 --- /dev/null
106513 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
106514 @@ -0,0 +1,19 @@
106515 +#
106516 +# Makefile for the Freescale Ethernet controllers
106517 +#
106518 +ccflags-y += -DVERSION=\"\"
106519 +#
106520 +#Include netcomm SW specific definitions
106521 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
106522 +
106523 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
106524 +
106525 +ccflags-y += -I$(NCSW_FM_INC)
106526 +ccflags-y += -I$(NET_DPA)
106527 +
106528 +obj-y += fsl-ncsw-PFM.o
106529 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
106530 +
106531 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
106532 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
106533 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
106534 --- /dev/null
106535 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
106536 @@ -0,0 +1,1665 @@
106537 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
106538 + * All rights reserved.
106539 + *
106540 + * Redistribution and use in source and binary forms, with or without
106541 + * modification, are permitted provided that the following conditions are met:
106542 + * * Redistributions of source code must retain the above copyright
106543 + * notice, this list of conditions and the following disclaimer.
106544 + * * Redistributions in binary form must reproduce the above copyright
106545 + * notice, this list of conditions and the following disclaimer in the
106546 + * documentation and/or other materials provided with the distribution.
106547 + * * Neither the name of Freescale Semiconductor nor the
106548 + * names of its contributors may be used to endorse or promote products
106549 + * derived from this software without specific prior written permission.
106550 + *
106551 + *
106552 + * ALTERNATIVELY, this software may be distributed under the terms of the
106553 + * GNU General Public License ("GPL") as published by the Free Software
106554 + * Foundation, either version 2 of that License or (at your option) any
106555 + * later version.
106556 + *
106557 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106558 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106559 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106560 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106561 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106562 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106563 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106564 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106565 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106566 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106567 + */
106568 +
106569 +/*
106570 + @File fman_test.c
106571 + @Authors Pistirica Sorin Andrei
106572 + @Description FM Linux test environment
106573 +*/
106574 +
106575 +#include <linux/kernel.h>
106576 +#include <linux/module.h>
106577 +#include <linux/fs.h>
106578 +#include <linux/cdev.h>
106579 +#include <linux/device.h>
106580 +#include <linux/io.h>
106581 +#include <linux/ioport.h>
106582 +#include <linux/of_platform.h>
106583 +#include <linux/ip.h>
106584 +#include <linux/compat.h>
106585 +#include <linux/uaccess.h>
106586 +#include <linux/errno.h>
106587 +#include <linux/netdevice.h>
106588 +#include <linux/spinlock.h>
106589 +#include <linux/types.h>
106590 +#include <linux/fsl_qman.h>
106591 +#include <linux/fsl_bman.h>
106592 +
106593 +/* private headers */
106594 +#include "fm_ext.h"
106595 +#include "lnxwrp_fsl_fman.h"
106596 +#include "fm_port_ext.h"
106597 +#if (DPAA_VERSION == 11)
106598 +#include "../../Peripherals/FM/MAC/memac.h"
106599 +#endif
106600 +#include "fm_test_ioctls.h"
106601 +#include "fsl_fman_test.h"
106602 +
106603 +#include "dpaa_eth.h"
106604 +#include "dpaa_eth_common.h"
106605 +
106606 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
106607 +
106608 +struct fmt_frame_s {
106609 + ioc_fmt_buff_desc_t buff;
106610 + struct list_head list;
106611 +};
106612 +
106613 +struct fmt_fqs_s {
106614 + struct qman_fq fq_base;
106615 + bool init;
106616 + struct fmt_port_s *fmt_port_priv;
106617 +};
106618 +
106619 +struct fmt_port_pcd_s {
106620 + int num_queues;
106621 + struct fmt_fqs_s *fmt_pcd_fqs;
106622 + uint32_t fqid_base;
106623 +};
106624 +
106625 +/* char dev structure: fm test port */
106626 +struct fmt_port_s {
106627 + bool valid;
106628 + uint8_t id;
106629 + ioc_fmt_port_type port_type;
106630 + ioc_diag_mode diag;
106631 + bool compat_test_type;
106632 +
106633 + /* fm ports */
106634 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
106635 + * p_tx_port == p_rx_port */
106636 + /* t_LnxWrpFmPortDev */
106637 + struct fm_port *p_tx_port;
106638 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
106639 + void *p_tx_fm_port_dev;
106640 + /* t_LnxWrpFmPortDev */
106641 + struct fm_port *p_rx_port;
106642 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
106643 + void *p_rx_fm_port_dev;
106644 +
106645 + void *p_mac_dev;
106646 + uint64_t fm_phys_base_addr;
106647 +
106648 + /* read/write queue manipulation */
106649 + spinlock_t rx_q_lock;
106650 + struct list_head rx_q;
106651 +
106652 + /* tx queuee for injecting traffic */
106653 + int num_of_tx_fqs;
106654 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
106655 +
106656 + /* pcd private queues manipulation */
106657 + struct fmt_port_pcd_s fmt_port_pcd;
106658 +
106659 + /* debugging stuff */
106660 +
106661 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106662 + atomic_t enqueue_to_qman_frm;
106663 + atomic_t enqueue_to_rxq;
106664 + atomic_t dequeue_from_rxq;
106665 + atomic_t not_enqueue_to_rxq_wrong_frm;
106666 +#endif
106667 +
106668 +};
106669 +
106670 +/* The devices. */
106671 +struct fmt_s {
106672 + int major;
106673 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
106674 + struct class *fmt_class;
106675 +};
106676 +
106677 +/* fm test structure */
106678 +static struct fmt_s fm_test;
106679 +
106680 +#if (DPAA_VERSION == 11)
106681 +struct mac_priv_s {
106682 + t_Handle mac;
106683 +};
106684 +#endif
106685 +
106686 +#define DTSEC_BASE_ADDR 0x000e0000
106687 +#define DTSEC_MEM_RANGE 0x00002000
106688 +#define MAC_1G_MACCFG1 0x00000100
106689 +#define MAC_1G_LOOP_MASK 0x00000100
106690 +static int set_1gmac_loopback(
106691 + struct fmt_port_s *fmt_port,
106692 + bool en)
106693 +{
106694 +#if (DPAA_VERSION <= 10)
106695 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
106696 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
106697 + phys_addr_t maccfg1_hw;
106698 + void *maccfg1_map;
106699 + uint32_t maccfg1_val;
106700 +
106701 + /* compute the maccfg1 register address */
106702 + maccfg1_hw = fmt_port->fm_phys_base_addr +
106703 + (phys_addr_t)(DTSEC_BASE_ADDR +
106704 + dtsec_idx_off +
106705 + MAC_1G_MACCFG1);
106706 +
106707 + /* map register */
106708 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
106709 +
106710 + /* set register */
106711 + maccfg1_val = in_be32(maccfg1_map);
106712 + if (en)
106713 + maccfg1_val |= MAC_1G_LOOP_MASK;
106714 + else
106715 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
106716 + out_be32(maccfg1_map, maccfg1_val);
106717 +
106718 + /* unmap register */
106719 + iounmap(maccfg1_map);
106720 +#else
106721 + struct mac_device *mac_dev;
106722 + struct mac_priv_s *priv;
106723 + t_Memac *p_memac;
106724 +
106725 + if (!fmt_port)
106726 + return -EINVAL;
106727 +
106728 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
106729 +
106730 + if (!mac_dev)
106731 + return -EINVAL;
106732 +
106733 + priv = macdev_priv(mac_dev);
106734 +
106735 + if (!priv)
106736 + return -EINVAL;
106737 +
106738 + p_memac = priv->mac;
106739 +
106740 + if (!p_memac)
106741 + return -EINVAL;
106742 +
106743 + memac_set_loopback(p_memac->p_MemMap, en);
106744 +#endif
106745 + return 0;
106746 +}
106747 +
106748 +/* TODO: re-write this function */
106749 +static int set_10gmac_int_loopback(
106750 + struct fmt_port_s *fmt_port,
106751 + bool en)
106752 +{
106753 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
106754 +#define FM_10GMAC0_OFFSET 0x000f0000
106755 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
106756 +#define CMD_CFG_LOOPBACK_EN 0x00000400
106757 +
106758 + uint64_t base_addr, reg_addr;
106759 + uint32_t tmp_val;
106760 +
106761 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
106762 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
106763 +
106764 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
106765 +
106766 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
106767 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
106768 + if (en)
106769 + tmp_val |= CMD_CFG_LOOPBACK_EN;
106770 + else
106771 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
106772 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
106773 +
106774 + iounmap(UINT_TO_PTR(base_addr));
106775 +
106776 + return 0;
106777 +#else
106778 + _fmt_err("TGEC don't have internal-loopback.\n");
106779 + return -EPERM;
106780 +#endif
106781 +}
106782 +
106783 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
106784 +{
106785 + int _err = 0;
106786 +
106787 + switch (fmt_port->port_type) {
106788 +
106789 + case e_IOC_FMT_PORT_T_RXTX:
106790 + /* 1G port */
106791 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
106792 + _err = set_1gmac_loopback(fmt_port, en);
106793 + /* 10g port */
106794 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
106795 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
106796 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
106797 +
106798 + _err = set_10gmac_int_loopback(fmt_port, en);
106799 + } else
106800 + _err = -EINVAL;
106801 + break;
106802 + /* op port does not have MAC (loopback mode) */
106803 + case e_IOC_FMT_PORT_T_OP:
106804 +
106805 + _err = 0;
106806 + break;
106807 + default:
106808 +
106809 + _err = -EPERM;
106810 + break;
106811 + }
106812 +
106813 + return _err;
106814 +}
106815 +
106816 +static void enqueue_fmt_frame(
106817 + struct fmt_port_s *fmt_port,
106818 + struct fmt_frame_s *p_fmt_frame)
106819 +{
106820 + spinlock_t *rx_q_lock = NULL;
106821 +
106822 + rx_q_lock = &fmt_port->rx_q_lock;
106823 +
106824 + spin_lock(rx_q_lock);
106825 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
106826 + spin_unlock(rx_q_lock);
106827 +
106828 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106829 + atomic_inc(&fmt_port->enqueue_to_rxq);
106830 +#endif
106831 +}
106832 +
106833 +static struct fmt_frame_s *dequeue_fmt_frame(
106834 + struct fmt_port_s *fmt_port)
106835 +{
106836 + struct fmt_frame_s *p_fmt_frame = NULL;
106837 + spinlock_t *rx_q_lock = NULL;
106838 +
106839 + rx_q_lock = &fmt_port->rx_q_lock;
106840 +
106841 + spin_lock(rx_q_lock);
106842 +
106843 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
106844 +
106845 + if (!list_empty(&fmt_port->rx_q)) {
106846 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
106847 + struct fmt_frame_s,
106848 + list);
106849 + list_del(&p_fmt_frame->list);
106850 +
106851 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106852 + atomic_inc(&fmt_port->dequeue_from_rxq);
106853 +#endif
106854 + }
106855 +
106856 + spin_unlock(rx_q_lock);
106857 +
106858 + return p_fmt_frame;
106859 +}
106860 +
106861 +/* eth-dev -to- fmt port association */
106862 +struct fmt_port_s *match_dpa_to_fmt_port(
106863 + struct dpa_priv_s *dpa_priv) {
106864 + struct mac_device *mac_dev = dpa_priv->mac_dev;
106865 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
106866 + struct fmt_port_s *fmt_port = NULL;
106867 + int i;
106868 +
106869 + _fmt_dbgr("calling...\n");
106870 +
106871 + /* find the FM-test-port object */
106872 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
106873 + if ((fm_test.ports[i].p_mac_dev &&
106874 + mac_dev == fm_test.ports[i].p_mac_dev) ||
106875 + fm_port == fm_test.ports[i].p_tx_port) {
106876 +
106877 + fmt_port = &fm_test.ports[i];
106878 + break;
106879 + }
106880 +
106881 + _fmt_dbgr("called\n");
106882 + return fmt_port;
106883 +}
106884 +
106885 +void dump_frame(
106886 + uint8_t *buffer,
106887 + uint32_t size)
106888 +{
106889 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106890 + unsigned int i;
106891 +
106892 + for (i = 0; i < size; i++) {
106893 + if (i%16 == 0)
106894 + printk(KERN_DEBUG "\n");
106895 + printk(KERN_DEBUG "%2x ", *(buffer+i));
106896 + }
106897 +#endif
106898 + return;
106899 +}
106900 +
106901 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
106902 + uint32_t fqid,
106903 + uint8_t *buffer,
106904 + uint32_t size)
106905 +{
106906 + struct fmt_frame_s *p_fmt_frame = NULL;
106907 + bool test_and_steal_frame_frame;
106908 + uint32_t data_offset;
106909 + uint32_t i;
106910 +
106911 + _fmt_dbgr("calling...\n");
106912 +
106913 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
106914 + return false;
106915 +
106916 + /* check watermark */
106917 + test_and_steal_frame_frame = false;
106918 + for (i = 0; i < size; i++) {
106919 + uint64_t temp = *((uint64_t *)(buffer + i));
106920 +
106921 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
106922 + _fmt_dbgr("watermark found!\n");
106923 + test_and_steal_frame_frame = true;
106924 + break;
106925 + }
106926 + }
106927 +
106928 + if (!test_and_steal_frame_frame) {
106929 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106930 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
106931 +#endif
106932 + _fmt_dbgr("NOT watermark found!\n");
106933 + return false;
106934 + }
106935 +
106936 + /* do not enqueue the tx conf/err frames */
106937 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
106938 + goto _test_and_steal_frame_return_true;
106939 +
106940 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
106941 + data_offset = FM_PORT_GetBufferDataOffset(
106942 + fmt_port->p_rx_fm_port_dev);
106943 +
106944 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
106945 +
106946 + /* dump frame... no more space left on device */
106947 + if (p_fmt_frame == NULL) {
106948 + _fmt_err("no space left on device!\n");
106949 + goto _test_and_steal_frame_return_true;
106950 + }
106951 +
106952 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
106953 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
106954 +
106955 + /* No more space left on device*/
106956 + if (p_fmt_frame->buff.p_data == NULL) {
106957 + _fmt_err("no space left on device!\n");
106958 + kfree(p_fmt_frame);
106959 + goto _test_and_steal_frame_return_true;
106960 + }
106961 +
106962 + p_fmt_frame->buff.size = size-data_offset;
106963 + p_fmt_frame->buff.qid = fqid;
106964 +
106965 + memcpy(p_fmt_frame->buff.p_data,
106966 + (uint8_t *)PTR_MOVE(buffer, data_offset),
106967 + p_fmt_frame->buff.size);
106968 +
106969 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
106970 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
106971 + (char *)buffer),
106972 + 32);
106973 +
106974 + /* enqueue frame - this frame will go to us */
106975 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
106976 +
106977 +_test_and_steal_frame_return_true:
106978 + return true;
106979 +}
106980 +
106981 +static int fmt_fq_release(const struct qm_fd *fd)
106982 +{
106983 + struct dpa_bp *_dpa_bp;
106984 + struct bm_buffer _bmb;
106985 +
106986 + if (fd->format == qm_fd_contig) {
106987 + _dpa_bp = dpa_bpid2pool(fd->bpid);
106988 + BUG_ON(IS_ERR(_dpa_bp));
106989 +
106990 + _bmb.hi = fd->addr_hi;
106991 + _bmb.lo = fd->addr_lo;
106992 +
106993 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
106994 + cpu_relax();
106995 +
106996 + } else {
106997 + _fmt_err("frame not supported !\n");
106998 + return -1;
106999 + }
107000 +
107001 + return 0;
107002 +}
107003 +
107004 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
107005 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
107006 + fm_get_rx_extra_headroom() + \
107007 + DPA_PARSE_RESULTS_SIZE + \
107008 + DPA_HASH_RESULTS_SIZE)
107009 +#define MAC_HEADER_LENGTH 14
107010 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
107011 +
107012 +/* dpa ingress hooks definition */
107013 +enum dpaa_eth_hook_result fmt_rx_default_hook(
107014 + struct sk_buff *skb,
107015 + struct net_device *net_dev,
107016 + u32 fqid)
107017 +{
107018 + struct dpa_priv_s *dpa_priv = NULL;
107019 + struct fmt_port_s *fmt_port = NULL;
107020 + uint8_t *buffer;
107021 + uint32_t buffer_len;
107022 +
107023 + _fmt_dbgr("calling...\n");
107024 +
107025 + dpa_priv = netdev_priv(net_dev);
107026 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107027 +
107028 + /* conversion from skb to fd:
107029 + * skb cames processed for L3, so we need to go back for
107030 + * layer 2 offset */
107031 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
107032 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
107033 +
107034 + /* if is not out frame let dpa to handle it */
107035 + if (test_and_steal_frame(fmt_port,
107036 + FMT_RX_DFLT_Q,
107037 + buffer,
107038 + buffer_len))
107039 + goto _fmt_rx_default_hook_stolen;
107040 +
107041 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107042 + return DPAA_ETH_CONTINUE;
107043 +
107044 +_fmt_rx_default_hook_stolen:
107045 + dev_kfree_skb(skb);
107046 +
107047 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107048 + return DPAA_ETH_STOLEN;
107049 +}
107050 +
107051 +enum dpaa_eth_hook_result fmt_rx_error_hook(
107052 + struct net_device *net_dev,
107053 + const struct qm_fd *fd,
107054 + u32 fqid)
107055 +{
107056 + struct dpa_priv_s *dpa_priv = NULL;
107057 + struct dpa_bp *dpa_bp = NULL;
107058 + struct fmt_port_s *fmt_port = NULL;
107059 + void *fd_virt_addr = NULL;
107060 + dma_addr_t addr = qm_fd_addr(fd);
107061 +
107062 + _fmt_dbgr("calling...\n");
107063 +
107064 + dpa_priv = netdev_priv(net_dev);
107065 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107066 +
107067 + /* dpaa doesn't do this... we have to do it here */
107068 + dpa_bp = dpa_bpid2pool(fd->bpid);
107069 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
107070 +
107071 + fd_virt_addr = phys_to_virt(addr);
107072 + /* if is not out frame let dpa to handle it */
107073 + if (test_and_steal_frame(fmt_port,
107074 + FMT_RX_ERR_Q,
107075 + fd_virt_addr,
107076 + fd->length20 + fd->offset)) {
107077 + goto _fmt_rx_error_hook_stolen;
107078 + }
107079 +
107080 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107081 + return DPAA_ETH_CONTINUE;
107082 +
107083 +_fmt_rx_error_hook_stolen:
107084 + /* the frame data doesn't matter,
107085 + * so, no mapping is needed */
107086 + fmt_fq_release(fd);
107087 +
107088 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107089 + return DPAA_ETH_STOLEN;
107090 +}
107091 +
107092 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
107093 + struct net_device *net_dev,
107094 + const struct qm_fd *fd,
107095 + u32 fqid)
107096 +{
107097 + struct dpa_priv_s *dpa_priv = NULL;
107098 + struct fmt_port_s *fmt_port = NULL;
107099 + dma_addr_t addr = qm_fd_addr(fd);
107100 + void *fd_virt_addr = NULL;
107101 + uint32_t fd_len = 0;
107102 +
107103 + _fmt_dbgr("calling...\n");
107104 +
107105 + dpa_priv = netdev_priv(net_dev);
107106 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107107 +
107108 + fd_virt_addr = phys_to_virt(addr);
107109 + fd_len = fd->length20 + fd->offset;
107110 +
107111 + if (fd_len > fm_get_max_frm()) {
107112 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
107113 + goto _fmt_tx_confirm_hook_continue;
107114 + }
107115 +
107116 + if (test_and_steal_frame(fmt_port,
107117 + FMT_TX_CONF_Q,
107118 + fd_virt_addr,
107119 + fd_len))
107120 + goto _fmt_tx_confirm_hook_stolen;
107121 +
107122 +_fmt_tx_confirm_hook_continue:
107123 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107124 + return DPAA_ETH_CONTINUE;
107125 +
107126 +_fmt_tx_confirm_hook_stolen:
107127 + kfree(fd_virt_addr);
107128 +
107129 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107130 + return DPAA_ETH_STOLEN;
107131 +}
107132 +
107133 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
107134 + struct net_device *net_dev,
107135 + const struct qm_fd *fd,
107136 + u32 fqid)
107137 +{
107138 + struct dpa_priv_s *dpa_priv = NULL;
107139 + struct fmt_port_s *fmt_port = NULL;
107140 + dma_addr_t addr = qm_fd_addr(fd);
107141 + void *fd_virt_addr = NULL;
107142 + uint32_t fd_len = 0;
107143 +
107144 + _fmt_dbgr("calling...\n");
107145 +
107146 + dpa_priv = netdev_priv(net_dev);
107147 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107148 +
107149 + fd_virt_addr = phys_to_virt(addr);
107150 + fd_len = fd->length20 + fd->offset;
107151 +
107152 + if (fd_len > fm_get_max_frm()) {
107153 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
107154 + goto _priv_ingress_tx_err_continue;
107155 + }
107156 +
107157 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
107158 + goto _priv_ingress_tx_err_stolen;
107159 +
107160 +_priv_ingress_tx_err_continue:
107161 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107162 + return DPAA_ETH_CONTINUE;
107163 +
107164 +_priv_ingress_tx_err_stolen:
107165 + kfree(fd_virt_addr);
107166 +
107167 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107168 + return DPAA_ETH_STOLEN;
107169 +}
107170 +
107171 +/* egress callbacks definition */
107172 +enum qman_cb_dqrr_result fmt_egress_dqrr(
107173 + struct qman_portal *portal,
107174 + struct qman_fq *fq,
107175 + const struct qm_dqrr_entry *dqrr)
107176 +{
107177 + /* this callback should never be called */
107178 + BUG();
107179 + return qman_cb_dqrr_consume;
107180 +}
107181 +
107182 +static void fmt_egress_error_dqrr(
107183 + struct qman_portal *p,
107184 + struct qman_fq *fq,
107185 + const struct qm_mr_entry *msg)
107186 +{
107187 + uint8_t *fd_virt_addr = NULL;
107188 +
107189 + /* tx failure, on the ern callback - release buffer */
107190 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
107191 + kfree(fd_virt_addr);
107192 +
107193 + return;
107194 +}
107195 +
107196 +static const struct qman_fq fmt_egress_fq = {
107197 + .cb = { .dqrr = fmt_egress_dqrr,
107198 + .ern = fmt_egress_error_dqrr,
107199 + .fqs = NULL}
107200 +};
107201 +
107202 +int fmt_fq_alloc(
107203 + struct fmt_fqs_s *fmt_fqs,
107204 + const struct qman_fq *qman_fq,
107205 + uint32_t fqid, uint32_t flags,
107206 + uint16_t channel, uint8_t wq)
107207 +{
107208 + int _errno = 0;
107209 +
107210 + _fmt_dbg("calling...\n");
107211 +
107212 + fmt_fqs->fq_base = *qman_fq;
107213 +
107214 + if (fqid == 0) {
107215 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
107216 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
107217 + } else
107218 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
107219 +
107220 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
107221 +
107222 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
107223 + if (_errno < 0) {
107224 + _fmt_err("frame queues create failed.\n");
107225 + return -EINVAL;
107226 + }
107227 +
107228 + if (fmt_fqs->init) {
107229 + struct qm_mcc_initfq initfq;
107230 +
107231 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
107232 + initfq.fqd.dest.channel = channel;
107233 + initfq.fqd.dest.wq = wq;
107234 +
107235 + _errno = qman_init_fq(&fmt_fqs->fq_base,
107236 + QMAN_INITFQ_FLAG_SCHED,
107237 + &initfq);
107238 + if (_errno < 0) {
107239 + _fmt_err("frame queues init erorr.\n");
107240 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
107241 + return -EINVAL;
107242 + }
107243 + }
107244 +
107245 + _fmt_dbg("called.\n");
107246 + return 0;
107247 +}
107248 +
107249 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
107250 +{
107251 + int _err = 0;
107252 +
107253 + _fmt_dbg("calling...\n");
107254 +
107255 + if (fmt_fq->init) {
107256 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
107257 + if (unlikely(_err < 0))
107258 + _fmt_err("qman_retire_fq(%u) = %d\n",
107259 + qman_fq_fqid(&fmt_fq->fq_base), _err);
107260 +
107261 + _err = qman_oos_fq(&fmt_fq->fq_base);
107262 + if (unlikely(_err < 0))
107263 + _fmt_err("qman_oos_fq(%u) = %d\n",
107264 + qman_fq_fqid(&fmt_fq->fq_base), _err);
107265 + }
107266 +
107267 + qman_destroy_fq(&fmt_fq->fq_base, 0);
107268 +
107269 + _fmt_dbg("called.\n");
107270 + return _err;
107271 +}
107272 +
107273 +/* private pcd dqrr calbacks */
107274 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
107275 + struct qman_portal *portal,
107276 + struct qman_fq *fq,
107277 + const struct qm_dqrr_entry *dq)
107278 +{
107279 + struct dpa_bp *dpa_bp = NULL;
107280 + dma_addr_t addr = qm_fd_addr(&dq->fd);
107281 + uint8_t *fd_virt_addr = NULL;
107282 + struct fmt_port_s *fmt_port;
107283 + struct fmt_port_pcd_s *fmt_port_pcd;
107284 + uint32_t relative_fqid = 0;
107285 + uint32_t fd_len = 0;
107286 +
107287 + _fmt_dbgr("calling...\n");
107288 +
107289 + /* upcast - from pcd_alloc_fq */
107290 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
107291 + if (!fmt_port) {
107292 + _fmt_err(" wrong fmt port -to- fq match.\n");
107293 + goto _fmt_pcd_dqrr_return;
107294 + }
107295 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
107296 +
107297 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
107298 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
107299 + relative_fqid, fmt_port_pcd->fqid_base);
107300 +
107301 + fd_len = dq->fd.length20 + dq->fd.offset;
107302 +
107303 + if (fd_len > fm_get_max_frm()) {
107304 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
107305 + fd_len, dq->fd.length20, dq->fd.offset);
107306 + goto _fmt_pcd_dqrr_return;
107307 + }
107308 +
107309 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
107310 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
107311 +
107312 + fd_virt_addr = phys_to_virt(addr);
107313 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
107314 + fd_len)) {
107315 +
107316 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107317 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
107318 +#endif
107319 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
107320 + " frame len: %u (dropped).\n",
107321 + dq->fqid, dq->fd.length20);
107322 + dump_frame(fd_virt_addr, fd_len);
107323 + }
107324 +
107325 +_fmt_pcd_dqrr_return:
107326 + /* no need to map again here */
107327 + fmt_fq_release(&dq->fd);
107328 +
107329 + _fmt_dbgr("calle.\n");
107330 + return qman_cb_dqrr_consume;
107331 +}
107332 +
107333 +static void fmt_pcd_err_dqrr(
107334 + struct qman_portal *qm,
107335 + struct qman_fq *fq,
107336 + const struct qm_mr_entry *msg)
107337 +{
107338 + _fmt_err("this callback should never be called.\n");
107339 + BUG();
107340 + return;
107341 +}
107342 +
107343 +static void fmt_pcd_fqs_dqrr(
107344 + struct qman_portal *qm,
107345 + struct qman_fq *fq,
107346 + const struct qm_mr_entry *msg)
107347 +{
107348 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
107349 + return;
107350 +}
107351 +
107352 +/* private pcd queue template */
107353 +static const struct qman_fq pcd_fq = {
107354 + .cb = { .dqrr = fmt_pcd_dqrr,
107355 + .ern = fmt_pcd_err_dqrr,
107356 + .fqs = fmt_pcd_fqs_dqrr}
107357 +};
107358 +
107359 +/* defined as weak in dpaa driver. */
107360 +/* ! parameters come from IOCTL call - US */
107361 +int dpa_alloc_pcd_fqids(
107362 + struct device *dev,
107363 + uint32_t num, uint8_t alignment,
107364 + uint32_t *base_fqid)
107365 +{
107366 + int _err = 0, i;
107367 + struct net_device *net_dev = NULL;
107368 + struct dpa_priv_s *dpa_priv = NULL;
107369 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
107370 + struct fmt_fqs_s *fmt_fqs = NULL;
107371 + struct fmt_port_s *fmt_port = NULL;
107372 + int num_allocated = 0;
107373 +
107374 + _fmt_dbg("calling...\n");
107375 +
107376 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
107377 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
107378 +
107379 + if (!netif_msg_probe(dpa_priv)) {
107380 + _fmt_err("dpa not probe.\n");
107381 + _err = -ENODEV;
107382 + goto _pcd_alloc_fqs_err;
107383 + }
107384 +
107385 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107386 + if (!fmt_port) {
107387 + _fmt_err("fmt port not found.");
107388 + _err = -EINVAL;
107389 + goto _pcd_alloc_fqs_err;
107390 + }
107391 +
107392 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
107393 +
107394 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
107395 +
107396 + if ((num_allocated <= 0) ||
107397 + (num_allocated < num) ||
107398 + (alignment && (*base_fqid) % alignment)) {
107399 + *base_fqid = 0;
107400 + _fmt_err("Failed to alloc pcd fqs rang.\n");
107401 + _err = -EINVAL;
107402 + goto _pcd_alloc_fqs_err;
107403 + }
107404 +
107405 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
107406 + num, alignment, num_allocated, *base_fqid);
107407 +
107408 + /* alloc pcd queues */
107409 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
107410 + sizeof(struct fmt_fqs_s),
107411 + GFP_KERNEL);
107412 + fmt_port_pcd->num_queues = num_allocated;
107413 + fmt_port_pcd->fqid_base = *base_fqid;
107414 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
107415 +
107416 + /* alloc the pcd queues */
107417 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
107418 + _err = fmt_fq_alloc(
107419 + fmt_fqs,
107420 + &pcd_fq,
107421 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
107422 + dpa_priv->channel, 7);
107423 +
107424 + if (_err < 0)
107425 + goto _pcd_alloc_fqs_err;
107426 +
107427 + /* upcast to identify from where the frames came from */
107428 + fmt_fqs->fmt_port_priv = fmt_port;
107429 + }
107430 +
107431 + _fmt_dbg("called.\n");
107432 + return _err;
107433 +_pcd_alloc_fqs_err:
107434 + if (num_allocated > 0)
107435 + qman_release_fqid_range(*base_fqid, num_allocated);
107436 + /*TODO: free fmt_pcd_fqs if are any */
107437 +
107438 + _fmt_dbg("called(_err:%d).\n", _err);
107439 + return _err;
107440 +}
107441 +
107442 +/* defined as weak in dpaa driver. */
107443 +int dpa_free_pcd_fqids(
107444 + struct device *dev,
107445 + uint32_t base_fqid)
107446 +{
107447 +
107448 + int _err = 0, i;
107449 + struct net_device *net_dev = NULL;
107450 + struct dpa_priv_s *dpa_priv = NULL;
107451 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
107452 + struct fmt_fqs_s *fmt_fqs = NULL;
107453 + struct fmt_port_s *fmt_port = NULL;
107454 + int num_allocated = 0;
107455 +
107456 + _fmt_dbg("calling...\n");
107457 +
107458 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
107459 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
107460 +
107461 + if (!netif_msg_probe(dpa_priv)) {
107462 + _fmt_err("dpa not probe.\n");
107463 + _err = -ENODEV;
107464 + goto _pcd_free_fqs_err;
107465 + }
107466 +
107467 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107468 + if (!fmt_port) {
107469 + _fmt_err("fmt port not found.");
107470 + _err = -EINVAL;
107471 + goto _pcd_free_fqs_err;
107472 + }
107473 +
107474 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
107475 + num_allocated = fmt_port_pcd->num_queues;
107476 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
107477 +
107478 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
107479 + fmt_fq_free(fmt_fqs);
107480 +
107481 + qman_release_fqid_range(base_fqid,num_allocated);
107482 +
107483 + kfree(fmt_port_pcd->fmt_pcd_fqs);
107484 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
107485 +
107486 + /* debugging stuff */
107487 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107488 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
107489 + _fmt_dbg(" frames enqueue to qman: %u.\n",
107490 + atomic_read(&fmt_port->enqueue_to_qman_frm));
107491 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
107492 + atomic_read(&fmt_port->enqueue_to_rxq));
107493 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
107494 + atomic_read(&fmt_port->dequeue_from_rxq));
107495 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
107496 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
107497 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
107498 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
107499 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
107500 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
107501 +#endif
107502 + return 0;
107503 +
107504 +_pcd_free_fqs_err:
107505 + return _err;
107506 +}
107507 +
107508 +static int fmt_port_init(
107509 + struct fmt_port_s *fmt_port,
107510 + ioc_fmt_port_param_t *p_Params)
107511 +{
107512 + struct device_node *fm_node, *fm_port_node;
107513 + const uint32_t *uint32_prop;
107514 + int _errno = 0, lenp = 0, i;
107515 + static struct of_device_id fm_node_of_match[] = {
107516 + { .compatible = "fsl,fman", },
107517 + { /* end of list */ },
107518 + };
107519 +
107520 + _fmt_dbg("calling...\n");
107521 +
107522 + /* init send/receive tu US list */
107523 + INIT_LIST_HEAD(&fmt_port->rx_q);
107524 +
107525 + /* check parameters */
107526 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
107527 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
107528 + _fmt_dbg("wrong test parameters.\n");
107529 + return -EINVAL;
107530 + }
107531 +
107532 + /* set port parameters */
107533 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
107534 + fmt_port->id = p_Params->fm_port_id;
107535 + fmt_port->port_type = p_Params->fm_port_type;
107536 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
107537 +
107538 + /* init debugging stuff */
107539 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107540 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
107541 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
107542 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
107543 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
107544 +#endif
107545 +
107546 + /* TODO: This should be done at probe time not at runtime
107547 + * very ugly function */
107548 + /* fill fmt port properties from dts */
107549 + for_each_matching_node(fm_node, fm_node_of_match) {
107550 +
107551 + uint32_prop = (uint32_t *)of_get_property(fm_node,
107552 + "cell-index", &lenp);
107553 + if (unlikely(uint32_prop == NULL)) {
107554 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
107555 + fm_node->full_name);
107556 + return -EINVAL;
107557 + }
107558 + if (WARN_ON(lenp != sizeof(uint32_t))) {
107559 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
107560 + fm_node->full_name);
107561 + return -EINVAL;
107562 + }
107563 +
107564 + if (*uint32_prop == p_Params->fm_id) {
107565 + struct resource res;
107566 +
107567 + /* Get the FM address */
107568 + _errno = of_address_to_resource(fm_node, 0, &res);
107569 + if (unlikely(_errno < 0)) {
107570 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
107571 + return -EINVAL;
107572 + }
107573 +
107574 + fmt_port->fm_phys_base_addr = res.start;
107575 +
107576 + for_each_child_of_node(fm_node, fm_port_node) {
107577 + struct platform_device *of_dev;
107578 +
107579 + if (!of_device_is_available(fm_port_node))
107580 + continue;
107581 +
107582 + uint32_prop = (uint32_t *)of_get_property(
107583 + fm_port_node,
107584 + "cell-index",
107585 + &lenp);
107586 + if (uint32_prop == NULL)
107587 + continue;
107588 +
107589 + if (of_device_is_compatible(fm_port_node,
107590 + "fsl,fman-port-oh") &&
107591 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
107592 +
107593 + if (*uint32_prop == fmt_port->id) {
107594 + of_dev = of_find_device_by_node(fm_port_node);
107595 + if (unlikely(of_dev == NULL)) {
107596 + _fmt_wrn("fm id invalid\n");
107597 + return -EINVAL;
107598 + }
107599 +
107600 + fmt_port->p_tx_port =
107601 + fm_port_bind(&of_dev->dev);
107602 + fmt_port->p_tx_fm_port_dev =
107603 + (void *)fm_port_get_handle(
107604 + fmt_port->p_tx_port);
107605 + fmt_port->p_rx_port =
107606 + fmt_port->p_tx_port;
107607 + fmt_port->p_rx_fm_port_dev =
107608 + fmt_port->p_tx_fm_port_dev;
107609 + fmt_port->p_mac_dev = NULL;
107610 + break;
107611 + }
107612 + } else if ((*uint32_prop == fmt_port->id) &&
107613 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
107614 +
107615 + of_dev = of_find_device_by_node(fm_port_node);
107616 + if (unlikely(of_dev == NULL)) {
107617 + _fmt_wrn("dtb fm id invalid value");
107618 + return -EINVAL;
107619 + }
107620 +
107621 + if (of_device_is_compatible(fm_port_node,
107622 + "fsl,fman-port-1g-tx")) {
107623 + fmt_port->p_tx_port =
107624 + fm_port_bind(&of_dev->dev);
107625 + fmt_port->p_tx_fm_port_dev = (void *)
107626 + fm_port_get_handle(
107627 + fmt_port->p_tx_port);
107628 + } else if (of_device_is_compatible(fm_port_node,
107629 + "fsl,fman-port-1g-rx")) {
107630 + fmt_port->p_rx_port =
107631 + fm_port_bind(&of_dev->dev);
107632 + fmt_port->p_rx_fm_port_dev = (void *)
107633 + fm_port_get_handle(
107634 + fmt_port->p_rx_port);
107635 + } else if (of_device_is_compatible(fm_port_node,
107636 + "fsl,fman-1g-mac") ||
107637 + of_device_is_compatible(fm_port_node,
107638 + "fsl,fman-memac"))
107639 + fmt_port->p_mac_dev =
107640 + (typeof(fmt_port->p_mac_dev))
107641 + dev_get_drvdata(&of_dev->dev);
107642 + else
107643 + continue;
107644 +
107645 + if (fmt_port->p_tx_fm_port_dev &&
107646 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
107647 + break;
107648 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
107649 + fmt_port->id) &&
107650 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
107651 +
107652 + of_dev = of_find_device_by_node(fm_port_node);
107653 + if (unlikely(of_dev == NULL)) {
107654 + _fmt_wrn("dtb fm id invalid value\n");
107655 + return -EINVAL;
107656 + }
107657 +
107658 + if (of_device_is_compatible(fm_port_node,
107659 + "fsl,fman-port-10g-tx")) {
107660 + fmt_port->p_tx_port =
107661 + fm_port_bind(&of_dev->dev);
107662 + fmt_port->p_tx_fm_port_dev = (void *)
107663 + fm_port_get_handle(
107664 + fmt_port->p_tx_port);
107665 + } else if (of_device_is_compatible(fm_port_node,
107666 + "fsl,fman-port-10g-rx")) {
107667 + fmt_port->p_rx_port =
107668 + fm_port_bind(&of_dev->dev);
107669 + fmt_port->p_rx_fm_port_dev = (void *)
107670 + fm_port_get_handle(
107671 + fmt_port->p_rx_port);
107672 + } else if (of_device_is_compatible(fm_port_node,
107673 + "fsl,fman-10g-mac") ||
107674 + of_device_is_compatible(fm_port_node,
107675 + "fsl,fman-memac"))
107676 + fmt_port->p_mac_dev =
107677 + (typeof(fmt_port->p_mac_dev))
107678 + dev_get_drvdata(&of_dev->dev);
107679 + else
107680 + continue;
107681 +
107682 + if (fmt_port->p_tx_fm_port_dev &&
107683 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
107684 + break;
107685 + }
107686 + } /* for_each_child */
107687 + }
107688 + } /* for each matching node */
107689 +
107690 + if (fmt_port->p_tx_fm_port_dev == 0 ||
107691 + fmt_port->p_rx_fm_port_dev == 0) {
107692 +
107693 + _fmt_err("bad fm port pointers.\n");
107694 + return -EINVAL;
107695 + }
107696 +
107697 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
107698 +
107699 + /* init fman test egress dynamic frame queues */
107700 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
107701 + int _errno;
107702 + _errno = fmt_fq_alloc(
107703 + &fmt_port->p_tx_fqs[i],
107704 + &fmt_egress_fq,
107705 + 0,
107706 + QMAN_FQ_FLAG_TO_DCPORTAL,
107707 + fm_get_tx_port_channel(fmt_port->p_tx_port),
107708 + i);
107709 +
107710 + if (_errno < 0) {
107711 + _fmt_err("tx queues allocation failed.\n");
107712 + /* TODO: memory leak here if 1 queue is allocated and
107713 + * next queues are failing ... */
107714 + return -EINVAL;
107715 + }
107716 + }
107717 +
107718 + /* port is valid and ready to use. */
107719 + fmt_port->valid = TRUE;
107720 +
107721 + _fmt_dbg("called.\n");
107722 + return 0;
107723 +}
107724 +
107725 +/* fm test chardev functions */
107726 +static int fmt_open(struct inode *inode, struct file *file)
107727 +{
107728 + unsigned int minor = iminor(inode);
107729 +
107730 + _fmt_dbg("calling...\n");
107731 +
107732 + if (file->private_data != NULL)
107733 + return 0;
107734 +
107735 + /* The minor represent the port number.
107736 + * Set the port structure accordingly, thus all the operations
107737 + * will be done on this port. */
107738 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
107739 + (minor < DEV_FM_TEST_MAX_MINORS))
107740 + file->private_data = &fm_test.ports[minor];
107741 + else
107742 + return -ENXIO;
107743 +
107744 + _fmt_dbg("called.\n");
107745 + return 0;
107746 +}
107747 +
107748 +static int fmt_close(struct inode *inode, struct file *file)
107749 +{
107750 + struct fmt_port_s *fmt_port = NULL;
107751 + struct fmt_frame_s *fmt_frame = NULL;
107752 +
107753 + int err = 0;
107754 +
107755 + _fmt_dbg("calling...\n");
107756 +
107757 + fmt_port = file->private_data;
107758 + if (!fmt_port)
107759 + return -ENODEV;
107760 +
107761 + /* Close the current test port by invalidating it. */
107762 + fmt_port->valid = FALSE;
107763 +
107764 + /* clean the fmt port queue */
107765 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
107766 + if (fmt_frame && fmt_frame->buff.p_data){
107767 + kfree(fmt_frame->buff.p_data);
107768 + kfree(fmt_frame);
107769 + }
107770 + }
107771 +
107772 + /* !!! the qman queues are cleaning from fm_ioctl...
107773 + * - very ugly */
107774 +
107775 + _fmt_dbg("called.\n");
107776 + return err;
107777 +}
107778 +
107779 +static int fmt_ioctls(unsigned int minor,
107780 + struct file *file,
107781 + unsigned int cmd,
107782 + unsigned long arg,
107783 + bool compat)
107784 +{
107785 + struct fmt_port_s *fmt_port = NULL;
107786 +
107787 + _fmt_dbg("IOCTL minor:%u "
107788 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
107789 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
107790 +
107791 + fmt_port = file->private_data;
107792 + if (!fmt_port) {
107793 + _fmt_err("invalid fmt port.\n");
107794 + return -ENODEV;
107795 + }
107796 +
107797 + /* set test type properly */
107798 + if (compat)
107799 + fmt_port->compat_test_type = true;
107800 + else
107801 + fmt_port->compat_test_type = false;
107802 +
107803 + switch (cmd) {
107804 + case FMT_PORT_IOC_INIT:
107805 + {
107806 + ioc_fmt_port_param_t param;
107807 +
107808 + if (fmt_port->valid) {
107809 + _fmt_wrn("port is already initialized.\n");
107810 + return -EFAULT;
107811 + }
107812 +#if defined(CONFIG_COMPAT)
107813 + if (compat) {
107814 + if (copy_from_user(&param,
107815 + (ioc_fmt_port_param_t *)compat_ptr(arg),
107816 + sizeof(ioc_fmt_port_param_t)))
107817 +
107818 + return -EFAULT;
107819 + } else
107820 +#endif
107821 + {
107822 + if (copy_from_user(&param,
107823 + (ioc_fmt_port_param_t *) arg,
107824 + sizeof(ioc_fmt_port_param_t)))
107825 +
107826 + return -EFAULT;
107827 + }
107828 +
107829 + return fmt_port_init(fmt_port, &param);
107830 + }
107831 +
107832 + case FMT_PORT_IOC_SET_DIAG_MODE:
107833 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
107834 + return -EFAULT;
107835 +
107836 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
107837 + return set_mac_int_loopback(fmt_port, TRUE);
107838 + else
107839 + return set_mac_int_loopback(fmt_port, FALSE);
107840 + break;
107841 +
107842 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
107843 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
107844 + default:
107845 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
107846 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
107847 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
107848 + return -EFAULT;
107849 + }
107850 +
107851 + return 0;
107852 +}
107853 +
107854 +#ifdef CONFIG_COMPAT
107855 +static long fmt_compat_ioctl(
107856 + struct file *file,
107857 + unsigned int cmd,
107858 + unsigned long arg)
107859 +{
107860 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
107861 +
107862 + _fmt_dbg("calling...\n");
107863 + return fmt_ioctls(minor, file, cmd, arg, true);
107864 +}
107865 +#endif
107866 +
107867 +static long fmt_ioctl(
107868 + struct file *file,
107869 + unsigned int cmd,
107870 + unsigned long arg)
107871 +{
107872 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
107873 + unsigned int res;
107874 +
107875 + _fmt_dbg("calling...\n");
107876 +
107877 + fm_mutex_lock();
107878 + res = fmt_ioctls(minor, file, cmd, arg, false);
107879 + fm_mutex_unlock();
107880 +
107881 + _fmt_dbg("called.\n");
107882 +
107883 + return res;
107884 +}
107885 +
107886 +#ifdef CONFIG_COMPAT
107887 +void copy_compat_test_frame_buffer(
107888 + ioc_fmt_buff_desc_t *buff,
107889 + ioc_fmt_compat_buff_desc_t *compat_buff)
107890 +{
107891 + compat_buff->qid = buff->qid;
107892 + compat_buff->p_data = ptr_to_compat(buff->p_data);
107893 + compat_buff->size = buff->size;
107894 + compat_buff->status = buff->status;
107895 +
107896 + compat_buff->buff_context.p_user_priv =
107897 + ptr_to_compat(buff->buff_context.p_user_priv);
107898 + memcpy(compat_buff->buff_context.fm_prs_res,
107899 + buff->buff_context.fm_prs_res,
107900 + FM_PRS_MAX * sizeof(uint8_t));
107901 + memcpy(compat_buff->buff_context.fm_time_stamp,
107902 + buff->buff_context.fm_time_stamp,
107903 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
107904 +}
107905 +#endif
107906 +
107907 +ssize_t fmt_read(
107908 + struct file *file,
107909 + char __user *buf,
107910 + size_t size,
107911 + loff_t *ppos)
107912 +{
107913 + struct fmt_port_s *fmt_port = NULL;
107914 + struct fmt_frame_s *p_fmt_frame = NULL;
107915 + ssize_t cnt = 0;
107916 +
107917 + fmt_port = file->private_data;
107918 + if (!fmt_port || !fmt_port->valid) {
107919 + _fmt_err("fmt port not valid!\n");
107920 + return -ENODEV;
107921 + }
107922 +
107923 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
107924 + if (p_fmt_frame == NULL)
107925 + return 0;
107926 +
107927 + _fmt_dbgr("calling...\n");
107928 +
107929 +#ifdef CONFIG_COMPAT
107930 + if (fmt_port->compat_test_type){
107931 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
107932 + }
107933 + else
107934 +#endif
107935 + {
107936 + cnt = sizeof(ioc_fmt_buff_desc_t);
107937 + }
107938 +
107939 + if (size < cnt) {
107940 + _fmt_err("illegal buffer-size!\n");
107941 + cnt = 0;
107942 + goto _fmt_read_return;
107943 + }
107944 +
107945 + /* Copy structure */
107946 +#ifdef CONFIG_COMPAT
107947 + if (fmt_port->compat_test_type) {
107948 + {
107949 + ioc_fmt_compat_buff_desc_t compat_buff;
107950 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
107951 + &compat_buff);
107952 +
107953 + if (copy_to_user(buf, &compat_buff, cnt)) {
107954 + _fmt_err("copy_to_user failed!\n");
107955 + goto _fmt_read_return;
107956 + }
107957 + }
107958 +
107959 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
107960 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
107961 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
107962 + } else
107963 +#endif
107964 + {
107965 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
107966 + _fmt_err("copy_to_user failed!\n");
107967 + goto _fmt_read_return;
107968 + }
107969 +
107970 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
107971 + buf + sizeof(ioc_fmt_buff_desc_t);
107972 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
107973 + }
107974 +
107975 + if (size < cnt) {
107976 + _fmt_err("illegal buffer-size!\n");
107977 + goto _fmt_read_return;
107978 + }
107979 +
107980 + /* copy frame */
107981 +#ifdef CONFIG_COMPAT
107982 + if (fmt_port->compat_test_type) {
107983 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
107984 + p_fmt_frame->buff.p_data, cnt)) {
107985 + _fmt_err("copy_to_user failed!\n");
107986 + goto _fmt_read_return;
107987 + }
107988 + } else
107989 +#endif
107990 + {
107991 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
107992 + p_fmt_frame->buff.p_data, cnt)) {
107993 + _fmt_err("copy_to_user failed!\n");
107994 + goto _fmt_read_return;
107995 + }
107996 + }
107997 +
107998 +_fmt_read_return:
107999 + kfree(p_fmt_frame->buff.p_data);
108000 + kfree(p_fmt_frame);
108001 +
108002 + _fmt_dbgr("called.\n");
108003 + return cnt;
108004 +}
108005 +
108006 +ssize_t fmt_write(
108007 + struct file *file,
108008 + const char __user *buf,
108009 + size_t size,
108010 + loff_t *ppos)
108011 +{
108012 + struct fmt_port_s *fmt_port = NULL;
108013 + ioc_fmt_buff_desc_t buff_desc;
108014 +#ifdef CONFIG_COMPAT
108015 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
108016 +#endif
108017 + uint8_t *p_data = NULL;
108018 + uint32_t data_offset;
108019 + int _errno;
108020 + t_DpaaFD fd;
108021 +
108022 + _fmt_dbgr("calling...\n");
108023 +
108024 + fmt_port = file->private_data;
108025 + if (!fmt_port || !fmt_port->valid) {
108026 + _fmt_err("fmt port not valid.\n");
108027 + return -EINVAL;
108028 + }
108029 +
108030 + /* If Compat (32B UserSpace - 64B KernelSpace) */
108031 +#ifdef CONFIG_COMPAT
108032 + if (fmt_port->compat_test_type) {
108033 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
108034 + _fmt_err("invalid buff_desc size.\n");
108035 + return -EFAULT;
108036 + }
108037 +
108038 + if (copy_from_user(&buff_desc_compat, buf,
108039 + sizeof(ioc_fmt_compat_buff_desc_t)))
108040 + return -EFAULT;
108041 +
108042 + buff_desc.qid = buff_desc_compat.qid;
108043 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
108044 + buff_desc.size = buff_desc_compat.size;
108045 + buff_desc.status = buff_desc_compat.status;
108046 +
108047 + buff_desc.buff_context.p_user_priv =
108048 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
108049 + memcpy(buff_desc.buff_context.fm_prs_res,
108050 + buff_desc_compat.buff_context.fm_prs_res,
108051 + FM_PRS_MAX * sizeof(uint8_t));
108052 + memcpy(buff_desc.buff_context.fm_time_stamp,
108053 + buff_desc_compat.buff_context.fm_time_stamp,
108054 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
108055 + } else
108056 +#endif
108057 + {
108058 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
108059 + _fmt_err("invalid buff_desc size.\n");
108060 + return -EFAULT;
108061 + }
108062 +
108063 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
108064 + sizeof(ioc_fmt_buff_desc_t)))
108065 + return -EFAULT;
108066 + }
108067 +
108068 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
108069 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
108070 + if (!p_data)
108071 + return -ENOMEM;
108072 +
108073 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
108074 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
108075 + buff_desc.p_data,
108076 + buff_desc.size)) {
108077 + kfree(p_data);
108078 + return -EFAULT;
108079 + }
108080 +
108081 + /* TODO: dma_map_single here (cannot access the bpool struct) */
108082 +
108083 + /* prepare fd */
108084 + memset(&fd, 0, sizeof(fd));
108085 + DPAA_FD_SET_ADDR(&fd, p_data);
108086 + DPAA_FD_SET_OFFSET(&fd, data_offset);
108087 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
108088 +
108089 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
108090 + (struct qm_fd *)&fd, 0);
108091 + if (_errno) {
108092 + buff_desc.status = (uint32_t)_errno;
108093 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
108094 + sizeof(ioc_fmt_buff_desc_t))) {
108095 + kfree(p_data);
108096 + return -EFAULT;
108097 + }
108098 + }
108099 +
108100 + /* for debugging */
108101 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
108102 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
108103 +#endif
108104 + _fmt_dbgr("called.\n");
108105 + return buff_desc.size;
108106 +}
108107 +
108108 +/* fm test character device definition */
108109 +static const struct file_operations fmt_fops =
108110 +{
108111 + .owner = THIS_MODULE,
108112 +#ifdef CONFIG_COMPAT
108113 + .compat_ioctl = fmt_compat_ioctl,
108114 +#endif
108115 + .unlocked_ioctl = fmt_ioctl,
108116 + .open = fmt_open,
108117 + .release = fmt_close,
108118 + .read = fmt_read,
108119 + .write = fmt_write,
108120 +};
108121 +
108122 +static int fmt_init(void)
108123 +{
108124 + int id;
108125 +
108126 + _fmt_dbg("calling...\n");
108127 +
108128 + /* Register to the /dev for IOCTL API */
108129 + /* Register dynamically a new major number for the character device: */
108130 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
108131 + if (fm_test.major <= 0) {
108132 + _fmt_wrn("Failed to allocate major number for device %s.\n",
108133 + DEV_FM_TEST_NAME);
108134 + return -ENODEV;
108135 + }
108136 +
108137 + /* Creating class for FMan_test */
108138 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
108139 + if (IS_ERR(fm_test.fmt_class)) {
108140 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
108141 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
108142 + return -ENODEV;
108143 + }
108144 +
108145 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
108146 + if (NULL == device_create(fm_test.fmt_class, NULL,
108147 + MKDEV(fm_test.major,
108148 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
108149 + DEV_FM_TEST_NAME "%d", id)) {
108150 +
108151 + _fmt_err("Error creating %s device.\n",
108152 + DEV_FM_TEST_NAME);
108153 + return -ENODEV;
108154 + }
108155 +
108156 + return 0;
108157 +}
108158 +
108159 +static void fmt_free(void)
108160 +{
108161 + int id;
108162 +
108163 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
108164 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
108165 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
108166 + class_destroy(fm_test.fmt_class);
108167 +}
108168 +
108169 +static int __init __cold fmt_load(void)
108170 +{
108171 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
108172 +
108173 + /* set dpaa hooks for default queues */
108174 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
108175 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
108176 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
108177 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
108178 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
108179 +
108180 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
108181 +
108182 + /* initialize the fman test environment */
108183 + if (fmt_init() < 0) {
108184 + _fmt_err("Failed to init FM-test modul.\n");
108185 + fmt_free();
108186 + return -ENODEV;
108187 + }
108188 +
108189 + _fmt_inf("FSL FM test module loaded.\n");
108190 +
108191 + return 0;
108192 +}
108193 +
108194 +static void __exit __cold fmt_unload(void)
108195 +{
108196 + fmt_free();
108197 + _fmt_inf("FSL FM test module unloaded.\n");
108198 +}
108199 +
108200 +module_init(fmt_load);
108201 +module_exit(fmt_unload);
108202 --- /dev/null
108203 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
108204 @@ -0,0 +1,2908 @@
108205 +/*
108206 + * Copyright 2008-2012 Freescale Semiconductor Inc.
108207 + *
108208 + * Redistribution and use in source and binary forms, with or without
108209 + * modification, are permitted provided that the following conditions are met:
108210 + * * Redistributions of source code must retain the above copyright
108211 + * notice, this list of conditions and the following disclaimer.
108212 + * * Redistributions in binary form must reproduce the above copyright
108213 + * notice, this list of conditions and the following disclaimer in the
108214 + * documentation and/or other materials provided with the distribution.
108215 + * * Neither the name of Freescale Semiconductor nor the
108216 + * names of its contributors may be used to endorse or promote products
108217 + * derived from this software without specific prior written permission.
108218 + *
108219 + *
108220 + * ALTERNATIVELY, this software may be distributed under the terms of the
108221 + * GNU General Public License ("GPL") as published by the Free Software
108222 + * Foundation, either version 2 of that License or (at your option) any
108223 + * later version.
108224 + *
108225 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
108226 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
108227 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
108228 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
108229 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
108230 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
108231 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
108232 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
108233 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
108234 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
108235 + */
108236 +
108237 +/*
108238 + @File lnxwrp_fm.c
108239 + @Author Shlomi Gridish
108240 + @Description FM Linux wrapper functions.
108241 +*/
108242 +
108243 +#include <linux/version.h>
108244 +#include <linux/slab.h>
108245 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
108246 +#define MODVERSIONS
108247 +#endif
108248 +#ifdef MODVERSIONS
108249 +#include <config/modversions.h>
108250 +#endif /* MODVERSIONS */
108251 +#include <linux/kernel.h>
108252 +#include <linux/module.h>
108253 +#include <linux/fs.h>
108254 +#include <linux/cdev.h>
108255 +#include <linux/device.h>
108256 +#include <linux/irq.h>
108257 +#include <linux/interrupt.h>
108258 +#include <linux/io.h>
108259 +#include <linux/ioport.h>
108260 +#include <linux/of_platform.h>
108261 +#include <linux/of_address.h>
108262 +#include <linux/of_irq.h>
108263 +#include <linux/clk.h>
108264 +#include <asm/uaccess.h>
108265 +#include <asm/errno.h>
108266 +#ifndef CONFIG_FMAN_ARM
108267 +#include <sysdev/fsl_soc.h>
108268 +#include <linux/fsl/guts.h>
108269 +#include <linux/fsl/svr.h>
108270 +#endif
108271 +#include <linux/stat.h> /* For file access mask */
108272 +#include <linux/skbuff.h>
108273 +#include <linux/proc_fs.h>
108274 +
108275 +/* NetCommSw Headers --------------- */
108276 +#include "std_ext.h"
108277 +#include "error_ext.h"
108278 +#include "sprint_ext.h"
108279 +#include "debug_ext.h"
108280 +#include "sys_io_ext.h"
108281 +
108282 +#include "fm_ioctls.h"
108283 +
108284 +#include "lnxwrp_fm.h"
108285 +#include "lnxwrp_resources.h"
108286 +#include "lnxwrp_sysfs_fm.h"
108287 +#include "lnxwrp_sysfs_fm_port.h"
108288 +#include "lnxwrp_exp_sym.h"
108289 +#include "fm_common.h"
108290 +#include "../../sdk_fman/Peripherals/FM/fm.h"
108291 +#define __ERR_MODULE__ MODULE_FM
108292 +
108293 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
108294 + e_FmPortType portType,
108295 + uint8_t portId);
108296 +
108297 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
108298 +
108299 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
108300 + do { \
108301 + if (i<max){ \
108302 + p_Entry = &p_Entrys[i]; \
108303 + p_Entry->p_Function = _func; \
108304 + _param \
108305 + i++; \
108306 + } \
108307 + else \
108308 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
108309 + ("Number of advanced-configuration entries exceeded"));\
108310 + } while (0)
108311 +
108312 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
108313 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
108314 +
108315 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
108316 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
108317 +
108318 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
108319 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
108320 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
108321 +
108322 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
108323 +#define FSL_FM_PAUSE_TIME_DISABLE 0
108324 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
108325 +
108326 +/*
108327 + * Max frame size, across all interfaces.
108328 + * Configurable from Kconfig or bootargs, to avoid allocating
108329 + * oversized (socket) buffers when not using jumbo frames.
108330 + * Must be large enough to accommodate the network MTU, but small enough
108331 + * to avoid wasting skb memory.
108332 + *
108333 + * Could be overridden once, at boot-time, via the
108334 + * fm_set_max_frm() callback.
108335 + */
108336 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
108337 +
108338 +/*
108339 + * Extra headroom for Rx buffers.
108340 + * FMan is instructed to allocate, on the Rx path, this amount of
108341 + * space at the beginning of a data buffer, beside the DPA private
108342 + * data area and the IC fields.
108343 + * Does not impact Tx buffer layout.
108344 + *
108345 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
108346 + * on particular forwarding scenarios that add extra headers to the
108347 + * forwarded frame.
108348 + */
108349 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
108350 +
108351 +#ifdef CONFIG_FMAN_PFC
108352 +static int fsl_fm_pfc_quanta[] = {
108353 + CONFIG_FMAN_PFC_QUANTA_0,
108354 + CONFIG_FMAN_PFC_QUANTA_1,
108355 + CONFIG_FMAN_PFC_QUANTA_2,
108356 + CONFIG_FMAN_PFC_QUANTA_3
108357 +};
108358 +#endif
108359 +
108360 +static t_LnxWrpFm lnxWrpFm;
108361 +
108362 +int fm_get_max_frm()
108363 +{
108364 + return fsl_fm_max_frm;
108365 +}
108366 +EXPORT_SYMBOL(fm_get_max_frm);
108367 +
108368 +int fm_get_rx_extra_headroom()
108369 +{
108370 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
108371 +}
108372 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
108373 +
108374 +static int __init fm_set_max_frm(char *str)
108375 +{
108376 + int ret = 0;
108377 +
108378 + ret = get_option(&str, &fsl_fm_max_frm);
108379 + if (ret != 1) {
108380 + /*
108381 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
108382 + * and something like "earlyprintk=serial,uart0,115200" is
108383 + * specified in the bootargs
108384 + */
108385 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
108386 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
108387 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
108388 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
108389 +
108390 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
108391 + return 1;
108392 + }
108393 +
108394 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
108395 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
108396 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
108397 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
108398 + "from Kconfig.\n",
108399 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
108400 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
108401 +
108402 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
108403 + return 1;
108404 + }
108405 +
108406 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
108407 + fsl_fm_max_frm);
108408 + return 0;
108409 +}
108410 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
108411 +
108412 +static int __init fm_set_rx_extra_headroom(char *str)
108413 +{
108414 + int ret;
108415 +
108416 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
108417 +
108418 + if (ret != 1) {
108419 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
108420 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
108421 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
108422 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
108423 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
108424 +
108425 + return 1;
108426 + }
108427 +
108428 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
108429 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
108430 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
108431 + "bootargs; will use the default "
108432 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
108433 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
108434 + fsl_fm_rx_extra_headroom,
108435 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
108436 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
108437 + }
108438 +
108439 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
108440 + fsl_fm_rx_extra_headroom);
108441 +
108442 + return 0;
108443 +}
108444 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
108445 +
108446 +static irqreturn_t fm_irq(int irq, void *_dev)
108447 +{
108448 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
108449 +#ifdef CONFIG_PM_SLEEP
108450 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
108451 +#endif
108452 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
108453 + return IRQ_NONE;
108454 +
108455 +#ifdef CONFIG_PM_SLEEP
108456 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
108457 + {
108458 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
108459 + }
108460 +#endif
108461 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
108462 + return IRQ_HANDLED;
108463 +}
108464 +
108465 +static irqreturn_t fm_err_irq(int irq, void *_dev)
108466 +{
108467 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
108468 +
108469 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
108470 + return IRQ_NONE;
108471 +
108472 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
108473 + return IRQ_HANDLED;
108474 +
108475 + return IRQ_NONE;
108476 +}
108477 +
108478 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
108479 +static struct mutex lnxwrp_mutex;
108480 +
108481 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
108482 +{
108483 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108484 + int j;
108485 +
108486 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
108487 + if (!p_LnxWrpFmDev)
108488 + {
108489 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
108490 + return NULL;
108491 + }
108492 +
108493 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
108494 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108495 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108496 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108497 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108498 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108499 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108500 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
108501 + {
108502 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108503 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108504 + }
108505 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
108506 + {
108507 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108508 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108509 + }
108510 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
108511 + {
108512 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108513 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108514 + }
108515 +
108516 + return p_LnxWrpFmDev;
108517 +}
108518 +
108519 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108520 +{
108521 + int j;
108522 +
108523 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
108524 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
108525 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
108526 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
108527 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
108528 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
108529 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
108530 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
108531 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
108532 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
108533 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
108534 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
108535 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
108536 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
108537 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
108538 +
108539 + XX_Free(p_LnxWrpFmDev);
108540 +}
108541 +
108542 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
108543 +{
108544 +#define FM_BMI_PPIDS_OFFSET 0x00080304
108545 +#define FM_DMA_PLR_OFFSET 0x000c2060
108546 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
108547 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
108548 +#define DMA_LOW_LIODN_MASK 0x00000FFF
108549 +#define DMA_LIODN_SHIFT 16
108550 +
108551 +typedef _Packed struct {
108552 + uint32_t plr[32];
108553 +} _PackedType t_Plr;
108554 +
108555 +typedef _Packed struct {
108556 + volatile uint32_t fmbm_ppid[63];
108557 +} _PackedType t_Ppids;
108558 +
108559 + t_Plr *p_Plr;
108560 + t_Ppids *p_Ppids;
108561 + int i,j;
108562 + uint32_t fmRev;
108563 +
108564 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
108565 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
108566 +#if (DPAA_VERSION >= 11)
108567 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
108568 +#else
108569 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
108570 +#endif
108571 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
108572 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
108573 +
108574 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
108575 + fmRev &= 0xffff;
108576 +
108577 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
108578 +#ifdef MODULE
108579 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
108580 + p_Plr->plr[i] = 0;
108581 +#endif /* MODULE */
108582 +
108583 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
108584 + {
108585 + uint16_t liodnBase = (uint16_t)((i%2) ?
108586 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
108587 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
108588 +#ifdef FM_PARTITION_ARRAY
108589 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
108590 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
108591 +#endif /* FM_PARTITION_ARRAY */
108592 +
108593 + if ((i >= phys1GRxPortId[0]) &&
108594 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
108595 + {
108596 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
108597 + if (phys1GRxPortId[j] == i)
108598 + break;
108599 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
108600 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
108601 + }
108602 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
108603 + (i >= phys10GRxPortId[0]) &&
108604 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
108605 + {
108606 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
108607 + if (phys10GRxPortId[j] == i)
108608 + break;
108609 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
108610 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
108611 + }
108612 + else if ((i >= physOhPortId[0]) &&
108613 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
108614 + {
108615 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
108616 + if (physOhPortId[j] == i)
108617 + break;
108618 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
108619 + if (j == 0)
108620 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
108621 + else
108622 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
108623 + }
108624 + else if ((i >= phys1GTxPortId[0]) &&
108625 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
108626 + {
108627 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
108628 + if (phys1GTxPortId[j] == i)
108629 + break;
108630 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
108631 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
108632 + }
108633 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
108634 + (i >= phys10GTxPortId[0]) &&
108635 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
108636 + {
108637 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
108638 + if (phys10GTxPortId[j] == i)
108639 + break;
108640 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
108641 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
108642 + }
108643 + }
108644 +
108645 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
108646 +
108647 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
108648 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
108649 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
108650 +
108651 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
108652 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
108653 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
108654 +
108655 + return E_OK;
108656 +}
108657 +
108658 +/* Structure that defines QE firmware binary files.
108659 + *
108660 + * See Documentation/powerpc/qe_firmware.txt for a description of these
108661 + * fields.
108662 + */
108663 +struct qe_firmware {
108664 + struct qe_header {
108665 + __be32 length; /* Length of the entire structure, in bytes */
108666 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
108667 + u8 version; /* Version of this layout. First ver is '1' */
108668 + } header;
108669 + u8 id[62]; /* Null-terminated identifier string */
108670 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
108671 + u8 count; /* Number of microcode[] structures */
108672 + struct {
108673 + __be16 model; /* The SOC model */
108674 + u8 major; /* The SOC revision major */
108675 + u8 minor; /* The SOC revision minor */
108676 + } __attribute__ ((packed)) soc;
108677 + u8 padding[4]; /* Reserved, for alignment */
108678 + __be64 extended_modes; /* Extended modes */
108679 + __be32 vtraps[8]; /* Virtual trap addresses */
108680 + u8 reserved[4]; /* Reserved, for future expansion */
108681 + struct qe_microcode {
108682 + u8 id[32]; /* Null-terminated identifier */
108683 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
108684 + __be32 eccr; /* The value for the ECCR register */
108685 + __be32 iram_offset; /* Offset into I-RAM for the code */
108686 + __be32 count; /* Number of 32-bit words of the code */
108687 + __be32 code_offset; /* Offset of the actual microcode */
108688 + u8 major; /* The microcode version major */
108689 + u8 minor; /* The microcode version minor */
108690 + u8 revision; /* The microcode version revision */
108691 + u8 padding; /* Reserved, for alignment */
108692 + u8 reserved[4]; /* Reserved, for future expansion */
108693 + } __attribute__ ((packed)) microcode[1];
108694 + /* All microcode binaries should be located here */
108695 + /* CRC32 should be located here, after the microcode binaries */
108696 +} __attribute__ ((packed));
108697 +
108698 +
108699 +/**
108700 + * FindFmanMicrocode - find the Fman microcode
108701 + *
108702 + * This function returns a pointer to the QE Firmware blob that holds
108703 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
108704 + * is similar to QE microcode, so there's no point in defining a new layout.
108705 + *
108706 + * Current versions of U-Boot embed the Fman firmware into the device tree,
108707 + * so we check for that first. Each Fman node in the device tree contains a
108708 + * node or a pointer to node that holds the firmware. Technically, we should
108709 + * be fetching the firmware node for the current Fman, but we don't have that
108710 + * information any more, so we assume that there is only one firmware node in
108711 + * the device tree, and that all Fmen use the same firmware.
108712 + */
108713 +static const struct qe_firmware *FindFmanMicrocode(void)
108714 +{
108715 + static const struct qe_firmware *P4080_UCPatch;
108716 + struct device_node *np;
108717 +
108718 + if (P4080_UCPatch)
108719 + return P4080_UCPatch;
108720 +
108721 + /* The firmware should be inside the device tree. */
108722 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
108723 + if (np) {
108724 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
108725 + of_node_put(np);
108726 + if (P4080_UCPatch)
108727 + return P4080_UCPatch;
108728 + else
108729 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
108730 + }
108731 +
108732 + /* Returning NULL here forces the reuse of the IRAM content */
108733 + return NULL;
108734 +}
108735 +#define SVR_SECURITY_MASK 0x00080000
108736 +#define SVR_PERSONALITY_MASK 0x0000FF00
108737 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
108738 +#define SVR_B4860_REV1_VALUE 0x86800010
108739 +#define SVR_B4860_REV2_VALUE 0x86800020
108740 +#define SVR_T4240_VALUE 0x82400000
108741 +#define SVR_T4120_VALUE 0x82400100
108742 +#define SVR_T4160_VALUE 0x82410000
108743 +#define SVR_T4080_VALUE 0x82410200
108744 +#define SVR_T4_DEVICE_ID 0x82400000
108745 +#define SVR_DEVICE_ID_MASK 0xFFF00000
108746 +
108747 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
108748 +
108749 +/* searches for a subnode with the given name/compatible */
108750 +static bool HasFmPcdOfNode(struct device_node *fm_node,
108751 + struct of_device_id *ids,
108752 + const char *name,
108753 + const char *compatible)
108754 +{
108755 + struct device_node *dev_node;
108756 + bool ret = false;
108757 +
108758 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
108759 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
108760 + return false;
108761 + strcpy(ids[0].name, name);
108762 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
108763 + return false;
108764 + strcpy(ids[0].compatible, compatible);
108765 + for_each_child_of_node(fm_node, dev_node)
108766 + if (of_match_node(ids, dev_node) != NULL)
108767 + ret = true;
108768 + return ret;
108769 +}
108770 +
108771 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
108772 +{
108773 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108774 + struct device_node *fm_node, *dev_node;
108775 + struct of_device_id ids[OF_DEV_ID_NUM];
108776 + struct resource res;
108777 + struct clk *clk;
108778 + u32 clk_rate;
108779 + const uint32_t *uint32_prop;
108780 + int _errno=0, lenp;
108781 + uint32_t tmp_prop;
108782 +
108783 + fm_node = of_node_get(of_dev->dev.of_node);
108784 +
108785 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
108786 + if (unlikely(uint32_prop == NULL)) {
108787 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
108788 + return NULL;
108789 + }
108790 + tmp_prop = be32_to_cpu(*uint32_prop);
108791 +
108792 + if (WARN_ON(lenp != sizeof(uint32_t)))
108793 + return NULL;
108794 +
108795 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
108796 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
108797 + return NULL;
108798 + }
108799 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
108800 + if (!p_LnxWrpFmDev) {
108801 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
108802 + return NULL;
108803 + }
108804 + p_LnxWrpFmDev->dev = &of_dev->dev;
108805 + p_LnxWrpFmDev->id = tmp_prop;
108806 +
108807 + /* Get the FM interrupt */
108808 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
108809 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
108810 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
108811 + DestroyFmDev(p_LnxWrpFmDev);
108812 + return NULL;
108813 + }
108814 +
108815 + /* Get the FM error interrupt */
108816 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
108817 +
108818 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
108819 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
108820 + DestroyFmDev(p_LnxWrpFmDev);
108821 + return NULL;
108822 + }
108823 +
108824 + /* Get the FM address */
108825 + _errno = of_address_to_resource(fm_node, 0, &res);
108826 + if (unlikely(_errno < 0)) {
108827 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
108828 + DestroyFmDev(p_LnxWrpFmDev);
108829 + return NULL;
108830 + }
108831 +
108832 +
108833 + p_LnxWrpFmDev->fmBaseAddr = 0;
108834 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
108835 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
108836 +
108837 + clk = of_clk_get(fm_node, 0);
108838 + if (IS_ERR(clk)) {
108839 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
108840 + __func__);
108841 + of_node_put(fm_node);
108842 + DestroyFmDev(p_LnxWrpFmDev);
108843 + return NULL;
108844 + }
108845 +
108846 + clk_rate = clk_get_rate(clk);
108847 + if (!clk_rate) {
108848 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
108849 + __func__);
108850 + of_node_put(fm_node);
108851 + DestroyFmDev(p_LnxWrpFmDev);
108852 + return NULL;
108853 + }
108854 +
108855 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
108856 + /* Get the MURAM base address and size */
108857 + memset(ids, 0, sizeof(ids));
108858 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
108859 + return NULL;
108860 + strcpy(ids[0].name, "muram");
108861 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
108862 + return NULL;
108863 + strcpy(ids[0].compatible, "fsl,fman-muram");
108864 + for_each_child_of_node(fm_node, dev_node) {
108865 + if (likely(of_match_node(ids, dev_node) != NULL)) {
108866 + _errno = of_address_to_resource(dev_node, 0, &res);
108867 + if (unlikely(_errno < 0)) {
108868 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
108869 + DestroyFmDev(p_LnxWrpFmDev);
108870 + return NULL;
108871 + }
108872 +
108873 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
108874 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
108875 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
108876 +
108877 +#ifndef CONFIG_FMAN_ARM
108878 + {
108879 + uint32_t svr;
108880 + svr = mfspr(SPRN_SVR);
108881 +
108882 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
108883 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
108884 + }
108885 +#endif
108886 + }
108887 + }
108888 +
108889 + /* Get the RTC base address and size */
108890 + memset(ids, 0, sizeof(ids));
108891 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
108892 + return NULL;
108893 + strcpy(ids[0].name, "ptp-timer");
108894 + if (WARN_ON(strlen("fsl,fman-ptp-timer") >= sizeof(ids[0].compatible)))
108895 + return NULL;
108896 + strcpy(ids[0].compatible, "fsl,fman-ptp-timer");
108897 + for_each_child_of_node(fm_node, dev_node) {
108898 + if (likely(of_match_node(ids, dev_node) != NULL)) {
108899 + _errno = of_address_to_resource(dev_node, 0, &res);
108900 + if (unlikely(_errno < 0)) {
108901 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
108902 + DestroyFmDev(p_LnxWrpFmDev);
108903 + return NULL;
108904 + }
108905 +
108906 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
108907 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
108908 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
108909 + }
108910 + }
108911 +
108912 +#if (DPAA_VERSION >= 11)
108913 + /* Get the VSP base address */
108914 + for_each_child_of_node(fm_node, dev_node) {
108915 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
108916 + _errno = of_address_to_resource(dev_node, 0, &res);
108917 + if (unlikely(_errno < 0)) {
108918 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
108919 + DestroyFmDev(p_LnxWrpFmDev);
108920 + return NULL;
108921 + }
108922 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
108923 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
108924 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
108925 + }
108926 + }
108927 +#endif
108928 +
108929 + /* Get all PCD nodes */
108930 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
108931 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
108932 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
108933 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
108934 +
108935 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
108936 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
108937 + p_LnxWrpFmDev->pcdActive = TRUE;
108938 +
108939 + if (p_LnxWrpFmDev->pcdActive)
108940 + {
108941 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
108942 + if (str_prop) {
108943 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
108944 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
108945 + }
108946 + else
108947 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
108948 + }
108949 +
108950 + of_node_put(fm_node);
108951 +
108952 + p_LnxWrpFmDev->hcCh =
108953 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
108954 +
108955 + p_LnxWrpFmDev->active = TRUE;
108956 +
108957 + return p_LnxWrpFmDev;
108958 +}
108959 +
108960 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
108961 +{
108962 + struct device_node *dev_node;
108963 + const uint32_t *uint32_prop;
108964 + int lenp;
108965 + uint32_t tmp_prop;
108966 +
108967 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
108968 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
108969 + if (unlikely(uint32_prop == NULL)) {
108970 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
108971 + ("of_get_property(%s, cell-index) failed",
108972 + dev_node->full_name));
108973 + return NULL;
108974 + }
108975 + tmp_prop = be32_to_cpu(*uint32_prop);
108976 + if (WARN_ON(lenp != sizeof(uint32_t)))
108977 + return NULL;
108978 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
108979 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
108980 + return NULL;
108981 + }
108982 + if (fmIndx == tmp_prop)
108983 + return dev_node;
108984 + }
108985 +
108986 + return NULL;
108987 +}
108988 +
108989 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
108990 +{
108991 + struct device_node *dev_node;
108992 + t_Error err = E_INVALID_VALUE;
108993 + const uint32_t *uint32_prop;
108994 + const char *str_prop;
108995 + int lenp;
108996 + uint32_t tmp_prop;
108997 +
108998 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
108999 + if (!dev_node) /* no advance parameters for FMan */
109000 + return E_OK;
109001 +
109002 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
109003 + if (str_prop) {
109004 + if (strcmp(str_prop, "port") == 0)
109005 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
109006 + else if (strcmp(str_prop, "tnum") == 0)
109007 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
109008 +
109009 + if (err != E_OK)
109010 + RETURN_ERROR(MINOR, err, NO_MSG);
109011 + }
109012 +
109013 + uint32_prop = (uint32_t *)of_get_property(dev_node,
109014 + "total-fifo-size", &lenp);
109015 + if (uint32_prop) {
109016 + tmp_prop = be32_to_cpu(*uint32_prop);
109017 + if (WARN_ON(lenp != sizeof(uint32_t)))
109018 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109019 +
109020 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
109021 + tmp_prop) != E_OK)
109022 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109023 + }
109024 +
109025 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
109026 + &lenp);
109027 + if (uint32_prop) {
109028 + tmp_prop = be32_to_cpu(*uint32_prop);
109029 + if (WARN_ON(lenp != sizeof(uint32_t)))
109030 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109031 +
109032 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
109033 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
109034 +
109035 + if (err != E_OK)
109036 + RETURN_ERROR(MINOR, err, NO_MSG);
109037 + }
109038 +
109039 + of_node_put(dev_node);
109040 +
109041 + return E_OK;
109042 +}
109043 +
109044 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
109045 +{
109046 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
109047 +
109048 + ASSERT_COND(p_LnxWrpFmDev);
109049 +
109050 + DBG(INFO, ("got fm exception %d", exception));
109051 +
109052 + /* do nothing */
109053 + UNUSED(exception);
109054 +}
109055 +
109056 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
109057 + e_FmPortType portType,
109058 + uint8_t portId,
109059 + uint64_t addr,
109060 + uint8_t tnum,
109061 + uint16_t liodn)
109062 +{
109063 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
109064 +
109065 + ASSERT_COND(p_LnxWrpFmDev);
109066 +
109067 + /* do nothing */
109068 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
109069 +}
109070 +
109071 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
109072 +{
109073 + struct resource *dev_res;
109074 + int _errno;
109075 +
109076 + if (!p_LnxWrpFmDev->active)
109077 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
109078 +
109079 +#ifndef MODULE
109080 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
109081 + if (unlikely(_errno < 0))
109082 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
109083 +#endif
109084 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
109085 + if (unlikely(_errno < 0))
109086 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
109087 +
109088 + enable_irq_wake(p_LnxWrpFmDev->irq);
109089 +
109090 + if (p_LnxWrpFmDev->err_irq != 0) {
109091 +#ifndef MODULE
109092 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
109093 + if (unlikely(_errno < 0))
109094 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
109095 +#endif
109096 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
109097 + if (unlikely(_errno < 0))
109098 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
109099 +
109100 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
109101 + }
109102 +
109103 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
109104 + if (unlikely(p_LnxWrpFmDev->res == NULL))
109105 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
109106 +
109107 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
109108 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
109109 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109110 +
109111 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
109112 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
109113 +
109114 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
109115 + if (unlikely(dev_res == NULL))
109116 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
109117 +
109118 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
109119 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
109120 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109121 +
109122 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
109123 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
109124 +
109125 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
109126 + {
109127 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-ptp-timer");
109128 + if (unlikely(dev_res == NULL))
109129 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
109130 +
109131 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
109132 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
109133 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109134 +
109135 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
109136 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
109137 + }
109138 +
109139 +#if (DPAA_VERSION >= 11)
109140 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
109141 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
109142 + if (unlikely(dev_res == NULL))
109143 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
109144 +
109145 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
109146 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
109147 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109148 + }
109149 +#endif
109150 +
109151 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
109152 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
109153 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
109154 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
109155 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
109156 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
109157 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
109158 +
109159 + return FillRestFmInfo(p_LnxWrpFmDev);
109160 +}
109161 +
109162 +#ifndef CONFIG_FMAN_ARM
109163 +/*
109164 + * Table for matching compatible strings, for device tree
109165 + * guts node, for QorIQ SOCs.
109166 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
109167 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
109168 + * string would be used.
109169 +*/
109170 +static const struct of_device_id guts_device_ids[] = {
109171 + { .compatible = "fsl,qoriq-device-config-1.0", },
109172 + { .compatible = "fsl,qoriq-device-config-2.0", },
109173 + {}
109174 +};
109175 +
109176 +static unsigned int get_rcwsr(int regnum)
109177 +{
109178 + struct ccsr_guts __iomem *guts_regs = NULL;
109179 + struct device_node *guts_node;
109180 +
109181 + guts_node = of_find_matching_node(NULL, guts_device_ids);
109182 + if (!guts_node) {
109183 + pr_err("could not find GUTS node\n");
109184 + return 0;
109185 + }
109186 + guts_regs = of_iomap(guts_node, 0);
109187 + of_node_put(guts_node);
109188 + if (!guts_regs) {
109189 + pr_err("ioremap of GUTS node failed\n");
109190 + return 0;
109191 + }
109192 +
109193 + return ioread32be(&guts_regs->rcwsr[regnum]);
109194 +}
109195 +
109196 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
109197 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
109198 +
109199 +/**
109200 + * @Function ResetOnInitErrata_A007273
109201 + *
109202 + * @Description Workaround for Errata A-007273
109203 + * This workaround is required to avoid a FMan hang during reset on initialization.
109204 + * Enable all MACs in guts.devdisr2 register,
109205 + * then perform a regular FMan reset and then restore MACs to their original state.
109206 + *
109207 + * @Param[in] h_Fm - FM module descriptor
109208 + *
109209 + * @Return None.
109210 + */
109211 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
109212 +{
109213 + struct ccsr_guts __iomem *guts_regs = NULL;
109214 + struct device_node *guts_node;
109215 + u32 devdisr2, enableMacs;
109216 +
109217 + /* Get guts registers */
109218 + guts_node = of_find_matching_node(NULL, guts_device_ids);
109219 + if (!guts_node) {
109220 + pr_err("could not find GUTS node\n");
109221 + return;
109222 + }
109223 + guts_regs = of_iomap(guts_node, 0);
109224 + of_node_put(guts_node);
109225 + if (!guts_regs) {
109226 + pr_err("ioremap of GUTS node failed\n");
109227 + return;
109228 + }
109229 +
109230 + /* Read current state */
109231 + devdisr2 = ioread32be(&guts_regs->devdisr2);
109232 +
109233 + if (FmGetId(h_Fm) == 0)
109234 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
109235 + else
109236 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
109237 +
109238 + /* Enable all MACs */
109239 + iowrite32be(enableMacs, &guts_regs->devdisr2);
109240 +
109241 + /* Perform standard FMan reset */
109242 + FmReset(h_Fm);
109243 +
109244 + /* Restore devdisr2 value */
109245 + iowrite32be(devdisr2, &guts_regs->devdisr2);
109246 +
109247 + iounmap(guts_regs);
109248 +}
109249 +#endif
109250 +
109251 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
109252 +{
109253 + const struct qe_firmware *fw;
109254 +
109255 + if (!p_LnxWrpFmDev->active)
109256 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
109257 +
109258 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
109259 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
109260 +
109261 + /* Loading the fman-controller code */
109262 + fw = FindFmanMicrocode();
109263 +
109264 + if (!fw) {
109265 + /* this forces the reuse of the current IRAM content */
109266 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
109267 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
109268 + } else {
109269 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
109270 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
109271 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
109272 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
109273 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
109274 + fw->microcode[0].major,
109275 + fw->microcode[0].minor,
109276 + fw->microcode[0].revision));
109277 + }
109278 +
109279 +#ifdef CONFIG_FMAN_ARM
109280 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
109281 + int i;
109282 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
109283 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
109284 + u32 *dest = kzalloc(usz, GFP_KERNEL);
109285 +
109286 + if (p_Code && dest)
109287 + for(i=0; i < usz / 4; ++i)
109288 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
109289 +
109290 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
109291 + }
109292 +#endif
109293 +
109294 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
109295 +
109296 +#if (DPAA_VERSION >= 11)
109297 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
109298 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
109299 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
109300 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
109301 + }
109302 +#endif
109303 +
109304 +#ifdef CONFIG_FMAN_ARM
109305 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
109306 +#else
109307 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
109308 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
109309 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
109310 + else
109311 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
109312 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
109313 +
109314 + {
109315 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
109316 + uint32_t svr;
109317 + svr = mfspr(SPRN_SVR);
109318 +
109319 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
109320 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
109321 + }
109322 +#endif /* CONFIG_FMAN_ARM */
109323 +
109324 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
109325 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
109326 +
109327 +
109328 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
109329 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109330 +
109331 +#ifndef CONFIG_FMAN_ARM
109332 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
109333 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
109334 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109335 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
109336 +#endif /* CONFIG_FMAN_ARM */
109337 +
109338 +#ifdef CONFIG_FMAN_P1023
109339 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
109340 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109341 +#endif
109342 +
109343 +
109344 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
109345 +
109346 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
109347 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109348 +
109349 + /* TODO: Why we mask these interrupts? */
109350 + if (p_LnxWrpFmDev->err_irq == 0) {
109351 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
109352 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
109353 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
109354 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
109355 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
109356 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
109357 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
109358 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
109359 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
109360 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
109361 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
109362 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
109363 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
109364 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
109365 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
109366 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
109367 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
109368 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
109369 + }
109370 +
109371 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
109372 + {
109373 + t_FmRtcParams fmRtcParam;
109374 +
109375 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
109376 + fmRtcParam.h_App = p_LnxWrpFmDev;
109377 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
109378 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
109379 +
109380 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
109381 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
109382 +
109383 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
109384 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
109385 +
109386 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
109387 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
109388 + }
109389 +
109390 + return E_OK;
109391 +}
109392 +
109393 +/* TODO: to be moved back here */
109394 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
109395 +
109396 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
109397 +{
109398 + if (!p_LnxWrpFmDev->active)
109399 + return;
109400 +
109401 + FreeFmPcdDev(p_LnxWrpFmDev);
109402 +
109403 + if (p_LnxWrpFmDev->h_RtcDev)
109404 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
109405 +
109406 + if (p_LnxWrpFmDev->h_Dev)
109407 + FM_Free(p_LnxWrpFmDev->h_Dev);
109408 +
109409 + if (p_LnxWrpFmDev->h_MuramDev)
109410 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
109411 +
109412 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
109413 + {
109414 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
109415 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
109416 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
109417 + }
109418 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
109419 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
109420 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
109421 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
109422 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
109423 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
109424 + if (p_LnxWrpFmDev->err_irq != 0) {
109425 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
109426 + }
109427 +
109428 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
109429 +}
109430 +
109431 +/* FMan character device file operations */
109432 +extern struct file_operations fm_fops;
109433 +
109434 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
109435 +{
109436 + t_LnxWrpFmDev *p_LnxWrpFmDev;
109437 +
109438 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
109439 + return -EIO;
109440 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
109441 + return -EIO;
109442 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
109443 + return -EIO;
109444 +
109445 + /* IOCTL ABI checking */
109446 + LnxWrpPCDIOCTLEnumChecking();
109447 + LnxWrpPCDIOCTLTypeChecking();
109448 +
109449 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
109450 +
109451 + /* Register to the /dev for IOCTL API */
109452 + /* Register dynamically a new major number for the character device: */
109453 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
109454 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
109455 + return -EIO;
109456 + }
109457 +
109458 + /* Creating classes for FM */
109459 + DBG(TRACE ,("class_create fm_class"));
109460 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
109461 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
109462 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
109463 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
109464 + return -EIO;
109465 + }
109466 +
109467 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
109468 + "fm%d", p_LnxWrpFmDev->id);
109469 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
109470 + "fm%d-pcd", p_LnxWrpFmDev->id);
109471 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
109472 +
109473 + /* create sysfs entries for stats and regs */
109474 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
109475 + {
109476 + FreeFmDev(p_LnxWrpFmDev);
109477 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
109478 + return -EIO;
109479 + }
109480 +
109481 +#ifdef CONFIG_PM
109482 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
109483 +#endif
109484 +
109485 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
109486 +
109487 + return 0;
109488 +}
109489 +
109490 +static int fm_remove(struct platform_device *of_dev)
109491 +{
109492 + t_LnxWrpFmDev *p_LnxWrpFmDev;
109493 + struct device *dev;
109494 +
109495 + dev = &of_dev->dev;
109496 + p_LnxWrpFmDev = dev_get_drvdata(dev);
109497 +
109498 + fm_sysfs_destroy(dev);
109499 +
109500 + DBG(TRACE, ("destroy fm_class"));
109501 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
109502 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
109503 + class_destroy(p_LnxWrpFmDev->fm_class);
109504 +
109505 + /* Destroy chardev */
109506 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
109507 +
109508 + FreeFmDev(p_LnxWrpFmDev);
109509 +
109510 + DestroyFmDev(p_LnxWrpFmDev);
109511 +
109512 + dev_set_drvdata(dev, NULL);
109513 +
109514 + return 0;
109515 +}
109516 +
109517 +static const struct of_device_id fm_match[] = {
109518 + {
109519 + .compatible = "fsl,fman"
109520 + },
109521 + {}
109522 +};
109523 +#ifndef MODULE
109524 +MODULE_DEVICE_TABLE(of, fm_match);
109525 +#endif /* !MODULE */
109526 +
109527 +#ifdef CONFIG_PM
109528 +
109529 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
109530 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
109531 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
109532 +
109533 +struct device *g_fm_dev;
109534 +
109535 +static int fm_soc_suspend(struct device *dev)
109536 +{
109537 + int err = 0;
109538 + uint32_t *fmclk;
109539 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
109540 + g_fm_dev = dev;
109541 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
109542 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
109543 + if (p_LnxWrpFmDev->h_DsarRxPort)
109544 + {
109545 +#ifdef CONFIG_FSL_QORIQ_PM
109546 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
109547 +#endif
109548 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
109549 + p_LnxWrpFmDev->h_DsarTxPort);
109550 + }
109551 + return err;
109552 +}
109553 +
109554 +static int fm_soc_resume(struct device *dev)
109555 +{
109556 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
109557 + uint32_t *fmclk;
109558 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
109559 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
109560 + if (p_LnxWrpFmDev->h_DsarRxPort)
109561 + {
109562 +#ifdef CONFIG_FSL_QORIQ_PM
109563 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
109564 +#endif
109565 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
109566 + p_LnxWrpFmDev->h_DsarTxPort);
109567 + p_LnxWrpFmDev->h_DsarRxPort = 0;
109568 + p_LnxWrpFmDev->h_DsarTxPort = 0;
109569 + }
109570 + return 0;
109571 +}
109572 +
109573 +static const struct dev_pm_ops fm_pm_ops = {
109574 + .suspend = fm_soc_suspend,
109575 + .resume = fm_soc_resume,
109576 +};
109577 +
109578 +#define FM_PM_OPS (&fm_pm_ops)
109579 +
109580 +#else /* CONFIG_PM */
109581 +
109582 +#define FM_PM_OPS NULL
109583 +
109584 +#endif /* CONFIG_PM */
109585 +
109586 +static struct platform_driver fm_driver = {
109587 + .driver = {
109588 + .name = "fsl-fman",
109589 + .of_match_table = fm_match,
109590 + .owner = THIS_MODULE,
109591 + .pm = FM_PM_OPS,
109592 + },
109593 + .probe = fm_probe,
109594 + .remove = fm_remove
109595 +};
109596 +
109597 +t_Handle LNXWRP_FM_Init(void)
109598 +{
109599 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
109600 + mutex_init(&lnxwrp_mutex);
109601 +
109602 + /* Register to the DTB for basic FM API */
109603 + platform_driver_register(&fm_driver);
109604 +
109605 + return &lnxWrpFm;
109606 +}
109607 +
109608 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
109609 +{
109610 + platform_driver_unregister(&fm_driver);
109611 + mutex_destroy(&lnxwrp_mutex);
109612 +
109613 + return E_OK;
109614 +}
109615 +
109616 +
109617 +struct fm * fm_bind(struct device *fm_dev)
109618 +{
109619 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
109620 +}
109621 +EXPORT_SYMBOL(fm_bind);
109622 +
109623 +void fm_unbind(struct fm *fm)
109624 +{
109625 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
109626 +
109627 + put_device(p_LnxWrpFmDev->dev);
109628 +}
109629 +EXPORT_SYMBOL(fm_unbind);
109630 +
109631 +struct resource * fm_get_mem_region(struct fm *fm)
109632 +{
109633 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
109634 +
109635 + return p_LnxWrpFmDev->res;
109636 +}
109637 +EXPORT_SYMBOL(fm_get_mem_region);
109638 +
109639 +void * fm_get_handle(struct fm *fm)
109640 +{
109641 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
109642 +
109643 + return (void *)p_LnxWrpFmDev->h_Dev;
109644 +}
109645 +EXPORT_SYMBOL(fm_get_handle);
109646 +
109647 +void * fm_get_rtc_handle(struct fm *fm)
109648 +{
109649 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
109650 +
109651 + return (void *)p_LnxWrpFmDev->h_RtcDev;
109652 +}
109653 +EXPORT_SYMBOL(fm_get_rtc_handle);
109654 +
109655 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
109656 +{
109657 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
109658 +}
109659 +EXPORT_SYMBOL(fm_port_bind);
109660 +
109661 +void fm_port_unbind(struct fm_port *port)
109662 +{
109663 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
109664 +
109665 + put_device(p_LnxWrpFmPortDev->dev);
109666 +}
109667 +EXPORT_SYMBOL(fm_port_unbind);
109668 +
109669 +void *fm_port_get_handle(const struct fm_port *port)
109670 +{
109671 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
109672 +
109673 + return (void *)p_LnxWrpFmPortDev->h_Dev;
109674 +}
109675 +EXPORT_SYMBOL(fm_port_get_handle);
109676 +
109677 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
109678 + const void *data)
109679 +{
109680 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
109681 + (void *)data);
109682 +}
109683 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
109684 +
109685 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
109686 +{
109687 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109688 +
109689 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
109690 +}
109691 +EXPORT_SYMBOL(fm_port_get_base_addr);
109692 +
109693 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
109694 +{
109695 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
109696 +
109697 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
109698 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
109699 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
109700 +}
109701 +EXPORT_SYMBOL(fm_port_pcd_bind);
109702 +
109703 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
109704 +{
109705 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109706 + struct device_node *fm_node, *port_node;
109707 + const uint32_t *uint32_prop;
109708 + int lenp;
109709 +
109710 + params->data_align = 0;
109711 + params->manip_extra_space = 0;
109712 +
109713 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
109714 + if (!fm_node) /* no advance parameters for FMan */
109715 + return;
109716 +
109717 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
109718 + p_LnxWrpFmPortDev->settings.param.portType,
109719 + p_LnxWrpFmPortDev->settings.param.portId);
109720 + if (!port_node) /* no advance parameters for FMan-Port */
109721 + return;
109722 +
109723 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
109724 + if (uint32_prop) {
109725 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
109726 + return;
109727 +
109728 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
109729 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
109730 + }
109731 +
109732 + of_node_put(port_node);
109733 + of_node_put(fm_node);
109734 +}
109735 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
109736 +
109737 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
109738 +{
109739 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
109740 +
109741 + return p_LnxWrpFmPortDev->txCh;
109742 +}
109743 +EXPORT_SYMBOL(fm_get_tx_port_channel);
109744 +
109745 +int fm_port_enable (struct fm_port *port)
109746 +{
109747 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
109748 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
109749 +
109750 + return GET_ERROR_TYPE(err);
109751 +}
109752 +EXPORT_SYMBOL(fm_port_enable);
109753 +
109754 +int fm_port_disable(struct fm_port *port)
109755 +{
109756 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
109757 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
109758 +
109759 + return GET_ERROR_TYPE(err);
109760 +}
109761 +EXPORT_SYMBOL(fm_port_disable);
109762 +
109763 +int fm_port_set_rate_limit(struct fm_port *port,
109764 + uint16_t max_burst_size,
109765 + uint32_t rate_limit)
109766 +{
109767 + t_FmPortRateLimit param;
109768 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109769 + int err = 0;
109770 +
109771 + param.maxBurstSize = max_burst_size;
109772 + param.rateLimit = rate_limit;
109773 + param.rateLimitDivider = 0;
109774 +
109775 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
109776 + return err;
109777 +}
109778 +EXPORT_SYMBOL(fm_port_set_rate_limit);
109779 +
109780 +int fm_port_del_rate_limit(struct fm_port *port)
109781 +{
109782 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109783 +
109784 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
109785 + return 0;
109786 +}
109787 +EXPORT_SYMBOL(fm_port_del_rate_limit);
109788 +
109789 +void FM_PORT_Dsar_DumpRegs(void);
109790 +int ar_showmem(struct file *file, const char __user *buffer,
109791 + unsigned long count, void *data)
109792 +{
109793 + FM_PORT_Dsar_DumpRegs();
109794 + return 2;
109795 +}
109796 +
109797 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
109798 + struct fm_port *port)
109799 +{
109800 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109801 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
109802 +}
109803 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
109804 +
109805 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
109806 + struct auto_res_port_params *params)
109807 +{
109808 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109809 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
109810 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
109811 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
109812 +
109813 + /*Register other under /proc/autoresponse */
109814 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
109815 + return -EFAULT;
109816 +
109817 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
109818 + return 0;
109819 +}
109820 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
109821 +
109822 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
109823 + struct fm_port *port_tx)
109824 +{
109825 +}
109826 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
109827 +
109828 +int fm_port_get_autores_stats(struct fm_port *port,
109829 + struct auto_res_port_stats *stats)
109830 +{
109831 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109832 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
109833 + return -EFAULT;
109834 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
109835 +}
109836 +EXPORT_SYMBOL(fm_port_get_autores_stats);
109837 +
109838 +int fm_port_suspend(struct fm_port *port)
109839 +{
109840 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109841 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
109842 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
109843 + else
109844 + return 0;
109845 +}
109846 +EXPORT_SYMBOL(fm_port_suspend);
109847 +
109848 +int fm_port_resume(struct fm_port *port)
109849 +{
109850 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109851 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
109852 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
109853 + else
109854 + return 0;
109855 +}
109856 +EXPORT_SYMBOL(fm_port_resume);
109857 +
109858 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
109859 +{
109860 + return FM_PORT_IsInDsar(port);
109861 +}
109862 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
109863 +
109864 +#ifdef CONFIG_FMAN_PFC
109865 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
109866 + uint8_t prio, uint8_t wq)
109867 +{
109868 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109869 + int err;
109870 + int _errno;
109871 +
109872 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
109873 + prio, wq);
109874 + _errno = -GET_ERROR_TYPE(err);
109875 + if (unlikely(_errno < 0))
109876 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
109877 +
109878 + return _errno;
109879 +}
109880 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
109881 +#endif
109882 +
109883 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
109884 + e_FmMacExceptions exception, bool enable)
109885 +{
109886 + int err;
109887 + int _errno;
109888 +
109889 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
109890 +
109891 + _errno = -GET_ERROR_TYPE(err);
109892 + if (unlikely(_errno < 0))
109893 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
109894 +
109895 + return _errno;
109896 +}
109897 +EXPORT_SYMBOL(fm_mac_set_exception);
109898 +
109899 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
109900 +{
109901 + int err;
109902 + int _error;
109903 +
109904 + err = FM_MAC_Free(fm_mac_dev);
109905 + _error = -GET_ERROR_TYPE(err);
109906 +
109907 + if (unlikely(_error < 0))
109908 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
109909 +
109910 + return _error;
109911 +}
109912 +EXPORT_SYMBOL(fm_mac_free);
109913 +
109914 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
109915 +{
109916 + struct fm_mac_dev *fm_mac_dev;
109917 +
109918 + fm_mac_dev = FM_MAC_Config(params);
109919 + if (unlikely(fm_mac_dev == NULL))
109920 + pr_err("FM_MAC_Config() failed\n");
109921 +
109922 + return fm_mac_dev;
109923 +}
109924 +EXPORT_SYMBOL(fm_mac_config);
109925 +
109926 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
109927 + int len)
109928 +{
109929 + int err;
109930 + int _errno;
109931 +
109932 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
109933 + _errno = -GET_ERROR_TYPE(err);
109934 + if (unlikely(_errno < 0))
109935 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
109936 +
109937 + return _errno;
109938 +}
109939 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
109940 +
109941 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
109942 +{
109943 + int err;
109944 + int _errno;
109945 +
109946 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
109947 + _errno = -GET_ERROR_TYPE(err);
109948 + if (unlikely(_errno < 0))
109949 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
109950 +
109951 + return _errno;
109952 +}
109953 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
109954 +
109955 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
109956 +{
109957 + int err;
109958 + int _errno;
109959 +
109960 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
109961 + _errno = -GET_ERROR_TYPE(err);
109962 + if (unlikely(_errno < 0))
109963 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
109964 +
109965 + return _errno;
109966 +}
109967 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
109968 +
109969 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
109970 +{
109971 + int err;
109972 + int _errno;
109973 +
109974 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
109975 + _errno = -GET_ERROR_TYPE(err);
109976 + if (unlikely(_errno < 0))
109977 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
109978 +
109979 + return _errno;
109980 +}
109981 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
109982 +
109983 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
109984 +{
109985 + int err;
109986 + int _errno;
109987 +
109988 + err = FM_MAC_Init(fm_mac_dev);
109989 + _errno = -GET_ERROR_TYPE(err);
109990 + if (unlikely(_errno < 0))
109991 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
109992 +
109993 + return _errno;
109994 +}
109995 +EXPORT_SYMBOL(fm_mac_init);
109996 +
109997 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
109998 +{
109999 + int err;
110000 + int _errno;
110001 +
110002 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
110003 + _errno = -GET_ERROR_TYPE(err);
110004 + if (unlikely(_errno < 0))
110005 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
110006 +
110007 + return _errno;
110008 +}
110009 +EXPORT_SYMBOL(fm_mac_get_version);
110010 +
110011 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
110012 +{
110013 + int _errno;
110014 + t_Error err;
110015 +
110016 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
110017 + _errno = -GET_ERROR_TYPE(err);
110018 + if (unlikely(_errno < 0))
110019 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
110020 +
110021 + return _errno;
110022 +}
110023 +EXPORT_SYMBOL(fm_mac_enable);
110024 +
110025 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
110026 +{
110027 + int _errno;
110028 + t_Error err;
110029 +
110030 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
110031 + _errno = -GET_ERROR_TYPE(err);
110032 + if (unlikely(_errno < 0))
110033 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
110034 +
110035 + return _errno;
110036 +}
110037 +EXPORT_SYMBOL(fm_mac_disable);
110038 +
110039 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
110040 +{
110041 + int _errno;
110042 + t_Error err;
110043 +
110044 + err = FM_MAC_Resume(fm_mac_dev);
110045 + _errno = -GET_ERROR_TYPE(err);
110046 + if (unlikely(_errno < 0))
110047 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
110048 +
110049 + return _errno;
110050 +}
110051 +EXPORT_SYMBOL(fm_mac_resume);
110052 +
110053 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
110054 + bool enable)
110055 +{
110056 + int _errno;
110057 + t_Error err;
110058 +
110059 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
110060 + _errno = -GET_ERROR_TYPE(err);
110061 + if (unlikely(_errno < 0))
110062 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
110063 +
110064 + return _errno;
110065 +}
110066 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
110067 +
110068 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
110069 + t_EnetAddr *mac_addr)
110070 +{
110071 + int _errno;
110072 + t_Error err;
110073 +
110074 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
110075 + _errno = -GET_ERROR_TYPE(err);
110076 + if (_errno < 0) {
110077 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
110078 + return _errno;
110079 + }
110080 +
110081 + return 0;
110082 +}
110083 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
110084 +
110085 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
110086 + t_EnetAddr *mac_addr)
110087 +{
110088 + int _errno;
110089 + t_Error err;
110090 +
110091 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
110092 + _errno = -GET_ERROR_TYPE(err);
110093 + if (_errno < 0) {
110094 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
110095 + return _errno;
110096 + }
110097 +
110098 + return 0;
110099 +}
110100 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
110101 +
110102 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
110103 + uint8_t *addr)
110104 +{
110105 + int _errno;
110106 + t_Error err;
110107 +
110108 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
110109 + _errno = -GET_ERROR_TYPE(err);
110110 + if (_errno < 0)
110111 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
110112 +
110113 + return _errno;
110114 +}
110115 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
110116 +
110117 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
110118 + bool link, int speed, bool duplex)
110119 +{
110120 + int _errno;
110121 + t_Error err;
110122 +
110123 + if (!link) {
110124 +#if (DPAA_VERSION < 11)
110125 + FM_MAC_RestartAutoneg(fm_mac_dev);
110126 +#endif
110127 + return 0;
110128 + }
110129 +
110130 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
110131 + _errno = -GET_ERROR_TYPE(err);
110132 + if (unlikely(_errno < 0))
110133 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
110134 +
110135 + return _errno;
110136 +}
110137 +EXPORT_SYMBOL(fm_mac_adjust_link);
110138 +
110139 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
110140 +{
110141 + int _errno;
110142 + t_Error err;
110143 +
110144 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
110145 + _errno = -GET_ERROR_TYPE(err);
110146 + if (unlikely(_errno < 0))
110147 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
110148 + return _errno;
110149 +}
110150 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
110151 +
110152 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
110153 +{
110154 + int _errno;
110155 + t_Error err;
110156 +
110157 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
110158 + _errno = -GET_ERROR_TYPE(err);
110159 + if (unlikely(_errno < 0))
110160 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
110161 + return _errno;
110162 +}
110163 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
110164 +
110165 +int fm_mac_set_rx_pause_frames(
110166 + struct fm_mac_dev *fm_mac_dev, bool en)
110167 +{
110168 + int _errno;
110169 + t_Error err;
110170 +
110171 + /* if rx pause is enabled, do NOT ignore pause frames */
110172 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
110173 +
110174 + _errno = -GET_ERROR_TYPE(err);
110175 + if (_errno < 0)
110176 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
110177 +
110178 + return _errno;
110179 +}
110180 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
110181 +
110182 +#ifdef CONFIG_FMAN_PFC
110183 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
110184 + bool en)
110185 +{
110186 + int _errno, i;
110187 + t_Error err;
110188 +
110189 + if (en)
110190 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
110191 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
110192 + i, fsl_fm_pfc_quanta[i],
110193 + FSL_FM_PAUSE_THRESH_DEFAULT);
110194 + _errno = -GET_ERROR_TYPE(err);
110195 + if (_errno < 0) {
110196 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
110197 + return _errno;
110198 + }
110199 + }
110200 + else
110201 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
110202 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
110203 + i, FSL_FM_PAUSE_TIME_DISABLE,
110204 + FSL_FM_PAUSE_THRESH_DEFAULT);
110205 + _errno = -GET_ERROR_TYPE(err);
110206 + if (_errno < 0) {
110207 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
110208 + return _errno;
110209 + }
110210 + }
110211 +
110212 + return _errno;
110213 +}
110214 +#else
110215 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
110216 + bool en)
110217 +{
110218 + int _errno;
110219 + t_Error err;
110220 +
110221 + if (en)
110222 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
110223 + FSL_FM_PAUSE_TIME_ENABLE);
110224 + else
110225 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
110226 + FSL_FM_PAUSE_TIME_DISABLE);
110227 +
110228 + _errno = -GET_ERROR_TYPE(err);
110229 + if (_errno < 0)
110230 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
110231 +
110232 + return _errno;
110233 +}
110234 +#endif
110235 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
110236 +
110237 +int fm_rtc_enable(struct fm *fm_dev)
110238 +{
110239 + int _errno;
110240 + t_Error err;
110241 +
110242 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
110243 + _errno = -GET_ERROR_TYPE(err);
110244 + if (unlikely(_errno < 0))
110245 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
110246 +
110247 + return _errno;
110248 +}
110249 +EXPORT_SYMBOL(fm_rtc_enable);
110250 +
110251 +int fm_rtc_disable(struct fm *fm_dev)
110252 +{
110253 + int _errno;
110254 + t_Error err;
110255 +
110256 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
110257 + _errno = -GET_ERROR_TYPE(err);
110258 + if (unlikely(_errno < 0))
110259 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
110260 +
110261 + return _errno;
110262 +}
110263 +EXPORT_SYMBOL(fm_rtc_disable);
110264 +
110265 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
110266 +{
110267 + int _errno;
110268 + t_Error err;
110269 +
110270 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
110271 + _errno = -GET_ERROR_TYPE(err);
110272 + if (unlikely(_errno < 0))
110273 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
110274 +
110275 + return _errno;
110276 +}
110277 +EXPORT_SYMBOL(fm_rtc_get_cnt);
110278 +
110279 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
110280 +{
110281 + int _errno;
110282 + t_Error err;
110283 +
110284 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
110285 + _errno = -GET_ERROR_TYPE(err);
110286 + if (unlikely(_errno < 0))
110287 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
110288 +
110289 + return _errno;
110290 +}
110291 +EXPORT_SYMBOL(fm_rtc_set_cnt);
110292 +
110293 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
110294 +{
110295 + int _errno;
110296 + t_Error err;
110297 +
110298 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
110299 + drift);
110300 + _errno = -GET_ERROR_TYPE(err);
110301 + if (unlikely(_errno < 0))
110302 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
110303 +
110304 + return _errno;
110305 +}
110306 +EXPORT_SYMBOL(fm_rtc_get_drift);
110307 +
110308 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
110309 +{
110310 + int _errno;
110311 + t_Error err;
110312 +
110313 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
110314 + drift);
110315 + _errno = -GET_ERROR_TYPE(err);
110316 + if (unlikely(_errno < 0))
110317 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
110318 +
110319 + return _errno;
110320 +}
110321 +EXPORT_SYMBOL(fm_rtc_set_drift);
110322 +
110323 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
110324 + uint64_t time)
110325 +{
110326 + t_FmRtcAlarmParams alarm;
110327 + int _errno;
110328 + t_Error err;
110329 +
110330 + alarm.alarmId = id;
110331 + alarm.alarmTime = time;
110332 + alarm.f_AlarmCallback = NULL;
110333 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
110334 + &alarm);
110335 + _errno = -GET_ERROR_TYPE(err);
110336 + if (unlikely(_errno < 0))
110337 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
110338 +
110339 + return _errno;
110340 +}
110341 +EXPORT_SYMBOL(fm_rtc_set_alarm);
110342 +
110343 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
110344 + uint64_t fiper)
110345 +{
110346 + t_FmRtcPeriodicPulseParams pp;
110347 + int _errno;
110348 + t_Error err;
110349 +
110350 + pp.periodicPulseId = id;
110351 + pp.periodicPulsePeriod = fiper;
110352 + pp.f_PeriodicPulseCallback = NULL;
110353 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
110354 + _errno = -GET_ERROR_TYPE(err);
110355 + if (unlikely(_errno < 0))
110356 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
110357 +
110358 + return _errno;
110359 +}
110360 +EXPORT_SYMBOL(fm_rtc_set_fiper);
110361 +
110362 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
110363 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
110364 +{
110365 + int _errno;
110366 + t_Error err;
110367 +
110368 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
110369 + events);
110370 + _errno = -GET_ERROR_TYPE(err);
110371 + if (unlikely(_errno < 0))
110372 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
110373 +
110374 + return _errno;
110375 +}
110376 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
110377 +
110378 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
110379 +{
110380 + int _errno;
110381 + t_Error err;
110382 +
110383 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
110384 + events);
110385 + _errno = -GET_ERROR_TYPE(err);
110386 + if (unlikely(_errno < 0))
110387 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
110388 +
110389 + return _errno;
110390 +}
110391 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
110392 +#endif
110393 +
110394 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
110395 +{
110396 + int _errno;
110397 + t_Error err;
110398 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110399 +
110400 + /* Do not set WoL on AR ports */
110401 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
110402 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
110403 + return 0;
110404 + }
110405 +
110406 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
110407 +
110408 + _errno = -GET_ERROR_TYPE(err);
110409 + if (_errno < 0)
110410 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
110411 +
110412 + return _errno;
110413 +}
110414 +EXPORT_SYMBOL(fm_mac_set_wol);
110415 +
110416 +void fm_mutex_lock(void)
110417 +{
110418 + mutex_lock(&lnxwrp_mutex);
110419 +}
110420 +EXPORT_SYMBOL(fm_mutex_lock);
110421 +
110422 +void fm_mutex_unlock(void)
110423 +{
110424 + mutex_unlock(&lnxwrp_mutex);
110425 +}
110426 +EXPORT_SYMBOL(fm_mutex_unlock);
110427 +
110428 +/*Macsec wrapper functions*/
110429 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
110430 +{
110431 + struct fm_macsec_dev *fm_macsec_dev;
110432 +
110433 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
110434 + if (unlikely(fm_macsec_dev == NULL))
110435 + pr_err("FM_MACSEC_Config() failed\n");
110436 +
110437 + return fm_macsec_dev;
110438 +}
110439 +EXPORT_SYMBOL(fm_macsec_config);
110440 +
110441 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
110442 +{
110443 + int err;
110444 + int _errno;
110445 +
110446 + err = FM_MACSEC_Init(fm_macsec_dev);
110447 + _errno = -GET_ERROR_TYPE(err);
110448 + if (unlikely(_errno < 0))
110449 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
110450 +
110451 + return _errno;
110452 +}
110453 +EXPORT_SYMBOL(fm_macsec_init);
110454 +
110455 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
110456 +{
110457 + int err;
110458 + int _error;
110459 +
110460 + err = FM_MACSEC_Free(fm_macsec_dev);
110461 + _error = -GET_ERROR_TYPE(err);
110462 +
110463 + if (unlikely(_error < 0))
110464 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
110465 +
110466 + return _error;
110467 +}
110468 +EXPORT_SYMBOL(fm_macsec_free);
110469 +
110470 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
110471 + *fm_macsec_dev,
110472 + fm_macsec_unknown_sci_frame_treatment treat_mode)
110473 +{
110474 + int err;
110475 + int _errno;
110476 +
110477 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
110478 + treat_mode);
110479 + _errno = -GET_ERROR_TYPE(err);
110480 + if (unlikely(_errno < 0))
110481 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
110482 +
110483 + return _errno;
110484 +}
110485 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
110486 +
110487 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
110488 + bool deliver_uncontrolled)
110489 +{
110490 + int err;
110491 + int _errno;
110492 +
110493 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
110494 + deliver_uncontrolled);
110495 + _errno = -GET_ERROR_TYPE(err);
110496 + if (unlikely(_errno < 0))
110497 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
110498 +
110499 + return _errno;
110500 +}
110501 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
110502 +
110503 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
110504 + bool discard_uncontrolled)
110505 +{
110506 + int err;
110507 + int _errno;
110508 +
110509 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
110510 + discard_uncontrolled);
110511 + _errno = -GET_ERROR_TYPE(err);
110512 + if (unlikely(_errno < 0))
110513 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
110514 +
110515 + return _errno;
110516 +}
110517 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
110518 +
110519 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
110520 + fm_macsec_untag_frame_treatment treat_mode)
110521 +{
110522 + int err;
110523 + int _errno;
110524 +
110525 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
110526 + _errno = -GET_ERROR_TYPE(err);
110527 + if (unlikely(_errno < 0))
110528 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
110529 +
110530 + return _errno;
110531 +}
110532 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
110533 +
110534 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
110535 + uint32_t pn_exh_thr)
110536 +{
110537 + int err;
110538 + int _errno;
110539 +
110540 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
110541 + _errno = -GET_ERROR_TYPE(err);
110542 + if (unlikely(_errno < 0))
110543 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
110544 +
110545 + return _errno;
110546 +}
110547 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
110548 +
110549 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
110550 +{
110551 + int err;
110552 + int _errno;
110553 +
110554 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
110555 + _errno = -GET_ERROR_TYPE(err);
110556 + if (unlikely(_errno < 0))
110557 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
110558 +
110559 + return _errno;
110560 +}
110561 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
110562 +
110563 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
110564 +{
110565 + int err;
110566 + int _errno;
110567 +
110568 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
110569 + _errno = -GET_ERROR_TYPE(err);
110570 + if (unlikely(_errno < 0))
110571 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
110572 +
110573 + return _errno;
110574 +}
110575 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
110576 +
110577 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
110578 + fm_macsec_exception exception, bool enable)
110579 +{
110580 + int err;
110581 + int _errno;
110582 +
110583 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
110584 + _errno = -GET_ERROR_TYPE(err);
110585 + if (unlikely(_errno < 0))
110586 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
110587 +
110588 + return _errno;
110589 +}
110590 +EXPORT_SYMBOL(fm_macsec_config_exception);
110591 +
110592 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
110593 + int *macsec_revision)
110594 +{
110595 + int err;
110596 + int _errno;
110597 +
110598 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
110599 + _errno = -GET_ERROR_TYPE(err);
110600 + if (unlikely(_errno < 0))
110601 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
110602 +
110603 + return _errno;
110604 +}
110605 +EXPORT_SYMBOL(fm_macsec_get_revision);
110606 +
110607 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
110608 +{
110609 + int err;
110610 + int _errno;
110611 +
110612 + err = FM_MACSEC_Enable(fm_macsec_dev);
110613 + _errno = -GET_ERROR_TYPE(err);
110614 + if (unlikely(_errno < 0))
110615 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
110616 +
110617 + return _errno;
110618 +}
110619 +EXPORT_SYMBOL(fm_macsec_enable);
110620 +
110621 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
110622 +{
110623 + int err;
110624 + int _errno;
110625 +
110626 + err = FM_MACSEC_Disable(fm_macsec_dev);
110627 + _errno = -GET_ERROR_TYPE(err);
110628 + if (unlikely(_errno < 0))
110629 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
110630 +
110631 + return _errno;
110632 +}
110633 +EXPORT_SYMBOL(fm_macsec_disable);
110634 +
110635 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
110636 + fm_macsec_exception exception, bool enable)
110637 +{
110638 + int err;
110639 + int _errno;
110640 +
110641 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
110642 + _errno = -GET_ERROR_TYPE(err);
110643 + if (unlikely(_errno < 0))
110644 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
110645 +
110646 + return _errno;
110647 +}
110648 +EXPORT_SYMBOL(fm_macsec_set_exception);
110649 +
110650 +/* Macsec SECY wrapper API */
110651 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
110652 +{
110653 + struct fm_macsec_secy_dev *fm_macsec_secy;
110654 +
110655 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
110656 + if (unlikely(fm_macsec_secy < 0))
110657 + pr_err("FM_MACSEC_SECY_Config() failed\n");
110658 +
110659 + return fm_macsec_secy;
110660 +}
110661 +EXPORT_SYMBOL(fm_macsec_secy_config);
110662 +
110663 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
110664 +{
110665 + int err;
110666 + int _errno;
110667 +
110668 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
110669 + _errno = -GET_ERROR_TYPE(err);
110670 + if (unlikely(_errno < 0))
110671 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
110672 +
110673 + return _errno;
110674 +}
110675 +EXPORT_SYMBOL(fm_macsec_secy_init);
110676 +
110677 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
110678 +{
110679 + int err;
110680 + int _errno;
110681 +
110682 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
110683 + _errno = -GET_ERROR_TYPE(err);
110684 + if (unlikely(_errno < 0))
110685 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
110686 +
110687 + return _errno;
110688 +}
110689 +EXPORT_SYMBOL(fm_macsec_secy_free);
110690 +
110691 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110692 + fm_macsec_sci_insertion_mode sci_insertion_mode)
110693 +{
110694 + int err;
110695 + int _errno;
110696 +
110697 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
110698 + sci_insertion_mode);
110699 + _errno = -GET_ERROR_TYPE(err);
110700 + if (unlikely(_errno < 0))
110701 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
110702 +
110703 + return _errno;
110704 +}
110705 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
110706 +
110707 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110708 + bool protect_frames)
110709 +{
110710 + int err;
110711 + int _errno;
110712 +
110713 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
110714 + protect_frames);
110715 + _errno = -GET_ERROR_TYPE(err);
110716 + if (unlikely(_errno < 0))
110717 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
110718 +
110719 + return _errno;
110720 +}
110721 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
110722 +
110723 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110724 + bool replay_protect, uint32_t replay_window)
110725 +{
110726 + int err;
110727 + int _errno;
110728 +
110729 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
110730 + replay_protect, replay_window);
110731 + _errno = -GET_ERROR_TYPE(err);
110732 + if (unlikely(_errno < 0))
110733 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
110734 +
110735 + return _errno;
110736 +}
110737 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
110738 +
110739 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110740 + fm_macsec_valid_frame_behavior validate_frames)
110741 +{
110742 + int err;
110743 + int _errno;
110744 +
110745 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
110746 + validate_frames);
110747 + _errno = -GET_ERROR_TYPE(err);
110748 + if (unlikely(_errno < 0))
110749 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
110750 +
110751 + return _errno;
110752 +}
110753 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
110754 +
110755 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110756 + bool confidentiality_enable,
110757 + uint32_t confidentiality_offset)
110758 +{
110759 + int err;
110760 + int _errno;
110761 +
110762 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
110763 + confidentiality_enable,
110764 + confidentiality_offset);
110765 + _errno = -GET_ERROR_TYPE(err);
110766 + if (unlikely(_errno < 0))
110767 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
110768 + err);
110769 +
110770 + return _errno;
110771 +}
110772 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
110773 +
110774 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
110775 +{
110776 + int err;
110777 + int _errno;
110778 +
110779 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
110780 + _errno = -GET_ERROR_TYPE(err);
110781 + if (unlikely(_errno < 0))
110782 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
110783 + err);
110784 +
110785 + return _errno;
110786 +}
110787 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
110788 +
110789 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110790 + fm_macsec_secy_exception exception,
110791 + bool enable)
110792 +{
110793 + int err;
110794 + int _errno;
110795 +
110796 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
110797 + enable);
110798 + _errno = -GET_ERROR_TYPE(err);
110799 + if (unlikely(_errno < 0))
110800 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
110801 + err);
110802 +
110803 + return _errno;
110804 +}
110805 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
110806 +
110807 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110808 + fm_macsec_secy_event event,
110809 + bool enable)
110810 +{
110811 + int err;
110812 + int _errno;
110813 +
110814 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
110815 + _errno = -GET_ERROR_TYPE(err);
110816 + if (unlikely(_errno < 0))
110817 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
110818 + err);
110819 +
110820 + return _errno;
110821 +}
110822 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
110823 +
110824 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110825 + struct fm_macsec_secy_sc_params *params)
110826 +{
110827 + struct rx_sc_dev *rx_sc_dev;
110828 +
110829 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
110830 + if (unlikely(rx_sc_dev == NULL))
110831 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
110832 +
110833 + return rx_sc_dev;
110834 +}
110835 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
110836 +
110837 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110838 + struct rx_sc_dev *sc)
110839 +{
110840 + int err;
110841 + int _errno;
110842 +
110843 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
110844 + _errno = -GET_ERROR_TYPE(err);
110845 + if (unlikely(_errno < 0))
110846 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
110847 + err);
110848 +
110849 + return _errno;
110850 +}
110851 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
110852 +
110853 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110854 + struct rx_sc_dev *sc, macsec_an_t an,
110855 + uint32_t lowest_pn, macsec_sa_key_t key)
110856 +{
110857 + int err;
110858 + int _errno;
110859 +
110860 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
110861 + lowest_pn, key);
110862 + _errno = -GET_ERROR_TYPE(err);
110863 + if (unlikely(_errno < 0))
110864 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
110865 + err);
110866 +
110867 + return _errno;
110868 +}
110869 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
110870 +
110871 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110872 + struct rx_sc_dev *sc, macsec_an_t an)
110873 +{
110874 + int err;
110875 + int _errno;
110876 +
110877 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
110878 + _errno = -GET_ERROR_TYPE(err);
110879 + if (unlikely(_errno < 0))
110880 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
110881 + err);
110882 +
110883 + return _errno;
110884 +}
110885 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
110886 +
110887 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110888 + struct rx_sc_dev *sc,
110889 + macsec_an_t an)
110890 +{
110891 + int err;
110892 + int _errno;
110893 +
110894 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
110895 + _errno = -GET_ERROR_TYPE(err);
110896 + if (unlikely(_errno < 0))
110897 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
110898 + err);
110899 +
110900 + return _errno;
110901 +}
110902 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
110903 +
110904 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110905 + struct rx_sc_dev *sc,
110906 + macsec_an_t an)
110907 +{
110908 + int err;
110909 + int _errno;
110910 +
110911 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
110912 + _errno = -GET_ERROR_TYPE(err);
110913 + if (unlikely(_errno < 0))
110914 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
110915 + err);
110916 +
110917 + return _errno;
110918 +}
110919 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
110920 +
110921 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110922 + struct rx_sc_dev *sc,
110923 + macsec_an_t an, uint32_t updt_next_pn)
110924 +{
110925 + int err;
110926 + int _errno;
110927 +
110928 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
110929 + updt_next_pn);
110930 + _errno = -GET_ERROR_TYPE(err);
110931 + if (unlikely(_errno < 0))
110932 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
110933 +
110934 + return _errno;
110935 +}
110936 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
110937 +
110938 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110939 + struct rx_sc_dev *sc,
110940 + macsec_an_t an, uint32_t updt_lowest_pn)
110941 +{
110942 + int err;
110943 + int _errno;
110944 +
110945 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
110946 + updt_lowest_pn);
110947 + _errno = -GET_ERROR_TYPE(err);
110948 + if (unlikely(_errno < 0))
110949 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
110950 + err);
110951 +
110952 + return _errno;
110953 +}
110954 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
110955 +
110956 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110957 + struct rx_sc_dev *sc,
110958 + macsec_an_t an, macsec_sa_key_t key)
110959 +{
110960 + int err;
110961 + int _errno;
110962 +
110963 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
110964 + _errno = -GET_ERROR_TYPE(err);
110965 + if (unlikely(_errno < 0))
110966 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
110967 + err);
110968 +
110969 + return _errno;
110970 +}
110971 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
110972 +
110973 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110974 + macsec_an_t an, macsec_sa_key_t key)
110975 +{
110976 + int err;
110977 + int _errno;
110978 +
110979 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
110980 + _errno = -GET_ERROR_TYPE(err);
110981 + if (unlikely(_errno < 0))
110982 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
110983 + err);
110984 +
110985 + return _errno;
110986 +}
110987 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
110988 +
110989 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
110990 + macsec_an_t an)
110991 +{
110992 + int err;
110993 + int _errno;
110994 +
110995 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
110996 + _errno = -GET_ERROR_TYPE(err);
110997 + if (unlikely(_errno < 0))
110998 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
110999 + err);
111000 +
111001 + return _errno;
111002 +}
111003 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
111004 +
111005 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111006 + macsec_an_t next_active_an,
111007 + macsec_sa_key_t key)
111008 +{
111009 + int err;
111010 + int _errno;
111011 +
111012 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
111013 + key);
111014 + _errno = -GET_ERROR_TYPE(err);
111015 + if (unlikely(_errno < 0))
111016 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
111017 + err);
111018 +
111019 + return _errno;
111020 +}
111021 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
111022 +
111023 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111024 + macsec_an_t an)
111025 +{
111026 + int err;
111027 + int _errno;
111028 +
111029 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
111030 + _errno = -GET_ERROR_TYPE(err);
111031 + if (unlikely(_errno < 0))
111032 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
111033 + err);
111034 +
111035 + return _errno;
111036 +}
111037 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
111038 +
111039 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111040 + macsec_an_t *p_an)
111041 +{
111042 + int err;
111043 + int _errno;
111044 +
111045 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
111046 + _errno = -GET_ERROR_TYPE(err);
111047 + if (unlikely(_errno < 0))
111048 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
111049 + err);
111050 +
111051 + return _errno;
111052 +}
111053 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
111054 +
111055 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111056 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
111057 +{
111058 + int err;
111059 + int _errno;
111060 +
111061 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
111062 + _errno = -GET_ERROR_TYPE(err);
111063 + if (unlikely(_errno < 0))
111064 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
111065 + err);
111066 +
111067 + return _errno;
111068 +}
111069 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
111070 +
111071 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111072 + uint32_t *sc_phys_id)
111073 +{
111074 + int err;
111075 + int _errno;
111076 +
111077 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
111078 + _errno = -GET_ERROR_TYPE(err);
111079 + if (unlikely(_errno < 0))
111080 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
111081 + err);
111082 +
111083 + return _errno;
111084 +}
111085 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
111086 +
111087 +static t_Handle h_FmLnxWrp;
111088 +
111089 +static int __init __cold fm_load (void)
111090 +{
111091 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
111092 + {
111093 + printk("Failed to init FM wrapper!\n");
111094 + return -ENODEV;
111095 + }
111096 +
111097 + printk(KERN_CRIT "Freescale FM module," \
111098 + " FMD API version %d.%d.%d\n",
111099 + FMD_API_VERSION_MAJOR,
111100 + FMD_API_VERSION_MINOR,
111101 + FMD_API_VERSION_RESPIN);
111102 + return 0;
111103 +}
111104 +
111105 +static void __exit __cold fm_unload (void)
111106 +{
111107 + if (h_FmLnxWrp)
111108 + LNXWRP_FM_Free(h_FmLnxWrp);
111109 +}
111110 +
111111 +module_init (fm_load);
111112 +module_exit (fm_unload);
111113 --- /dev/null
111114 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
111115 @@ -0,0 +1,294 @@
111116 +/*
111117 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111118 + *
111119 + * Redistribution and use in source and binary forms, with or without
111120 + * modification, are permitted provided that the following conditions are met:
111121 + * * Redistributions of source code must retain the above copyright
111122 + * notice, this list of conditions and the following disclaimer.
111123 + * * Redistributions in binary form must reproduce the above copyright
111124 + * notice, this list of conditions and the following disclaimer in the
111125 + * documentation and/or other materials provided with the distribution.
111126 + * * Neither the name of Freescale Semiconductor nor the
111127 + * names of its contributors may be used to endorse or promote products
111128 + * derived from this software without specific prior written permission.
111129 + *
111130 + *
111131 + * ALTERNATIVELY, this software may be distributed under the terms of the
111132 + * GNU General Public License ("GPL") as published by the Free Software
111133 + * Foundation, either version 2 of that License or (at your option) any
111134 + * later version.
111135 + *
111136 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111137 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111138 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111139 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111140 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111141 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111142 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111143 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111144 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111145 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111146 + */
111147 +
111148 +/*
111149 + @File lnxwrp_fm.h
111150 +
111151 + @Author Shlomi Gridish
111152 +
111153 + @Description FM Linux wrapper functions.
111154 +
111155 +*/
111156 +
111157 +#ifndef __LNXWRP_FM_H__
111158 +#define __LNXWRP_FM_H__
111159 +
111160 +#include <linux/fsl_qman.h> /* struct qman_fq */
111161 +
111162 +#include "std_ext.h"
111163 +#include "error_ext.h"
111164 +#include "list_ext.h"
111165 +
111166 +#include "lnxwrp_fm_ext.h"
111167 +
111168 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
111169 +
111170 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
111171 +
111172 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
111173 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
111174 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
111175 +#else
111176 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
111177 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
111178 +#endif
111179 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
111180 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
111181 +
111182 +#define FRAG_MANIP_SPACE 128
111183 +#define FRAG_DATA_ALIGN 64
111184 +
111185 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
111186 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
111187 +#endif
111188 +
111189 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
111190 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
111191 +#endif
111192 +
111193 +typedef enum {
111194 + e_NO_PCD = 0,
111195 + e_FM_PCD_3_TUPLE
111196 +} e_LnxWrpFmPortPcdDefUseCase;
111197 +
111198 +
111199 +typedef struct t_FmTestFq {
111200 + struct qman_fq fq_base;
111201 + t_Handle h_Arg;
111202 +} t_FmTestFq;
111203 +
111204 +typedef struct {
111205 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
111206 + int minor;
111207 + char name[20];
111208 + bool active;
111209 + uint64_t phys_baseAddr;
111210 + uint64_t baseAddr; /* Port's *virtual* address */
111211 + uint32_t memSize;
111212 + t_WrpFmPortDevSettings settings;
111213 + t_FmExtPools opExtPools;
111214 + uint8_t totalNumOfSchemes;
111215 + uint8_t schemesBase;
111216 + uint8_t numOfSchemesUsed;
111217 + uint32_t pcdBaseQ;
111218 + uint16_t pcdNumOfQs;
111219 + struct fm_port_pcd_param pcd_owner_params;
111220 + e_LnxWrpFmPortPcdDefUseCase defPcd;
111221 + t_Handle h_DefNetEnv;
111222 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
111223 + t_FmBufferPrefixContent buffPrefixContent;
111224 + t_Handle h_Dev;
111225 + t_Handle h_DfltVsp;
111226 + t_Handle h_LnxWrpFmDev;
111227 + uint16_t txCh;
111228 + struct device *dev;
111229 + struct device_attribute *dev_attr_stats;
111230 + struct device_attribute *dev_attr_regs;
111231 + struct device_attribute *dev_attr_bmi_regs;
111232 + struct device_attribute *dev_attr_qmi_regs;
111233 +#if (DPAA_VERSION >= 11)
111234 + struct device_attribute *dev_attr_ipv4_opt;
111235 +#endif
111236 + struct device_attribute *dev_attr_dsar_regs;
111237 + struct device_attribute *dev_attr_dsar_mem;
111238 + struct auto_res_tables_sizes dsar_table_sizes;
111239 +} t_LnxWrpFmPortDev;
111240 +
111241 +typedef struct {
111242 + uint8_t id;
111243 + bool active;
111244 + uint64_t baseAddr;
111245 + uint32_t memSize;
111246 + t_WrpFmMacDevSettings settings;
111247 + t_Handle h_Dev;
111248 + t_Handle h_LnxWrpFmDev;
111249 +} t_LnxWrpFmMacDev;
111250 +
111251 +/* information about all active ports for an FMan.
111252 + * !Some ports may be disabled by u-boot, thus will not be available */
111253 +struct fm_active_ports {
111254 + uint32_t num_oh_ports;
111255 + uint32_t num_tx_ports;
111256 + uint32_t num_rx_ports;
111257 + uint32_t num_tx25_ports;
111258 + uint32_t num_rx25_ports;
111259 + uint32_t num_tx10_ports;
111260 + uint32_t num_rx10_ports;
111261 +};
111262 +
111263 +/* FMan resources precalculated at fm probe based
111264 + * on available FMan port. */
111265 +struct fm_resource_settings {
111266 + /* buffers - fifo sizes */
111267 + uint32_t tx1g_num_buffers;
111268 + uint32_t rx1g_num_buffers;
111269 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
111270 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
111271 + uint32_t tx10g_num_buffers;
111272 + uint32_t rx10g_num_buffers;
111273 + uint32_t oh_num_buffers;
111274 + uint32_t shared_ext_buffers;
111275 +
111276 + /* open DMAs */
111277 + uint32_t tx_1g_dmas;
111278 + uint32_t rx_1g_dmas;
111279 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
111280 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
111281 + uint32_t tx_10g_dmas;
111282 + uint32_t rx_10g_dmas;
111283 + uint32_t oh_dmas;
111284 + uint32_t shared_ext_open_dma;
111285 +
111286 + /* Tnums */
111287 + uint32_t tx_1g_tnums;
111288 + uint32_t rx_1g_tnums;
111289 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
111290 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
111291 + uint32_t tx_10g_tnums;
111292 + uint32_t rx_10g_tnums;
111293 + uint32_t oh_tnums;
111294 + uint32_t shared_ext_tnums;
111295 +};
111296 +
111297 +typedef struct {
111298 + uint8_t id;
111299 + char name[10];
111300 + bool active;
111301 + bool pcdActive;
111302 + bool prsActive;
111303 + bool kgActive;
111304 + bool ccActive;
111305 + bool plcrActive;
111306 + e_LnxWrpFmPortPcdDefUseCase defPcd;
111307 + uint32_t usedSchemes;
111308 + uint8_t totalNumOfSharedSchemes;
111309 + uint8_t sharedSchemesBase;
111310 + uint8_t numOfSchemesUsed;
111311 + uint8_t defNetEnvId;
111312 + uint64_t fmPhysBaseAddr;
111313 + uint64_t fmBaseAddr;
111314 + uint32_t fmMemSize;
111315 + uint64_t fmMuramPhysBaseAddr;
111316 + uint64_t fmMuramBaseAddr;
111317 + uint32_t fmMuramMemSize;
111318 + uint64_t fmRtcPhysBaseAddr;
111319 + uint64_t fmRtcBaseAddr;
111320 + uint32_t fmRtcMemSize;
111321 + uint64_t fmVspPhysBaseAddr;
111322 + uint64_t fmVspBaseAddr;
111323 + uint32_t fmVspMemSize;
111324 + int irq;
111325 + int err_irq;
111326 + t_WrpFmDevSettings fmDevSettings;
111327 + t_WrpFmPcdDevSettings fmPcdDevSettings;
111328 + t_Handle h_Dev;
111329 + uint16_t hcCh;
111330 +
111331 + t_Handle h_MuramDev;
111332 + t_Handle h_PcdDev;
111333 + t_Handle h_RtcDev;
111334 +
111335 + t_Handle h_DsarRxPort;
111336 + t_Handle h_DsarTxPort;
111337 +
111338 + t_LnxWrpFmPortDev hcPort;
111339 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
111340 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
111341 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
111342 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
111343 + struct fm_active_ports fm_active_ports_info;
111344 + struct fm_resource_settings fm_resource_settings_info;
111345 +
111346 + struct device *dev;
111347 + struct resource *res;
111348 + int major;
111349 + struct class *fm_class;
111350 + struct device_attribute *dev_attr_stats;
111351 + struct device_attribute *dev_attr_regs;
111352 + struct device_attribute *dev_attr_risc_load;
111353 +
111354 + struct device_attribute *dev_pcd_attr_stats;
111355 + struct device_attribute *dev_plcr_attr_regs;
111356 + struct device_attribute *dev_prs_attr_regs;
111357 + struct device_attribute *dev_fm_fpm_attr_regs;
111358 + struct device_attribute *dev_fm_kg_attr_regs;
111359 + struct device_attribute *dev_fm_kg_pe_attr_regs;
111360 + struct device_attribute *dev_attr_muram_free_size;
111361 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
111362 +
111363 +
111364 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
111365 +} t_LnxWrpFmDev;
111366 +
111367 +typedef struct {
111368 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
111369 +} t_LnxWrpFm;
111370 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
111371 +
111372 +
111373 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
111374 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
111375 +
111376 +
111377 +#if 0
111378 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
111379 +{
111380 + uint32_t schemeMask;
111381 + uint8_t i;
111382 +
111383 + if (!numSchemes)
111384 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111385 +
111386 + schemeMask = 0x80000000;
111387 + *p_BaseSchemeNum = 0xff;
111388 +
111389 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
111390 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
111391 + {
111392 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
111393 + numSchemes--;
111394 + if (*p_BaseSchemeNum==0xff)
111395 + *p_BaseSchemeNum = i;
111396 + }
111397 + else if (*p_BaseSchemeNum!=0xff)
111398 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
111399 +
111400 + if (numSchemes)
111401 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
111402 + return E_OK;
111403 +}
111404 +#endif
111405 +
111406 +void LnxWrpPCDIOCTLTypeChecking(void);
111407 +void LnxWrpPCDIOCTLEnumChecking(void);
111408 +
111409 +#endif /* __LNXWRP_FM_H__ */
111410 --- /dev/null
111411 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
111412 @@ -0,0 +1,1512 @@
111413 +/*
111414 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111415 + *
111416 + * Redistribution and use in source and binary forms, with or without
111417 + * modification, are permitted provided that the following conditions are met:
111418 + * * Redistributions of source code must retain the above copyright
111419 + * notice, this list of conditions and the following disclaimer.
111420 + * * Redistributions in binary form must reproduce the above copyright
111421 + * notice, this list of conditions and the following disclaimer in the
111422 + * documentation and/or other materials provided with the distribution.
111423 + * * Neither the name of Freescale Semiconductor nor the
111424 + * names of its contributors may be used to endorse or promote products
111425 + * derived from this software without specific prior written permission.
111426 + *
111427 + *
111428 + * ALTERNATIVELY, this software may be distributed under the terms of the
111429 + * GNU General Public License ("GPL") as published by the Free Software
111430 + * Foundation, either version 2 of that License or (at your option) any
111431 + * later version.
111432 + *
111433 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111434 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111435 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111436 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111437 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111438 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111439 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111440 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111441 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111442 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111443 + */
111444 +
111445 +/*
111446 + @File lnxwrp_fm_port.c
111447 +
111448 + @Description FMD wrapper - FMan port functions.
111449 +
111450 +*/
111451 +
111452 +#include <linux/version.h>
111453 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111454 +#define MODVERSIONS
111455 +#endif
111456 +#ifdef MODVERSIONS
111457 +#include <config/modversions.h>
111458 +#endif /* MODVERSIONS */
111459 +#include <linux/kernel.h>
111460 +#include <linux/module.h>
111461 +#include <linux/of_platform.h>
111462 +#include <linux/of_address.h>
111463 +#include <linux/cdev.h>
111464 +#include <linux/slab.h>
111465 +#include <linux/spinlock.h>
111466 +#ifndef CONFIG_FMAN_ARM
111467 +#include <linux/fsl/svr.h>
111468 +#endif
111469 +#include <linux/io.h>
111470 +
111471 +#include "sprint_ext.h"
111472 +#include "fm_common.h"
111473 +#include "lnxwrp_fsl_fman.h"
111474 +#include "fm_port_ext.h"
111475 +#if (DPAA_VERSION >= 11)
111476 +#include "fm_vsp_ext.h"
111477 +#endif /* DPAA_VERSION >= 11 */
111478 +#include "fm_ioctls.h"
111479 +#include "lnxwrp_resources.h"
111480 +#include "lnxwrp_sysfs_fm_port.h"
111481 +
111482 +#define __ERR_MODULE__ MODULE_FM
111483 +
111484 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
111485 +
111486 +/* TODO: duplicated, see lnxwrp_fm.c */
111487 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
111488 +do {\
111489 + if (i < max) {\
111490 + p_Entry = &p_Entrys[i];\
111491 + p_Entry->p_Function = _func;\
111492 + _param\
111493 + i++;\
111494 + } else {\
111495 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
111496 + ("Number of advanced-configuration entries exceeded"));\
111497 + } \
111498 +} while (0)
111499 +
111500 +#ifndef CONFIG_FMAN_ARM
111501 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111502 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111503 +#endif
111504 +
111505 +static volatile int hcFrmRcv/* = 0 */;
111506 +static spinlock_t lock;
111507 +
111508 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
111509 + struct qman_fq *fq,
111510 + const struct qm_dqrr_entry
111511 + *dq)
111512 +{
111513 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
111514 + unsigned long flags;
111515 +
111516 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
111517 +{
111518 + /* extract the HC frame address */
111519 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
111520 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
111521 + int i;
111522 +
111523 + /* 32b byteswap of all data in the HC Frame */
111524 + for(i = 0; i < hcf_l / 4; ++i)
111525 + hcf_va[i] =
111526 + ___constant_swab32(hcf_va[i]);
111527 +}
111528 +#endif
111529 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
111530 + spin_lock_irqsave(&lock, flags);
111531 + hcFrmRcv--;
111532 + spin_unlock_irqrestore(&lock, flags);
111533 +
111534 + return qman_cb_dqrr_consume;
111535 +}
111536 +
111537 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
111538 + struct qman_fq *fq,
111539 + const struct qm_dqrr_entry *dq)
111540 +{
111541 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
111542 + __func__);
111543 + return qman_cb_dqrr_consume;
111544 +}
111545 +
111546 +static void qm_err_cb(struct qman_portal *portal,
111547 + struct qman_fq *fq, const struct qm_mr_entry *msg)
111548 +{
111549 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
111550 + __func__);
111551 +}
111552 +
111553 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
111554 + uint32_t fqid,
111555 + uint32_t flags, uint16_t channel, uint8_t wq)
111556 +{
111557 + int _errno;
111558 + struct qman_fq *fq = NULL;
111559 + t_FmTestFq *p_FmtFq;
111560 + struct qm_mcc_initfq initfq;
111561 +
111562 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
111563 + if (!p_FmtFq) {
111564 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
111565 + return NULL;
111566 + }
111567 +
111568 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
111569 + ? qm_tx_conf_dqrr_cb
111570 + : qm_tx_dqrr_cb);
111571 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
111572 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
111573 + /* qm_err_cb wrongly called when the FQ is parked */
111574 + p_FmtFq->fq_base.cb.fqs = NULL;
111575 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
111576 + if (fqid == 0) {
111577 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
111578 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
111579 + } else {
111580 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
111581 + }
111582 +
111583 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
111584 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
111585 + XX_Free(p_FmtFq);
111586 + return NULL;
111587 + }
111588 + fq = &p_FmtFq->fq_base;
111589 +
111590 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
111591 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
111592 + initfq.fqd.dest.channel = channel;
111593 + initfq.fqd.dest.wq = wq;
111594 +
111595 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
111596 + if (unlikely(_errno < 0)) {
111597 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
111598 + ("FQ obj - qman_init_fq!!!"));
111599 + qman_destroy_fq(fq, 0);
111600 + XX_Free(p_FmtFq);
111601 + return NULL;
111602 + }
111603 + }
111604 +
111605 + DBG(TRACE,
111606 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
111607 + flags, channel, wq));
111608 +
111609 + return fq;
111610 +}
111611 +
111612 +static void FqFree(struct qman_fq *fq)
111613 +{
111614 + int _errno;
111615 +
111616 + _errno = qman_retire_fq(fq, NULL);
111617 + if (unlikely(_errno < 0))
111618 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
111619 +
111620 + _errno = qman_oos_fq(fq);
111621 + if (unlikely(_errno < 0))
111622 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
111623 +
111624 + qman_destroy_fq(fq, 0);
111625 + XX_Free((t_FmTestFq *) fq);
111626 +}
111627 +
111628 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
111629 +{
111630 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
111631 + int _errno, timeout = 1000000;
111632 + unsigned long flags;
111633 +
111634 + ASSERT_COND(p_LnxWrpFmDev);
111635 +
111636 + spin_lock_irqsave(&lock, flags);
111637 + hcFrmRcv++;
111638 + spin_unlock_irqrestore(&lock, flags);
111639 +
111640 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
111641 +{
111642 + /* extract the HC frame address */
111643 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
111644 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
111645 + int i;
111646 +
111647 + /* 32b byteswap of all data in the HC Frame */
111648 + for(i = 0; i < hcf_l / 4; ++i)
111649 + hcf_va[i] =
111650 + ___constant_swab32(hcf_va[i]);
111651 +}
111652 +#endif
111653 +
111654 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
111655 + 0);
111656 + if (_errno)
111657 + RETURN_ERROR(MINOR, E_INVALID_STATE,
111658 + ("qman_enqueue() failed"));
111659 +
111660 + while (hcFrmRcv && --timeout) {
111661 + udelay(1);
111662 + cpu_relax();
111663 + }
111664 + if (timeout == 0) {
111665 + dump_stack();
111666 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
111667 + ("timeout waiting for Tx confirmation"));
111668 + return E_WRITE_FAILED;
111669 + }
111670 +
111671 + return E_OK;
111672 +}
111673 +
111674 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
111675 + *of_dev)
111676 +{
111677 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111678 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111679 + struct device_node *fm_node, *port_node;
111680 + struct resource res;
111681 + const uint32_t *uint32_prop;
111682 + int _errno = 0, lenp;
111683 + uint32_t tmp_prop;
111684 +
111685 +#ifdef CONFIG_FMAN_P1023
111686 + static unsigned char have_oh_port/* = 0 */;
111687 +#endif
111688 +
111689 + port_node = of_node_get(of_dev->dev.of_node);
111690 +
111691 + /* Get the FM node */
111692 + fm_node = of_get_parent(port_node);
111693 + if (unlikely(fm_node == NULL)) {
111694 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
111695 + ("of_get_parent() = %d", _errno));
111696 + return NULL;
111697 + }
111698 +
111699 + p_LnxWrpFmDev =
111700 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
111701 + of_node_put(fm_node);
111702 +
111703 + /* if fm_probe() failed, no point in going further with port probing */
111704 + if (p_LnxWrpFmDev == NULL)
111705 + return NULL;
111706 +
111707 + uint32_prop =
111708 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
111709 + if (unlikely(uint32_prop == NULL)) {
111710 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111711 + ("of_get_property(%s, cell-index) failed",
111712 + port_node->full_name));
111713 + return NULL;
111714 + }
111715 + tmp_prop = be32_to_cpu(*uint32_prop);
111716 + if (WARN_ON(lenp != sizeof(uint32_t)))
111717 + return NULL;
111718 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh") ||
111719 + of_device_is_compatible(port_node, "fsl,fman-v2-port-oh") ||
111720 + of_device_is_compatible(port_node, "fsl,fman-v3-port-oh")) {
111721 +#ifndef CONFIG_FMAN_ARM
111722 +#ifdef CONFIG_FMAN_P3040_P4080_P5020
111723 + /* On PPC FMan v2, OH ports start from cell-index 0x1 */
111724 + tmp_prop -= 0x1;
111725 +#else
111726 + /* On PPC FMan v3 (Low and High), OH ports start from
111727 + * cell-index 0x2
111728 + */
111729 + tmp_prop -= 0x2;
111730 +#endif // CONFIG_FMAN_P3040_P4080_P5020
111731 +#endif // CONFIG_FMAN_ARM
111732 +
111733 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
111734 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111735 + ("of_get_property(%s, cell-index) failed",
111736 + port_node->full_name));
111737 + return NULL;
111738 + }
111739 +
111740 +#ifdef CONFIG_FMAN_P1023
111741 + /* Beware, this can be done when there is only
111742 + one FMan to be initialized */
111743 + if (!have_oh_port) {
111744 + have_oh_port = 1; /* first OP/HC port
111745 + is used for host command */
111746 +#else
111747 + /* Here it is hardcoded the use of the OH port 1
111748 + (with cell-index 0) */
111749 + if (tmp_prop == 0) {
111750 +#endif
111751 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
111752 + p_LnxWrpFmPortDev->id = 0;
111753 + /*
111754 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
111755 + p_LnxWrpFmPortDev->id = *uint32_prop;
111756 + */
111757 + p_LnxWrpFmPortDev->settings.param.portType =
111758 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
111759 + } else {
111760 + p_LnxWrpFmPortDev =
111761 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
111762 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
111763 + p_LnxWrpFmPortDev->settings.param.portType =
111764 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
111765 + }
111766 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
111767 +
111768 + uint32_prop =
111769 + (uint32_t *) of_get_property(port_node,
111770 + "fsl,qman-channel-id",
111771 + &lenp);
111772 + if (uint32_prop == NULL) {
111773 + /*
111774 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
111775 + */
111776 + XX_Print("FM warning: missing fsl,qman-channel-id"
111777 + " for OH port.\n");
111778 + return NULL;
111779 + }
111780 + tmp_prop = be32_to_cpu(*uint32_prop);
111781 + if (WARN_ON(lenp != sizeof(uint32_t)))
111782 + return NULL;
111783 + p_LnxWrpFmPortDev->txCh = tmp_prop;
111784 +
111785 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
111786 + qmChannel = p_LnxWrpFmPortDev->txCh;
111787 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
111788 + tmp_prop -= 0x28;
111789 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
111790 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111791 + ("of_get_property(%s, cell-index) failed",
111792 + port_node->full_name));
111793 + return NULL;
111794 + }
111795 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
111796 +
111797 + p_LnxWrpFmPortDev->id = tmp_prop;
111798 + p_LnxWrpFmPortDev->settings.param.portId =
111799 + p_LnxWrpFmPortDev->id;
111800 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
111801 +
111802 + uint32_prop = (uint32_t *) of_get_property(port_node,
111803 + "fsl,qman-channel-id", &lenp);
111804 + if (uint32_prop == NULL) {
111805 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111806 + ("missing fsl,qman-channel-id"));
111807 + return NULL;
111808 + }
111809 + tmp_prop = be32_to_cpu(*uint32_prop);
111810 + if (WARN_ON(lenp != sizeof(uint32_t)))
111811 + return NULL;
111812 + p_LnxWrpFmPortDev->txCh = tmp_prop;
111813 + p_LnxWrpFmPortDev->
111814 + settings.param.specificParams.nonRxParams.qmChannel =
111815 + p_LnxWrpFmPortDev->txCh;
111816 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
111817 +#ifndef CONFIG_FMAN_ARM
111818 + /* On T102x, the 10G TX port IDs start from 0x28 */
111819 + if (IS_T1023_T1024)
111820 + tmp_prop -= 0x28;
111821 + else
111822 +#endif
111823 + tmp_prop -= 0x30;
111824 +
111825 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
111826 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111827 + ("of_get_property(%s, cell-index) failed",
111828 + port_node->full_name));
111829 + return NULL;
111830 + }
111831 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
111832 + FM_MAX_NUM_OF_1G_TX_PORTS];
111833 +#ifndef CONFIG_FMAN_ARM
111834 + if (IS_T1023_T1024)
111835 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
111836 +#endif
111837 +
111838 + p_LnxWrpFmPortDev->id = tmp_prop;
111839 + p_LnxWrpFmPortDev->settings.param.portId =
111840 + p_LnxWrpFmPortDev->id;
111841 + p_LnxWrpFmPortDev->settings.param.portType =
111842 + e_FM_PORT_TYPE_TX_10G;
111843 + uint32_prop = (uint32_t *) of_get_property(port_node,
111844 + "fsl,qman-channel-id", &lenp);
111845 + if (uint32_prop == NULL) {
111846 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111847 + ("missing fsl,qman-channel-id"));
111848 + return NULL;
111849 + }
111850 + tmp_prop = be32_to_cpu(*uint32_prop);
111851 + if (WARN_ON(lenp != sizeof(uint32_t)))
111852 + return NULL;
111853 + p_LnxWrpFmPortDev->txCh = tmp_prop;
111854 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
111855 + qmChannel = p_LnxWrpFmPortDev->txCh;
111856 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
111857 + tmp_prop -= 0x08;
111858 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
111859 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111860 + ("of_get_property(%s, cell-index) failed",
111861 + port_node->full_name));
111862 + return NULL;
111863 + }
111864 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
111865 +
111866 + p_LnxWrpFmPortDev->id = tmp_prop;
111867 + p_LnxWrpFmPortDev->settings.param.portId =
111868 + p_LnxWrpFmPortDev->id;
111869 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
111870 + if (p_LnxWrpFmDev->pcdActive)
111871 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
111872 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
111873 +#ifndef CONFIG_FMAN_ARM
111874 + /* On T102x, the 10G RX port IDs start from 0x08 */
111875 + if (IS_T1023_T1024)
111876 + tmp_prop -= 0x8;
111877 + else
111878 +#endif
111879 + tmp_prop -= 0x10;
111880 +
111881 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
111882 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111883 + ("of_get_property(%s, cell-index) failed",
111884 + port_node->full_name));
111885 + return NULL;
111886 + }
111887 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
111888 + FM_MAX_NUM_OF_1G_RX_PORTS];
111889 +
111890 +#ifndef CONFIG_FMAN_ARM
111891 + if (IS_T1023_T1024)
111892 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
111893 +#endif
111894 +
111895 + p_LnxWrpFmPortDev->id = tmp_prop;
111896 + p_LnxWrpFmPortDev->settings.param.portId =
111897 + p_LnxWrpFmPortDev->id;
111898 + p_LnxWrpFmPortDev->settings.param.portType =
111899 + e_FM_PORT_TYPE_RX_10G;
111900 + if (p_LnxWrpFmDev->pcdActive)
111901 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
111902 + } else {
111903 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
111904 + return NULL;
111905 + }
111906 +
111907 + _errno = of_address_to_resource(port_node, 0, &res);
111908 + if (unlikely(_errno < 0)) {
111909 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111910 + ("of_address_to_resource() = %d", _errno));
111911 + return NULL;
111912 + }
111913 +
111914 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
111915 + p_LnxWrpFmPortDev->baseAddr = 0;
111916 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
111917 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
111918 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
111919 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
111920 +
111921 + of_node_put(port_node);
111922 +
111923 + p_LnxWrpFmPortDev->active = TRUE;
111924 +
111925 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
111926 + /* for performance mode no OH port available. */
111927 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111928 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
111929 + p_LnxWrpFmPortDev->active = FALSE;
111930 +#endif
111931 +
111932 + return p_LnxWrpFmPortDev;
111933 +}
111934 +
111935 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
111936 + e_FmPortType portType,
111937 + uint8_t portId)
111938 +{
111939 + struct device_node *port_node;
111940 + const uint32_t *uint32_prop;
111941 + int lenp;
111942 + char *portTypeString;
111943 + uint32_t tmp_prop;
111944 +
111945 + switch(portType) {
111946 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
111947 + portTypeString = "fsl,fman-port-op-extended-args";
111948 + break;
111949 + case e_FM_PORT_TYPE_TX:
111950 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
111951 + break;
111952 + case e_FM_PORT_TYPE_TX_10G:
111953 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
111954 + break;
111955 + case e_FM_PORT_TYPE_RX:
111956 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
111957 + break;
111958 + case e_FM_PORT_TYPE_RX_10G:
111959 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
111960 + break;
111961 + default:
111962 + return NULL;
111963 + }
111964 +
111965 + for_each_child_of_node(fm_node, port_node) {
111966 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
111967 + if (unlikely(uint32_prop == NULL)) {
111968 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
111969 + ("of_get_property(%s, cell-index) failed",
111970 + port_node->full_name));
111971 + return NULL;
111972 + }
111973 + tmp_prop = be32_to_cpu(*uint32_prop);
111974 + if (WARN_ON(lenp != sizeof(uint32_t)))
111975 + return NULL;
111976 + if ((portId == tmp_prop) &&
111977 + (of_device_is_compatible(port_node, portTypeString))) {
111978 + return port_node;
111979 + }
111980 + }
111981 +
111982 + return NULL;
111983 +}
111984 +
111985 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111986 +{
111987 + struct device_node *fm_node, *port_node;
111988 + t_Error err;
111989 + t_FmPortRsrc portRsrc;
111990 + const uint32_t *uint32_prop;
111991 + /*const char *str_prop;*/
111992 + int lenp;
111993 +#ifdef CONFIG_FMAN_PFC
111994 + uint8_t i, id, num_pools;
111995 + t_FmBufPoolDepletion poolDepletion;
111996 +
111997 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
111998 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
111999 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
112000 + poolDepletion.singlePoolModeEnable = true;
112001 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112002 + extBufPools.numOfPoolsUsed;
112003 + for (i = 0; i < num_pools; i++) {
112004 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112005 + extBufPools.extBufPool[i].id;
112006 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
112007 + }
112008 +
112009 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
112010 + poolDepletion.pfcPrioritiesEn[i] = true;
112011 +
112012 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
112013 + &poolDepletion);
112014 + if (err != E_OK)
112015 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
112016 + }
112017 +#endif
112018 +
112019 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
112020 + if (!fm_node) /* no advance parameters for FMan */
112021 + return E_OK;
112022 +
112023 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
112024 + p_LnxWrpFmPortDev->settings.param.portType,
112025 + p_LnxWrpFmPortDev->settings.param.portId);
112026 + if (!port_node) /* no advance parameters for FMan-Port */
112027 + return E_OK;
112028 +
112029 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
112030 + if (uint32_prop) {
112031 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112032 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112033 +
112034 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
112035 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
112036 +
112037 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
112038 + &portRsrc)) != E_OK)
112039 + RETURN_ERROR(MINOR, err, NO_MSG);
112040 + }
112041 +
112042 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
112043 + if (uint32_prop) {
112044 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112045 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112046 +
112047 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
112048 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
112049 +
112050 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
112051 + &portRsrc)) != E_OK)
112052 + RETURN_ERROR(MINOR, err, NO_MSG);
112053 + }
112054 +
112055 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
112056 + if (uint32_prop) {
112057 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112058 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112059 +
112060 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
112061 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
112062 +
112063 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
112064 + &portRsrc)) != E_OK)
112065 + RETURN_ERROR(MINOR, err, NO_MSG);
112066 + }
112067 +
112068 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
112069 + if (uint32_prop) {
112070 + if (WARN_ON(lenp != sizeof(uint32_t)))
112071 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112072 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
112073 + be32_to_cpu(uint32_prop[0]))) != E_OK)
112074 + RETURN_ERROR(MINOR, err, NO_MSG);
112075 + }
112076 +
112077 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
112078 + &lenp);
112079 + if (uint32_prop) {
112080 +
112081 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
112082 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112083 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
112084 + e_FM_PORT_TYPE_RX) &&
112085 + (p_LnxWrpFmPortDev->settings.param.portType !=
112086 + e_FM_PORT_TYPE_RX_10G))
112087 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
112088 + ("Auto Response is an Rx port atribute."));
112089 +
112090 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
112091 +
112092 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
112093 + (uint16_t)be32_to_cpu(uint32_prop[0]);
112094 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
112095 + (uint16_t)be32_to_cpu(uint32_prop[1]);
112096 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
112097 + (uint16_t)be32_to_cpu(uint32_prop[2]);
112098 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
112099 + (uint16_t)be32_to_cpu(uint32_prop[3]);
112100 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
112101 + (uint16_t)be32_to_cpu(uint32_prop[4]);
112102 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
112103 + (uint16_t)be32_to_cpu(uint32_prop[5]);
112104 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
112105 + (uint16_t)be32_to_cpu(uint32_prop[6]);
112106 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
112107 + (uint16_t)be32_to_cpu(uint32_prop[7]);
112108 +
112109 + uint32_prop = (uint32_t *)of_get_property(port_node,
112110 + "ar-filters-sizes", &lenp);
112111 + if (uint32_prop) {
112112 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
112113 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112114 +
112115 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
112116 + (uint16_t)be32_to_cpu(uint32_prop[0]);
112117 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
112118 + (uint16_t)be32_to_cpu(uint32_prop[1]);
112119 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
112120 + (uint16_t)be32_to_cpu(uint32_prop[2]);
112121 + }
112122 +
112123 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
112124 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
112125 + RETURN_ERROR(MINOR, err, NO_MSG);
112126 + }
112127 +
112128 + of_node_put(port_node);
112129 + of_node_put(fm_node);
112130 +
112131 + return E_OK;
112132 +}
112133 +
112134 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112135 +{
112136 + struct device_node *fm_node, *port_node;
112137 + t_Error err;
112138 + const uint32_t *uint32_prop;
112139 + /*const char *str_prop;*/
112140 + int lenp;
112141 +
112142 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
112143 + if (!fm_node) /* no advance parameters for FMan */
112144 + return E_OK;
112145 +
112146 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
112147 + p_LnxWrpFmPortDev->settings.param.portType,
112148 + p_LnxWrpFmPortDev->settings.param.portId);
112149 + if (!port_node) /* no advance parameters for FMan-Port */
112150 + return E_OK;
112151 +
112152 +#if (DPAA_VERSION >= 11)
112153 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
112154 + if (uint32_prop) {
112155 + t_FmPortVSPAllocParams portVSPAllocParams;
112156 + t_FmVspParams fmVspParams;
112157 + t_LnxWrpFmDev *p_LnxWrpFmDev;
112158 + uint8_t portId;
112159 +
112160 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
112161 +
112162 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112163 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112164 +
112165 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
112166 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
112167 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112168 + p_LnxWrpFmPortDev->settings.frag_enabled))
112169 + return E_OK;
112170 +
112171 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
112172 + memset(&fmVspParams, 0, sizeof(fmVspParams));
112173 +
112174 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
112175 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
112176 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
112177 +
112178 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
112179 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
112180 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
112181 +
112182 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
112183 + {
112184 + portId = fmVspParams.portParams.portId;
112185 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
112186 +#ifndef CONFIG_FMAN_ARM
112187 + if (!(IS_T1023_T1024))
112188 +#endif
112189 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
112190 + }
112191 + portVSPAllocParams.h_FmTxPort =
112192 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
112193 + fmVspParams.liodnOffset =
112194 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
112195 + memcpy(&fmVspParams.extBufPools,
112196 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
112197 + sizeof(t_FmExtPools));
112198 + }
112199 + else
112200 + {
112201 + memcpy(&fmVspParams.extBufPools,
112202 + &p_LnxWrpFmPortDev->opExtPools,
112203 + sizeof(t_FmExtPools));
112204 + }
112205 +
112206 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
112207 + &portVSPAllocParams)) != E_OK)
112208 + RETURN_ERROR(MINOR, err, NO_MSG);
112209 +
112210 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
112211 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112212 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
112213 + return E_OK;
112214 +
112215 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
112216 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
112217 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
112218 +
112219 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
112220 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
112221 + RETURN_ERROR(MINOR, err, NO_MSG);
112222 +
112223 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
112224 + RETURN_ERROR(MINOR, err, NO_MSG);
112225 + }
112226 +#else
112227 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
112228 +#endif /* (DPAA_VERSION >= 11) */
112229 +
112230 + of_node_put(port_node);
112231 + of_node_put(fm_node);
112232 +
112233 + return E_OK;
112234 +}
112235 +
112236 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112237 +{
112238 + t_LnxWrpFmDev *p_LnxWrpFmDev =
112239 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
112240 + struct resource *dev_res;
112241 +
112242 + if (!p_LnxWrpFmPortDev->active)
112243 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
112244 + ("FM port not configured!!!"));
112245 +
112246 + dev_res =
112247 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
112248 + p_LnxWrpFmPortDev->phys_baseAddr,
112249 + p_LnxWrpFmPortDev->memSize,
112250 + "fman-port-hc");
112251 + if (unlikely(dev_res == NULL))
112252 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
112253 + ("__devm_request_region() failed"));
112254 + p_LnxWrpFmPortDev->baseAddr =
112255 + PTR_TO_UINT(devm_ioremap
112256 + (p_LnxWrpFmDev->dev,
112257 + p_LnxWrpFmPortDev->phys_baseAddr,
112258 + p_LnxWrpFmPortDev->memSize));
112259 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
112260 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
112261 + ("devm_ioremap() failed"));
112262 +
112263 + p_LnxWrpFmPortDev->settings.param.baseAddr =
112264 + p_LnxWrpFmPortDev->baseAddr;
112265 +
112266 + return E_OK;
112267 +}
112268 +
112269 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112270 +{
112271 +#define MY_ADV_CONFIG_CHECK_END \
112272 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
112273 + ("Advanced configuration routine"));\
112274 + if (errCode != E_OK)\
112275 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
112276 + }
112277 +
112278 + int i = 0;
112279 +
112280 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
112281 + return E_INVALID_STATE;
112282 +
112283 + p_LnxWrpFmPortDev->h_Dev =
112284 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
112285 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
112286 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
112287 +
112288 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
112289 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112290 + e_FM_PORT_TYPE_TX_10G)
112291 + || (p_LnxWrpFmPortDev->settings.param.portType ==
112292 + e_FM_PORT_TYPE_TX)) {
112293 + t_Error errCode = E_OK;
112294 + errCode =
112295 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
112296 + TRUE);
112297 + if (errCode != E_OK)
112298 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
112299 + errCode =
112300 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
112301 + e_FM_PORT_DEQ_FULL_PREFETCH);
112302 + if (errCode
112303 + != E_OK)
112304 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
112305 + }
112306 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
112307 +
112308 +#ifndef CONFIG_FMAN_ARM
112309 +#ifdef FM_BCB_ERRATA_BMI_SW001
112310 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
112311 +#define SVR_SECURITY_MASK 0x00080000
112312 +#define SVR_PERSONALITY_MASK 0x0000FF00
112313 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
112314 +#define SVR_B4860_REV1_VALUE 0x86800010
112315 +
112316 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112317 + e_FM_PORT_TYPE_RX_10G) ||
112318 + (p_LnxWrpFmPortDev->settings.param.portType ==
112319 + e_FM_PORT_TYPE_RX)) {
112320 + unsigned int svr;
112321 +
112322 + svr = mfspr(SPRN_SVR);
112323 +
112324 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
112325 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
112326 + }
112327 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
112328 +#endif /* CONFIG_FMAN_ARM */
112329 +/* Call the driver's advanced configuration routines, if requested:
112330 + Compare the function pointer of each entry to the available routines,
112331 + and invoke the matching routine with proper casting of arguments. */
112332 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
112333 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
112334 +
112335 +/* TODO: Change this MACRO */
112336 + ADV_CONFIG_CHECK_START(
112337 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
112338 +
112339 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
112340 + FM_PORT_ConfigBufferPrefixContent,
112341 + NCSW_PARAMS(1,
112342 + (t_FmBufferPrefixContent *)))
112343 +
112344 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112345 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112346 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
112347 +
112348 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
112349 + FM_PORT_ConfigExtBufPools,
112350 + NCSW_PARAMS(1, (t_FmExtPools *)))
112351 +
112352 + /* this define contains an else */
112353 + MY_ADV_CONFIG_CHECK_END
112354 + }
112355 +
112356 + /* Advance to next advanced configuration entry */
112357 + i++;
112358 + }
112359 +
112360 +
112361 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
112362 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
112363 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
112364 + FM_PORT_FRM_ERR_IPR_NCSP |
112365 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
112366 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112367 + }
112368 +
112369 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
112370 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112371 +
112372 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
112373 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112374 +
112375 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
112376 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112377 +
112378 +/* FMan Fifo sizes behind the scene":
112379 + * Using the following formulae (*), under a set of simplifying assumptions (.):
112380 + * . all ports are configured in Normal Mode (rather than Independent Mode)
112381 + * . the DPAA Eth driver allocates buffers of size:
112382 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
112383 + * + DPA_HASH_RESULTS_SIZE, i.e.:
112384 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
112385 + * MAXFRM + 66
112386 + * . excessive buffer pools not accounted for
112387 + *
112388 + * * for Rx ports on P4080:
112389 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
112390 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
112391 + * add up to 256 to the above
112392 + *
112393 + * * for Rx ports on P1023:
112394 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
112395 + * if at least 2 bpools are configured
112396 + * . IFSZ = 8 * 256, if only a single bpool is configured
112397 + *
112398 + * * for Tx ports:
112399 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
112400 + * + FMBM_TFP[DPDE] * 256, i.e.:
112401 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
112402 + *
112403 + * * for OH ports on P4080:
112404 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
112405 + * * for OH ports on P1023:
112406 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
112407 + * * for both P4080 and P1023:
112408 + * . (conservative decisions, assuming that BMI must bring the entire
112409 + * frame, not only the frame header)
112410 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
112411 + * add up to 256 to the above
112412 + *
112413 + * . for P4080/P5020/P3041/P2040, DPDE is:
112414 + * > 0 or 1, for 1Gb ports, HW default: 0
112415 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
112416 + * . for P1023, DPDE should be 1
112417 + *
112418 + * . for P1023, MXT is in range (0..31)
112419 + * . for P4080, MXT is in range (0..63)
112420 + *
112421 + */
112422 +#if 0
112423 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
112424 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
112425 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112426 +#endif
112427 + return E_OK;
112428 +}
112429 +
112430 +void fm_set_rx_port_params(struct fm_port *port,
112431 + struct fm_port_params *params)
112432 +{
112433 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
112434 + int i;
112435 +
112436 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
112437 + params->errq;
112438 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
112439 + params->defq;
112440 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
112441 + numOfPoolsUsed = params->num_pools;
112442 + for (i = 0; i < params->num_pools; i++) {
112443 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112444 + extBufPools.extBufPool[i].id =
112445 + params->pool_param[i].id;
112446 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112447 + extBufPools.extBufPool[i].size =
112448 + params->pool_param[i].size;
112449 + }
112450 +
112451 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
112452 + params->priv_data_size;
112453 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
112454 + params->parse_results;
112455 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
112456 + params->hash_results;
112457 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
112458 + params->time_stamp;
112459 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
112460 + params->data_align;
112461 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
112462 + params->manip_extra_space;
112463 +
112464 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
112465 + FM_MAX_NUM_OF_ADV_SETTINGS)
112466 +
112467 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
112468 + ARGS(1,
112469 + (&p_LnxWrpFmPortDev->
112470 + buffPrefixContent)));
112471 +
112472 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
112473 +}
112474 +EXPORT_SYMBOL(fm_set_rx_port_params);
112475 +
112476 +/* this function is called from oh_probe as well, thus it contains oh port
112477 + * specific parameters (make sure everything is checked) */
112478 +void fm_set_tx_port_params(struct fm_port *port,
112479 + struct fm_port_params *params)
112480 +{
112481 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
112482 +
112483 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
112484 + params->errq;
112485 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
112486 + dfltFqid = params->defq;
112487 +
112488 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
112489 + params->priv_data_size;
112490 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
112491 + params->parse_results;
112492 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
112493 + params->hash_results;
112494 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
112495 + params->time_stamp;
112496 + p_LnxWrpFmPortDev->settings.frag_enabled =
112497 + params->frag_enable;
112498 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
112499 + params->data_align;
112500 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
112501 + params->manip_extra_space;
112502 +
112503 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
112504 + FM_MAX_NUM_OF_ADV_SETTINGS)
112505 +
112506 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
112507 + ARGS(1,
112508 + (&p_LnxWrpFmPortDev->
112509 + buffPrefixContent)));
112510 +
112511 + /* oh port specific parameter (for fragmentation only) */
112512 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112513 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112514 + params->num_pools) {
112515 + int i;
112516 +
112517 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
112518 + for (i = 0; i < params->num_pools; i++) {
112519 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
112520 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
112521 + }
112522 +
112523 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
112524 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
112525 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
112526 + }
112527 +
112528 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
112529 +}
112530 +EXPORT_SYMBOL(fm_set_tx_port_params);
112531 +
112532 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
112533 + t_Handle h_fm_mac,
112534 + int mac_id)
112535 +{
112536 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
112537 +
112538 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
112539 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
112540 +}
112541 +EXPORT_SYMBOL(fm_mac_set_handle);
112542 +
112543 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
112544 + e_FmPcdExceptions exception)
112545 +{
112546 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
112547 +
112548 + ASSERT_COND(p_LnxWrpFmDev);
112549 +
112550 + DBG(INFO, ("got fm-pcd exception %d", exception));
112551 +
112552 + /* do nothing */
112553 + UNUSED(exception);
112554 +}
112555 +
112556 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
112557 + e_FmPcdExceptions exception,
112558 + uint16_t index)
112559 +{
112560 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
112561 +
112562 + ASSERT_COND(p_LnxWrpFmDev);
112563 +
112564 + DBG(INFO,
112565 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
112566 +
112567 + /* do nothing */
112568 + UNUSED(exception);
112569 + UNUSED(index);
112570 +}
112571 +
112572 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
112573 +{
112574 + spin_lock_init(&lock);
112575 +
112576 + if (p_LnxWrpFmDev->pcdActive) {
112577 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
112578 + t_FmPcdParams fmPcdParams;
112579 + t_Error err;
112580 +
112581 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
112582 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
112583 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
112584 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
112585 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
112586 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
112587 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
112588 +
112589 +#ifndef CONFIG_GUEST_PARTITION
112590 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
112591 + if (fmPcdParams.kgSupport)
112592 + fmPcdParams.f_ExceptionId =
112593 + LnxwrpFmPcdDevIndexedExceptionsCb;
112594 + fmPcdParams.h_App = p_LnxWrpFmDev;
112595 +#endif /* !CONFIG_GUEST_PARTITION */
112596 +
112597 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
112598 + fmPcdParams.numOfSchemes = 0;
112599 + fmPcdParams.numOfClsPlanEntries = 0;
112600 + fmPcdParams.partitionId = 0;
112601 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
112602 + fmPcdParams.useHostCommand = TRUE;
112603 +
112604 + p_LnxWrpFmDev->hc_tx_fq =
112605 + FqAlloc(p_LnxWrpFmDev,
112606 + 0,
112607 + QMAN_FQ_FLAG_TO_DCPORTAL,
112608 + p_LnxWrpFmPortDev->txCh, 0);
112609 + if (!p_LnxWrpFmDev->hc_tx_fq)
112610 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
112611 + ("Frame queue allocation failed..."));
112612 +
112613 + p_LnxWrpFmDev->hc_tx_conf_fq =
112614 + FqAlloc(p_LnxWrpFmDev,
112615 + 0,
112616 + QMAN_FQ_FLAG_NO_ENQUEUE,
112617 + p_LnxWrpFmDev->hcCh, 1);
112618 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
112619 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
112620 + ("Frame queue allocation failed..."));
112621 +
112622 + p_LnxWrpFmDev->hc_tx_err_fq =
112623 + FqAlloc(p_LnxWrpFmDev,
112624 + 0,
112625 + QMAN_FQ_FLAG_NO_ENQUEUE,
112626 + p_LnxWrpFmDev->hcCh, 2);
112627 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
112628 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
112629 + ("Frame queue allocation failed..."));
112630 +
112631 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
112632 + fmPcdParams.hc.portId =
112633 + p_LnxWrpFmPortDev->settings.param.portId;
112634 + fmPcdParams.hc.liodnBase =
112635 + p_LnxWrpFmPortDev->settings.param.liodnBase;
112636 + fmPcdParams.hc.errFqid =
112637 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
112638 + fmPcdParams.hc.confFqid =
112639 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
112640 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
112641 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
112642 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
112643 +
112644 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
112645 + if (!p_LnxWrpFmDev->h_PcdDev)
112646 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
112647 +
112648 + err =
112649 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
112650 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
112651 + if (err != E_OK)
112652 + RETURN_ERROR(MAJOR, err, NO_MSG);
112653 +
112654 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
112655 + if (err != E_OK)
112656 + RETURN_ERROR(MAJOR, err, NO_MSG);
112657 +
112658 + if (p_LnxWrpFmDev->err_irq == 0) {
112659 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112660 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
112661 + FALSE);
112662 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112663 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
112664 + FALSE);
112665 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112666 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
112667 + FALSE);
112668 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112669 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
112670 + FALSE);
112671 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112672 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
112673 + FALSE);
112674 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112675 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
112676 + FALSE);
112677 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112678 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
112679 + FALSE);
112680 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
112681 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
112682 + FALSE);
112683 + }
112684 + }
112685 +
112686 + return E_OK;
112687 +}
112688 +
112689 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
112690 +{
112691 +
112692 + if (p_LnxWrpFmDev->h_PcdDev)
112693 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
112694 +
112695 + if (p_LnxWrpFmDev->hc_tx_err_fq)
112696 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
112697 +
112698 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
112699 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
112700 +
112701 + if (p_LnxWrpFmDev->hc_tx_fq)
112702 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
112703 +}
112704 +
112705 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112706 +{
112707 + t_LnxWrpFmDev *p_LnxWrpFmDev =
112708 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
112709 +
112710 + if (!p_LnxWrpFmPortDev->active)
112711 + return;
112712 +
112713 + if (p_LnxWrpFmPortDev->h_Dev)
112714 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
112715 +
112716 + devm_iounmap(p_LnxWrpFmDev->dev,
112717 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
112718 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
112719 + p_LnxWrpFmPortDev->phys_baseAddr,
112720 + p_LnxWrpFmPortDev->memSize);
112721 +}
112722 +
112723 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
112724 +{
112725 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
112726 + t_LnxWrpFmDev *p_LnxWrpFmDev;
112727 + struct device *dev;
112728 +
112729 + dev = &of_dev->dev;
112730 +
112731 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
112732 + if (p_LnxWrpFmPortDev == NULL)
112733 + return -EIO;
112734 + /* Port can be inactive, thus will not be probed:
112735 + - in performance mode, OH ports are disabled
112736 + ...
112737 + */
112738 + if (!p_LnxWrpFmPortDev->active)
112739 + return 0;
112740 +
112741 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
112742 + return -EIO;
112743 +
112744 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
112745 +
112746 + if (p_LnxWrpFmPortDev->settings.param.portType ==
112747 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
112748 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
112749 +
112750 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
112751 +
112752 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
112753 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
112754 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
112755 + p_LnxWrpFmPortDev->minor =
112756 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
112757 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
112758 + e_FM_PORT_TYPE_RX_10G) {
112759 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
112760 + p_LnxWrpFmDev->name,
112761 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
112762 + p_LnxWrpFmPortDev->minor =
112763 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
112764 + DEV_FM_RX_PORTS_MINOR_BASE;
112765 +#ifndef CONFIG_FMAN_ARM
112766 + if (IS_T1023_T1024) {
112767 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
112768 + p_LnxWrpFmDev->name,
112769 + p_LnxWrpFmPortDev->id);
112770 + p_LnxWrpFmPortDev->minor =
112771 + p_LnxWrpFmPortDev->id +
112772 + DEV_FM_RX_PORTS_MINOR_BASE;
112773 + }
112774 +#endif
112775 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
112776 + e_FM_PORT_TYPE_TX) {
112777 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
112778 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
112779 + p_LnxWrpFmPortDev->minor =
112780 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
112781 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
112782 + e_FM_PORT_TYPE_TX_10G) {
112783 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
112784 + p_LnxWrpFmDev->name,
112785 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
112786 + p_LnxWrpFmPortDev->minor =
112787 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
112788 + DEV_FM_TX_PORTS_MINOR_BASE;
112789 +#ifndef CONFIG_FMAN_ARM
112790 + if (IS_T1023_T1024) {
112791 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
112792 + p_LnxWrpFmDev->name,
112793 + p_LnxWrpFmPortDev->id);
112794 + p_LnxWrpFmPortDev->minor =
112795 + p_LnxWrpFmPortDev->id +
112796 + DEV_FM_TX_PORTS_MINOR_BASE;
112797 + }
112798 +#endif
112799 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
112800 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
112801 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
112802 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
112803 + p_LnxWrpFmPortDev->minor =
112804 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
112805 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
112806 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
112807 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
112808 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
112809 + p_LnxWrpFmPortDev->minor =
112810 + p_LnxWrpFmPortDev->id + 1 +
112811 + DEV_FM_OH_PORTS_MINOR_BASE;
112812 + }
112813 +
112814 + device_create(p_LnxWrpFmDev->fm_class, NULL,
112815 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
112816 + NULL, p_LnxWrpFmPortDev->name);
112817 +
112818 + /* create sysfs entries for stats and regs */
112819 +
112820 + if (fm_port_sysfs_create(dev) != 0) {
112821 + FreeFmPortDev(p_LnxWrpFmPortDev);
112822 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
112823 + ("Unable to create sys entry - fm port!!!"));
112824 + return -EIO;
112825 + }
112826 +
112827 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
112828 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
112829 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
112830 +
112831 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
112832 +
112833 + return 0;
112834 +}
112835 +
112836 +static int fm_port_remove(struct platform_device *of_dev)
112837 +{
112838 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
112839 + t_LnxWrpFmDev *p_LnxWrpFmDev;
112840 + struct device *dev;
112841 +
112842 + dev = &of_dev->dev;
112843 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
112844 +
112845 + fm_port_sysfs_destroy(dev);
112846 +
112847 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
112848 + device_destroy(p_LnxWrpFmDev->fm_class,
112849 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
112850 +
112851 + FreeFmPortDev(p_LnxWrpFmPortDev);
112852 +
112853 + dev_set_drvdata(dev, NULL);
112854 +
112855 + return 0;
112856 +}
112857 +
112858 +static const struct of_device_id fm_port_match[] = {
112859 + {
112860 + .compatible = "fsl,fman-port-oh"},
112861 + {
112862 + .compatible = "fsl,fman-v2-port-oh"},
112863 + {
112864 + .compatible = "fsl,fman-v3-port-oh"},
112865 + {
112866 + .compatible = "fsl,fman-port-1g-rx"},
112867 + {
112868 + .compatible = "fsl,fman-port-10g-rx"},
112869 + {
112870 + .compatible = "fsl,fman-port-1g-tx"},
112871 + {
112872 + .compatible = "fsl,fman-port-10g-tx"},
112873 + {}
112874 +};
112875 +
112876 +#ifndef MODULE
112877 +MODULE_DEVICE_TABLE(of, fm_port_match);
112878 +#endif /* !MODULE */
112879 +
112880 +static struct platform_driver fm_port_driver = {
112881 +
112882 + .driver = {
112883 + .name = "fsl-fman-port",
112884 + .of_match_table = fm_port_match,
112885 + .owner = THIS_MODULE,
112886 + },
112887 + .probe = fm_port_probe,
112888 + .remove = fm_port_remove
112889 +};
112890 +
112891 +
112892 +t_Error LNXWRP_FM_Port_Init(void)
112893 +{
112894 + /* Register to the DTB for basic FM port API */
112895 + if (platform_driver_register(&fm_port_driver))
112896 + return E_NO_DEVICE;
112897 +
112898 + return E_OK;
112899 +}
112900 +
112901 +void LNXWRP_FM_Port_Free(void)
112902 +{
112903 + platform_driver_unregister(&fm_port_driver);
112904 +}
112905 +
112906 +static int __init __cold fm_port_load(void)
112907 +{
112908 + if (LNXWRP_FM_Port_Init() != E_OK) {
112909 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
112910 + return -ENODEV;
112911 + }
112912 +
112913 + printk(KERN_CRIT "Freescale FM Ports module\n");
112914 +
112915 + return 0;
112916 +}
112917 +
112918 +static void __exit __cold fm_port_unload(void)
112919 +{
112920 + LNXWRP_FM_Port_Free();
112921 +}
112922 +
112923 +module_init(fm_port_load);
112924 +module_exit(fm_port_unload);
112925 --- /dev/null
112926 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
112927 @@ -0,0 +1,4854 @@
112928 +/*
112929 + * Copyright 2008-2012 Freescale Semiconductor Inc.
112930 + *
112931 + * Redistribution and use in source and binary forms, with or without
112932 + * modification, are permitted provided that the following conditions are met:
112933 + * * Redistributions of source code must retain the above copyright
112934 + * notice, this list of conditions and the following disclaimer.
112935 + * * Redistributions in binary form must reproduce the above copyright
112936 + * notice, this list of conditions and the following disclaimer in the
112937 + * documentation and/or other materials provided with the distribution.
112938 + * * Neither the name of Freescale Semiconductor nor the
112939 + * names of its contributors may be used to endorse or promote products
112940 + * derived from this software without specific prior written permission.
112941 + *
112942 + *
112943 + * ALTERNATIVELY, this software may be distributed under the terms of the
112944 + * GNU General Public License ("GPL") as published by the Free Software
112945 + * Foundation, either version 2 of that License or (at your option) any
112946 + * later version.
112947 + *
112948 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
112949 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
112950 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
112951 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
112952 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
112953 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
112954 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
112955 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
112956 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
112957 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
112958 + */
112959 +
112960 +/*
112961 + @File lnxwrp_ioctls_fm.c
112962 + @Author Shlomi Gridish
112963 + @Description FM Linux wrapper functions.
112964 +*/
112965 +
112966 +/* Linux Headers ------------------- */
112967 +#include <linux/version.h>
112968 +
112969 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
112970 +#define MODVERSIONS
112971 +#endif
112972 +#ifdef MODVERSIONS
112973 +#include <config/modversions.h>
112974 +#endif /* MODVERSIONS */
112975 +
112976 +#include <linux/kernel.h>
112977 +#include <linux/module.h>
112978 +#include <linux/slab.h>
112979 +#include <linux/fs.h>
112980 +#include <linux/cdev.h>
112981 +#include <linux/device.h>
112982 +#include <linux/irq.h>
112983 +#include <linux/interrupt.h>
112984 +#include <linux/io.h>
112985 +#include <linux/ioport.h>
112986 +#include <linux/of_platform.h>
112987 +#include <linux/uaccess.h>
112988 +#include <asm/errno.h>
112989 +#ifndef CONFIG_FMAN_ARM
112990 +#include <sysdev/fsl_soc.h>
112991 +#include <linux/fsl/svr.h>
112992 +#endif
112993 +
112994 +#if defined(CONFIG_COMPAT)
112995 +#include <linux/compat.h>
112996 +#endif
112997 +
112998 +#include "part_ext.h"
112999 +#include "fm_ioctls.h"
113000 +#include "fm_pcd_ioctls.h"
113001 +#include "fm_port_ioctls.h"
113002 +#include "fm_vsp_ext.h"
113003 +
113004 +#ifndef CONFIG_FMAN_ARM
113005 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
113006 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
113007 +#endif
113008 +
113009 +#define __ERR_MODULE__ MODULE_FM
113010 +
113011 +#if defined(CONFIG_COMPAT)
113012 +#include "lnxwrp_ioctls_fm_compat.h"
113013 +#endif
113014 +
113015 +#include "lnxwrp_fm.h"
113016 +
113017 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
113018 +
113019 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
113020 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
113021 +#error Error: please synchronize IOC_ defines!
113022 +#endif
113023 +
113024 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
113025 +#error Error: please synchronize IOC_ defines!
113026 +#endif
113027 +
113028 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
113029 +#error Error: please synchronize IOC_ defines!
113030 +#endif
113031 +
113032 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
113033 +#error Error: please synchronize IOC_ defines!
113034 +#endif
113035 +
113036 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
113037 +#error Error: please synchronize IOC_ defines!
113038 +#endif
113039 +
113040 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
113041 +#error Error: please synchronize IOC_ defines!
113042 +#endif
113043 +
113044 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
113045 +#error Error: please synchronize IOC_ defines!
113046 +#endif
113047 +
113048 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
113049 +#error Error: please synchronize IOC_ defines!
113050 +#endif
113051 +
113052 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
113053 +#error Error: please synchronize IOC_ defines!
113054 +#endif
113055 +
113056 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
113057 +#error Error: please synchronize IOC_ defines!
113058 +#endif
113059 +
113060 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
113061 +#error Error: please synchronize IOC_ defines!
113062 +#endif
113063 +
113064 +#if DPAA_VERSION >= 11
113065 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
113066 +#error Error: please synchronize IOC_ defines!
113067 +#endif
113068 +#endif
113069 +
113070 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
113071 +#error Error: please synchronize IOC_ defines!
113072 +#endif
113073 +
113074 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
113075 +#error Error: please synchronize IOC_ defines!
113076 +#endif
113077 +
113078 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
113079 +#error Error: please synchronize IOC_ defines!
113080 +#endif
113081 +
113082 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
113083 +#error Error: please synchronize IOC_ defines!
113084 +#endif
113085 +
113086 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
113087 +#error Error: please synchronize IOC_ defines!
113088 +#endif
113089 +
113090 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
113091 +#error Error: please synchronize IOC_ defines!
113092 +#endif
113093 +
113094 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
113095 +#error Error: please synchronize IOC_ defines!
113096 +#endif
113097 +
113098 +/* net_ioctls.h === net_ext.h assertions */
113099 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
113100 +#error Error: please synchronize IOC_ defines!
113101 +#endif
113102 +
113103 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
113104 +#error Error: please synchronize IOC_ defines!
113105 +#endif
113106 +
113107 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
113108 +#error Error: please synchronize IOC_ defines!
113109 +#endif
113110 +
113111 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
113112 +#error Error: please synchronize IOC_ defines!
113113 +#endif
113114 +
113115 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
113116 +#error Error: please synchronize IOC_ defines!
113117 +#endif
113118 +
113119 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
113120 +#error Error: please synchronize IOC_ defines!
113121 +#endif
113122 +
113123 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
113124 +#error Error: please synchronize IOC_ defines!
113125 +#endif
113126 +
113127 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
113128 +#error Error: please synchronize IOC_ defines!
113129 +#endif
113130 +
113131 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
113132 +#error Error: please synchronize IOC_ defines!
113133 +#endif
113134 +
113135 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
113136 +#error Error: please synchronize IOC_ defines!
113137 +#endif
113138 +
113139 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
113140 +#error Error: please synchronize IOC_ defines!
113141 +#endif
113142 +
113143 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
113144 +#error Error: please synchronize IOC_ defines!
113145 +#endif
113146 +
113147 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
113148 +#error Error: please synchronize IOC_ defines!
113149 +#endif
113150 +
113151 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
113152 +#error Error: please synchronize IOC_ defines!
113153 +#endif
113154 +
113155 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
113156 +#error Error: please synchronize IOC_ defines!
113157 +#endif
113158 +
113159 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
113160 +#error Error: please synchronize IOC_ defines!
113161 +#endif
113162 +
113163 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
113164 +#error Error: please synchronize IOC_ defines!
113165 +#endif
113166 +
113167 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
113168 +#error Error: please synchronize IOC_ defines!
113169 +#endif
113170 +
113171 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
113172 +#error Error: please synchronize IOC_ defines!
113173 +#endif
113174 +
113175 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
113176 +#error Error: please synchronize IOC_ defines!
113177 +#endif
113178 +
113179 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
113180 +#error Error: please synchronize IOC_ defines!
113181 +#endif
113182 +
113183 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
113184 +#error Error: please synchronize IOC_ defines!
113185 +#endif
113186 +
113187 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
113188 +#error Error: please synchronize IOC_ defines!
113189 +#endif
113190 +
113191 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
113192 +#error Error: please synchronize IOC_ defines!
113193 +#endif
113194 +
113195 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
113196 +#error Error: please synchronize IOC_ defines!
113197 +#endif
113198 +
113199 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
113200 +#warning Error: please synchronize IOC_ defines!
113201 +#endif
113202 +
113203 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
113204 +#error Error: please synchronize IOC_ defines!
113205 +#endif
113206 +
113207 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
113208 +#error Error: please synchronize IOC_ defines!
113209 +#endif
113210 +
113211 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
113212 +#error Error: please synchronize IOC_ defines!
113213 +#endif
113214 +
113215 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
113216 +#error Error: please synchronize IOC_ defines!
113217 +#endif
113218 +
113219 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
113220 +#error Error: please synchronize IOC_ defines!
113221 +#endif
113222 +
113223 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
113224 +#error Error: please synchronize IOC_ defines!
113225 +#endif
113226 +
113227 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
113228 +#error Error: please synchronize IOC_ defines!
113229 +#endif
113230 +
113231 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
113232 +#error Error: please synchronize IOC_ defines!
113233 +#endif
113234 +
113235 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
113236 +#error Error: please synchronize IOC_ defines!
113237 +#endif
113238 +
113239 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
113240 +#error Error: please synchronize IOC_ defines!
113241 +#endif
113242 +
113243 +/* fm_ioctls.h === fm_ext.h assertions */
113244 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
113245 +#error Error: please synchronize IOC_ defines!
113246 +#endif
113247 +
113248 +void LnxWrpPCDIOCTLTypeChecking(void)
113249 +{
113250 + /* fm_ext.h == fm_ioctls.h */
113251 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
113252 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
113253 +
113254 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
113255 + /*ioc_fm_pcd_counters_params_t : NOT USED */
113256 + /*ioc_fm_pcd_exception_params_t : private */
113257 +#if (DPAA_VERSION >= 11)
113258 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
113259 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
113260 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
113261 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
113262 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
113263 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
113264 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
113265 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
113266 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
113267 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
113268 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
113269 +#endif /* (DPAA_VERSION >= 11) */
113270 +
113271 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
113272 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
113273 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
113274 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
113275 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
113276 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
113277 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
113278 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
113279 +
113280 +#if defined(CONFIG_ARM64)
113281 + /* different alignment */
113282 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
113283 +#else
113284 +#if !defined(CONFIG_COMPAT)
113285 + /* different alignment */
113286 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
113287 +#endif
113288 +#endif
113289 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
113290 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
113291 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
113292 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
113293 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
113294 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
113295 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
113296 +#if (DPAA_VERSION >= 11)
113297 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
113298 +#endif
113299 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
113300 +#if !defined(CONFIG_COMPAT)
113301 + /* different alignment */
113302 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
113303 +#endif
113304 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
113305 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
113306 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
113307 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
113308 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
113309 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
113310 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
113311 +#if !defined(CONFIG_COMPAT)
113312 + /* different alignment */
113313 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
113314 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
113315 +#endif
113316 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
113317 +#if !defined(CONFIG_COMPAT)
113318 + /* different alignment */
113319 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
113320 +#endif
113321 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
113322 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
113323 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
113324 + /*ioc_fm_pcd_port_params_t : private */
113325 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
113326 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
113327 +
113328 +#ifdef FM_CAPWAP_SUPPORT
113329 +#error TODO: unsupported feature
113330 +/*
113331 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
113332 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
113333 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
113334 +*/
113335 +#endif
113336 +
113337 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
113338 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
113339 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
113340 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
113341 + /*ioc_fm_manip_hdr_info_t : private */
113342 + /*ioc_fm_pcd_hash_table_set_t : private */
113343 +
113344 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
113345 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
113346 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
113347 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
113348 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
113349 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
113350 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
113351 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
113352 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
113353 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
113354 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
113355 +#if !defined(CONFIG_COMPAT)
113356 + /* different alignment */
113357 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
113358 +#endif
113359 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
113360 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
113361 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
113362 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
113363 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
113364 +#if DPAA_VERSION >= 11
113365 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
113366 +#endif
113367 +
113368 + /* fm_port_ext.h == fm_port_ioctls.h */
113369 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
113370 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
113371 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
113372 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
113373 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
113374 +
113375 + return;
113376 +}
113377 +
113378 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
113379 +
113380 +void LnxWrpPCDIOCTLEnumChecking(void)
113381 +{
113382 + /* net_ext.h == net_ioctls.h : sampling checks */
113383 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
113384 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
113385 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
113386 +
113387 + /* fm_ext.h == fm_ioctls.h */
113388 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
113389 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
113390 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
113391 +
113392 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
113393 + 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);
113394 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
113395 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
113396 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
113397 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
113398 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
113399 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
113400 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
113401 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
113402 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
113403 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
113404 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
113405 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
113406 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
113407 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
113408 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
113409 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
113410 + 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);
113411 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
113412 + 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);
113413 +#if !defined(FM_CAPWAP_SUPPORT)
113414 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
113415 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
113416 +#else
113417 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
113418 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
113419 + 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);
113420 +#endif
113421 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
113422 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
113423 +
113424 +#ifdef FM_CAPWAP_SUPPORT
113425 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
113426 +#endif
113427 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
113428 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
113429 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
113430 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
113431 +
113432 + /* fm_port_ext.h == fm_port_ioctls.h */
113433 +#if !defined(FM_CAPWAP_SUPPORT)
113434 + 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);
113435 +#else
113436 + 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);
113437 +#endif
113438 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
113439 + 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);
113440 +
113441 + return;
113442 +}
113443 +
113444 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
113445 +{
113446 + t_Error err = E_OK;
113447 +
113448 +/*
113449 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
113450 +
113451 + FM_PCD_PrsLoadSw
113452 + FM_PCD_SetAdvancedOffloadSupport
113453 + FM_PCD_Enable
113454 + FM_PCD_Disable
113455 + FM_PCD_ForceIntr
113456 + FM_PCD_SetException
113457 + FM_PCD_KgSetAdditionalDataAfterParsing
113458 + FM_PCD_KgSetDfltValue
113459 + FM_PCD_NetEnvCharacteristicsSet
113460 + FM_PCD_NetEnvCharacteristicsDelete
113461 + FM_PCD_KgSchemeSet
113462 + FM_PCD_KgSchemeDelete
113463 + FM_PCD_MatchTableSet
113464 + FM_PCD_MatchTableDelete
113465 + FM_PCD_CcRootBuild
113466 + FM_PCD_CcRootDelete
113467 + FM_PCD_PlcrProfileSet
113468 + FM_PCD_PlcrProfileDelete
113469 + FM_PCD_CcRootModifyNextEngine
113470 + FM_PCD_MatchTableModifyNextEngine
113471 + FM_PCD_MatchTableModifyMissNextEngine
113472 + FM_PCD_MatchTableRemoveKey
113473 + FM_PCD_MatchTableAddKey
113474 + FM_PCD_MatchTableModifyKeyAndNextEngine
113475 + FM_PCD_HashTableSet
113476 + FM_PCD_HashTableDelete
113477 + FM_PCD_HashTableAddKey
113478 + FM_PCD_HashTableRemoveKey
113479 + FM_PCD_MatchTableModifyKey
113480 + FM_PCD_ManipNodeReplace
113481 + FM_PCD_ManipNodeSet
113482 + FM_PCD_ManipNodeDelete
113483 +
113484 +Status: not exported, should be thru sysfs
113485 + FM_PCD_KgSchemeGetCounter
113486 + FM_PCD_KgSchemeSetCounter
113487 + FM_PCD_PlcrProfileGetCounter
113488 + FM_PCD_PlcrProfileSetCounter
113489 +
113490 +Status: not exported
113491 + FM_PCD_MatchTableFindNRemoveKey
113492 + FM_PCD_MatchTableFindNModifyNextEngine
113493 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
113494 + FM_PCD_MatchTableFindNModifyKey
113495 + FM_PCD_MatchTableGetIndexedHashBucket
113496 + FM_PCD_MatchTableGetNextEngine
113497 + FM_PCD_MatchTableGetKeyCounter
113498 +
113499 +Status: not exported, would be nice to have
113500 + FM_PCD_HashTableModifyNextEngine
113501 + FM_PCD_HashTableModifyMissNextEngine
113502 + FM_PCD_HashTableGetMissNextEngine
113503 + FM_PCD_ManipGetStatistics
113504 +
113505 +Status: not exported
113506 +#if DPAA_VERSION >= 11
113507 +
113508 + FM_VSP_GetStatistics -- it's not available yet
113509 +#endif
113510 +
113511 +Status: feature not supported
113512 +#ifdef FM_CAPWAP_SUPPORT
113513 +#error unsupported feature
113514 + FM_PCD_StatisticsSetNode
113515 +#endif
113516 +
113517 + */
113518 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
113519 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
113520 +
113521 + switch (cmd)
113522 + {
113523 +#if defined(CONFIG_COMPAT)
113524 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
113525 +#endif
113526 + case FM_PCD_IOC_PRS_LOAD_SW:
113527 + {
113528 + ioc_fm_pcd_prs_sw_params_t *param;
113529 + uint8_t *p_code;
113530 +
113531 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
113532 + if (!param)
113533 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113534 +
113535 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
113536 +
113537 +#if defined(CONFIG_COMPAT)
113538 + if (compat)
113539 + {
113540 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
113541 +
113542 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
113543 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
113544 + if (!compat_param)
113545 + {
113546 + XX_Free(param);
113547 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113548 + }
113549 +
113550 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
113551 + if (copy_from_user(compat_param,
113552 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
113553 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
113554 + {
113555 + XX_Free(compat_param);
113556 + XX_Free(param);
113557 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113558 + }
113559 +
113560 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
113561 +
113562 + XX_Free(compat_param);
113563 + }
113564 + else
113565 +#endif
113566 + {
113567 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
113568 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
113569 + {
113570 + XX_Free(param);
113571 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113572 + }
113573 + }
113574 +
113575 + if (!param->p_code || !param->size)
113576 + {
113577 + XX_Free(param);
113578 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113579 + }
113580 +
113581 + p_code = (uint8_t *) XX_Malloc(param->size);
113582 + if (!p_code)
113583 + {
113584 + XX_Free(param);
113585 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113586 + }
113587 +
113588 + memset(p_code, 0, param->size);
113589 + if (copy_from_user(p_code, param->p_code, param->size))
113590 + {
113591 + XX_Free(p_code);
113592 + XX_Free(param);
113593 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113594 + }
113595 +
113596 + param->p_code = p_code;
113597 +
113598 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
113599 +
113600 + XX_Free(p_code);
113601 + XX_Free(param);
113602 + break;
113603 + }
113604 +
113605 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
113606 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
113607 + break;
113608 +
113609 + case FM_PCD_IOC_ENABLE:
113610 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
113611 + break;
113612 +
113613 + case FM_PCD_IOC_DISABLE:
113614 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
113615 + break;
113616 +
113617 + case FM_PCD_IOC_FORCE_INTR:
113618 + {
113619 + int exception;
113620 +
113621 +#if defined(CONFIG_COMPAT)
113622 + if (compat)
113623 + {
113624 + if (get_user(exception, (int *) compat_ptr(arg)))
113625 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113626 + }
113627 + else
113628 +#endif
113629 + {
113630 + if (get_user(exception, (int *)arg))
113631 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113632 + }
113633 +
113634 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
113635 + break;
113636 + }
113637 +
113638 + case FM_PCD_IOC_SET_EXCEPTION:
113639 + {
113640 + ioc_fm_pcd_exception_params_t *param;
113641 +
113642 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
113643 + sizeof(ioc_fm_pcd_exception_params_t));
113644 + if (!param)
113645 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113646 +
113647 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
113648 +
113649 +#if defined(CONFIG_COMPAT)
113650 + if (compat)
113651 + {
113652 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
113653 + sizeof(ioc_fm_pcd_exception_params_t)))
113654 + {
113655 + XX_Free(param);
113656 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113657 + }
113658 + }
113659 + else
113660 +#endif
113661 + {
113662 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
113663 + sizeof(ioc_fm_pcd_exception_params_t)))
113664 + {
113665 + XX_Free(param);
113666 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113667 + }
113668 + }
113669 +
113670 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
113671 +
113672 + XX_Free(param);
113673 + break;
113674 + }
113675 +
113676 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
113677 + {
113678 + uint8_t payloadOffset;
113679 +
113680 +#if defined(CONFIG_COMPAT)
113681 + if (compat)
113682 + {
113683 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
113684 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113685 + }
113686 + else
113687 +#endif
113688 + {
113689 + if (get_user(payloadOffset, (uint8_t*) arg))
113690 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113691 + }
113692 +
113693 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
113694 + break;
113695 + }
113696 +
113697 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
113698 + {
113699 + ioc_fm_pcd_kg_dflt_value_params_t *param;
113700 +
113701 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
113702 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
113703 + if (!param)
113704 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113705 +
113706 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
113707 +
113708 +#if defined(CONFIG_COMPAT)
113709 + if (compat)
113710 + {
113711 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
113712 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
113713 + {
113714 + XX_Free(param);
113715 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113716 + }
113717 + }
113718 + else
113719 +#endif
113720 + {
113721 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
113722 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
113723 + {
113724 + XX_Free(param);
113725 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113726 + }
113727 + }
113728 +
113729 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
113730 +
113731 + XX_Free(param);
113732 + break;
113733 + }
113734 +
113735 +#if defined(CONFIG_COMPAT)
113736 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
113737 +#endif
113738 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
113739 + {
113740 + ioc_fm_pcd_net_env_params_t *param;
113741 +
113742 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
113743 + if (!param)
113744 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113745 +
113746 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
113747 +
113748 +#if defined(CONFIG_COMPAT)
113749 + if (compat)
113750 + {
113751 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
113752 +
113753 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
113754 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
113755 + if (!compat_param)
113756 + {
113757 + XX_Free(param);
113758 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113759 + }
113760 +
113761 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
113762 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
113763 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
113764 + {
113765 + XX_Free(compat_param);
113766 + XX_Free(param);
113767 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113768 + }
113769 +
113770 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
113771 + XX_Free(compat_param);
113772 + }
113773 + else
113774 +#endif
113775 + {
113776 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
113777 + sizeof(ioc_fm_pcd_net_env_params_t)))
113778 + {
113779 + XX_Free(param);
113780 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113781 + }
113782 + }
113783 +
113784 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
113785 +
113786 + if (!param->id)
113787 + {
113788 + XX_Free(param);
113789 + err = E_INVALID_VALUE;
113790 + /* Since the LLD has no errno-style error reporting,
113791 + we're left here with no other option than to report
113792 + a generic E_INVALID_VALUE */
113793 + break;
113794 + }
113795 +
113796 +#if defined(CONFIG_COMPAT)
113797 + if (compat)
113798 + {
113799 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
113800 +
113801 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
113802 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
113803 + if (!compat_param)
113804 + {
113805 + XX_Free(param);
113806 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113807 + }
113808 +
113809 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
113810 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
113811 +
113812 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
113813 + compat_param,
113814 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
113815 + err = E_READ_FAILED;
113816 +
113817 + XX_Free(compat_param);
113818 + }
113819 + else
113820 +#endif
113821 + {
113822 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
113823 + param,
113824 + sizeof(ioc_fm_pcd_net_env_params_t)))
113825 + err = E_READ_FAILED;
113826 + }
113827 +
113828 + XX_Free(param);
113829 + break;
113830 + }
113831 +
113832 +#if defined(CONFIG_COMPAT)
113833 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
113834 +#endif
113835 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
113836 + {
113837 + ioc_fm_obj_t id;
113838 +
113839 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113840 +
113841 +#if defined(CONFIG_COMPAT)
113842 + if (compat)
113843 + {
113844 + ioc_compat_fm_obj_t compat_id;
113845 +
113846 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113847 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113848 +
113849 + compat_obj_delete(&compat_id, &id);
113850 + }
113851 + else
113852 +#endif
113853 + {
113854 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113855 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113856 + }
113857 +
113858 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
113859 + break;
113860 + }
113861 +
113862 +#if defined(CONFIG_COMPAT)
113863 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
113864 +#endif
113865 + case FM_PCD_IOC_KG_SCHEME_SET:
113866 + {
113867 + ioc_fm_pcd_kg_scheme_params_t *param;
113868 +
113869 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
113870 + if (!param)
113871 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113872 +
113873 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
113874 +
113875 +#if defined(CONFIG_COMPAT)
113876 + if (compat)
113877 + {
113878 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
113879 +
113880 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
113881 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
113882 + if (!compat_param)
113883 + {
113884 + XX_Free(param);
113885 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113886 + }
113887 +
113888 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
113889 +
113890 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
113891 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
113892 + {
113893 + XX_Free(compat_param);
113894 + XX_Free(param);
113895 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113896 + }
113897 +
113898 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
113899 +
113900 + XX_Free(compat_param);
113901 + }
113902 + else
113903 +#endif
113904 + {
113905 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
113906 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
113907 + {
113908 + XX_Free(param);
113909 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113910 + }
113911 + }
113912 +
113913 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
113914 +
113915 + if (!param->id)
113916 + {
113917 + XX_Free(param);
113918 + err = E_INVALID_VALUE;
113919 + /* Since the LLD has no errno-style error reporting,
113920 + we're left here with no other option than to report
113921 + a generic E_INVALID_VALUE */
113922 + break;
113923 + }
113924 +
113925 +#if defined(CONFIG_COMPAT)
113926 + if (compat)
113927 + {
113928 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
113929 +
113930 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
113931 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
113932 + if (!compat_param)
113933 + {
113934 + XX_Free(param);
113935 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113936 + }
113937 +
113938 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
113939 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
113940 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
113941 + compat_param,
113942 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
113943 + err = E_READ_FAILED;
113944 +
113945 + XX_Free(compat_param);
113946 + }
113947 + else
113948 +#endif
113949 + {
113950 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
113951 + param,
113952 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
113953 + err = E_READ_FAILED;
113954 + }
113955 +
113956 + XX_Free(param);
113957 + break;
113958 + }
113959 +
113960 +#if defined(CONFIG_COMPAT)
113961 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
113962 +#endif
113963 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
113964 + {
113965 + ioc_fm_pcd_kg_scheme_spc_t *param;
113966 +
113967 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
113968 + if (!param)
113969 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113970 +
113971 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
113972 +
113973 +#if defined(CONFIG_COMPAT)
113974 + if (compat)
113975 + {
113976 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
113977 +
113978 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
113979 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
113980 + if (!compat_param)
113981 + {
113982 + XX_Free(param);
113983 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113984 + }
113985 +
113986 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
113987 +
113988 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
113989 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
113990 + {
113991 + XX_Free(compat_param);
113992 + XX_Free(param);
113993 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113994 + }
113995 +
113996 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
113997 +
113998 + XX_Free(compat_param);
113999 + }
114000 + else
114001 +#endif
114002 + {
114003 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
114004 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
114005 + {
114006 + XX_Free(param);
114007 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114008 + }
114009 + }
114010 +
114011 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
114012 +
114013 +#if defined(CONFIG_COMPAT)
114014 + if (compat)
114015 + {
114016 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
114017 +
114018 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
114019 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
114020 + if (!compat_param)
114021 + {
114022 + XX_Free(param);
114023 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114024 + }
114025 +
114026 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
114027 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
114028 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
114029 + compat_param,
114030 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
114031 + err = E_READ_FAILED;
114032 +
114033 + XX_Free(compat_param);
114034 + }
114035 + else
114036 +#endif
114037 + {
114038 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
114039 + param,
114040 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
114041 + err = E_READ_FAILED;
114042 + }
114043 +
114044 + XX_Free(param);
114045 + break;
114046 + }
114047 +
114048 +#if defined(CONFIG_COMPAT)
114049 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
114050 +#endif
114051 + case FM_PCD_IOC_KG_SCHEME_DELETE:
114052 + {
114053 + ioc_fm_obj_t id;
114054 +
114055 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114056 +
114057 +#if defined(CONFIG_COMPAT)
114058 + if (compat)
114059 + {
114060 + ioc_compat_fm_obj_t compat_id;
114061 +
114062 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114063 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114064 +
114065 + compat_obj_delete(&compat_id, &id);
114066 + }
114067 + else
114068 +#endif
114069 + {
114070 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114071 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114072 + }
114073 +
114074 + err = FM_PCD_KgSchemeDelete(id.obj);
114075 + break;
114076 + }
114077 +
114078 +#if defined(CONFIG_COMPAT)
114079 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
114080 +#endif
114081 + case FM_PCD_IOC_MATCH_TABLE_SET:
114082 + {
114083 + ioc_fm_pcd_cc_node_params_t *param;
114084 + uint8_t *keys;
114085 + uint8_t *masks;
114086 + int i,k;
114087 +
114088 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
114089 + sizeof(ioc_fm_pcd_cc_node_params_t) +
114090 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114091 + if (!param)
114092 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114093 +
114094 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
114095 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114096 +
114097 + keys = (uint8_t *) (param + 1);
114098 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
114099 +
114100 +#if defined(CONFIG_COMPAT)
114101 + if (compat)
114102 + {
114103 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
114104 +
114105 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
114106 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114107 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114108 + if (!compat_param)
114109 + {
114110 + XX_Free(param);
114111 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114112 + }
114113 +
114114 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114115 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114116 +
114117 + if (copy_from_user(compat_param,
114118 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
114119 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
114120 + {
114121 + XX_Free(compat_param);
114122 + XX_Free(param);
114123 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114124 + }
114125 +
114126 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
114127 +
114128 + XX_Free(compat_param);
114129 + }
114130 + else
114131 +#endif
114132 + {
114133 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
114134 + {
114135 + XX_Free(param);
114136 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114137 + }
114138 + }
114139 +
114140 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
114141 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
114142 +
114143 + /* support for indexed lookup */
114144 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
114145 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
114146 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
114147 + {
114148 + for (i=0, k=0;
114149 + i < param->keys_params.num_of_keys;
114150 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
114151 + {
114152 + if (param->keys_params.key_params[i].p_key &&
114153 + param->keys_params.key_size)
114154 + {
114155 + if (copy_from_user(&keys[k],
114156 + param->keys_params.key_params[i].p_key,
114157 + param->keys_params.key_size))
114158 + {
114159 + XX_Free(param);
114160 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114161 + }
114162 +
114163 + param->keys_params.key_params[i].p_key = &keys[k];
114164 + }
114165 +
114166 + if (param->keys_params.key_params[i].p_mask)
114167 + {
114168 + if (copy_from_user(&masks[k],
114169 + param->keys_params.key_params[i].p_mask,
114170 + param->keys_params.key_size))
114171 + {
114172 + XX_Free(param);
114173 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114174 + }
114175 +
114176 + param->keys_params.key_params[i].p_mask = &masks[k];
114177 + }
114178 + }
114179 + }
114180 +
114181 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
114182 +
114183 + if (!param->id) {
114184 + XX_Free(param);
114185 + err = E_INVALID_VALUE;
114186 + /* Since the LLD has no errno-style error reporting,
114187 + we're left here with no other option than to report
114188 + a generic E_INVALID_VALUE */
114189 + break;
114190 + }
114191 +
114192 +#if defined(CONFIG_COMPAT)
114193 + if (compat)
114194 + {
114195 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
114196 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
114197 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114198 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114199 + if (!compat_param)
114200 + {
114201 + XX_Free(param);
114202 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114203 + }
114204 +
114205 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114206 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114207 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
114208 +
114209 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
114210 + compat_param,
114211 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
114212 + err = E_READ_FAILED;
114213 +
114214 + XX_Free(compat_param);
114215 + }
114216 + else
114217 +#endif
114218 + {
114219 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
114220 + param,
114221 + sizeof(ioc_fm_pcd_cc_node_params_t)))
114222 + err = E_READ_FAILED;
114223 + }
114224 +
114225 + XX_Free(param);
114226 + break;
114227 + }
114228 +
114229 +#if defined(CONFIG_COMPAT)
114230 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
114231 +#endif
114232 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
114233 + {
114234 + ioc_fm_obj_t id;
114235 +
114236 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114237 +
114238 +#if defined(CONFIG_COMPAT)
114239 + if (compat)
114240 + {
114241 + ioc_compat_fm_obj_t compat_id;
114242 +
114243 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114244 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114245 +
114246 + compat_obj_delete(&compat_id, &id);
114247 + }
114248 + else
114249 +#endif
114250 + {
114251 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114252 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114253 + }
114254 +
114255 + err = FM_PCD_MatchTableDelete(id.obj);
114256 + break;
114257 + }
114258 +
114259 +#if defined(CONFIG_COMPAT)
114260 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
114261 +#endif
114262 + case FM_PCD_IOC_CC_ROOT_BUILD:
114263 + {
114264 + ioc_fm_pcd_cc_tree_params_t *param;
114265 +
114266 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
114267 + if (!param)
114268 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114269 +
114270 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
114271 +
114272 +#if defined(CONFIG_COMPAT)
114273 + if (compat)
114274 + {
114275 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
114276 +
114277 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
114278 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114279 + if (!compat_param)
114280 + {
114281 + XX_Free(param);
114282 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114283 + }
114284 +
114285 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114286 + if (copy_from_user(compat_param,
114287 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
114288 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
114289 + {
114290 + XX_Free(compat_param);
114291 + XX_Free(param);
114292 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114293 + }
114294 +
114295 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
114296 +
114297 + XX_Free(compat_param);
114298 + }
114299 + else
114300 +#endif
114301 + {
114302 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
114303 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
114304 + {
114305 + XX_Free(param);
114306 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114307 + }
114308 + }
114309 +
114310 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
114311 +
114312 + if (!param->id) {
114313 + XX_Free(param);
114314 + err = E_INVALID_VALUE;
114315 + /* Since the LLD has no errno-style error reporting,
114316 + we're left here with no other option than to report
114317 + a generic E_INVALID_VALUE */
114318 + break;
114319 + }
114320 +
114321 +#if defined(CONFIG_COMPAT)
114322 + if (compat)
114323 + {
114324 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
114325 +
114326 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114327 + if (!compat_param)
114328 + {
114329 + XX_Free(param);
114330 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114331 + }
114332 +
114333 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114334 +
114335 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
114336 +
114337 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
114338 + compat_param,
114339 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
114340 + err = E_READ_FAILED;
114341 +
114342 + XX_Free(compat_param);
114343 + }
114344 + else
114345 +#endif
114346 + {
114347 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
114348 + param,
114349 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
114350 + err = E_READ_FAILED;
114351 + }
114352 +
114353 + XX_Free(param);
114354 + break;
114355 + }
114356 +
114357 +#if defined(CONFIG_COMPAT)
114358 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
114359 +#endif
114360 + case FM_PCD_IOC_CC_ROOT_DELETE:
114361 + {
114362 + ioc_fm_obj_t id;
114363 +
114364 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114365 +
114366 +#if defined(CONFIG_COMPAT)
114367 + if (compat)
114368 + {
114369 + ioc_compat_fm_obj_t compat_id;
114370 +
114371 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114372 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114373 +
114374 + compat_obj_delete(&compat_id, &id);
114375 + }
114376 + else
114377 +#endif
114378 + {
114379 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114380 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114381 + }
114382 +
114383 + err = FM_PCD_CcRootDelete(id.obj);
114384 + break;
114385 + }
114386 +
114387 +#if defined(CONFIG_COMPAT)
114388 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
114389 +#endif
114390 + case FM_PCD_IOC_PLCR_PROFILE_SET:
114391 + {
114392 + ioc_fm_pcd_plcr_profile_params_t *param;
114393 +
114394 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
114395 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
114396 + if (!param)
114397 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114398 +
114399 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
114400 +
114401 +#if defined(CONFIG_COMPAT)
114402 + if (compat)
114403 + {
114404 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
114405 +
114406 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
114407 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114408 + if (!compat_param)
114409 + {
114410 + XX_Free(param);
114411 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114412 + }
114413 +
114414 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114415 + if (copy_from_user(compat_param, (
114416 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
114417 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
114418 + {
114419 + XX_Free(compat_param);
114420 + XX_Free(param);
114421 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114422 + }
114423 +
114424 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
114425 +
114426 + XX_Free(compat_param);
114427 + }
114428 + else
114429 +#endif
114430 + {
114431 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
114432 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
114433 + {
114434 + XX_Free(param);
114435 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114436 + }
114437 + }
114438 +
114439 + if (!param->modify &&
114440 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
114441 + {
114442 + t_Handle h_Port;
114443 + ioc_fm_pcd_port_params_t *port_params;
114444 +
114445 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
114446 + if (!port_params)
114447 + {
114448 + XX_Free(param);
114449 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114450 + }
114451 +
114452 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
114453 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
114454 + sizeof(ioc_fm_pcd_port_params_t)))
114455 + {
114456 + XX_Free(port_params);
114457 + XX_Free(param);
114458 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114459 + }
114460 +
114461 + switch(port_params->port_type)
114462 + {
114463 + case (e_IOC_FM_PORT_TYPE_RX):
114464 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
114465 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
114466 + break;
114467 + }
114468 + goto invalid_port_id;
114469 +
114470 + case (e_IOC_FM_PORT_TYPE_RX_10G):
114471 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
114472 +#ifndef CONFIG_FMAN_ARM
114473 + if (IS_T1023_T1024) {
114474 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
114475 + } else {
114476 +#else
114477 + {
114478 +#endif
114479 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
114480 + }
114481 + break;
114482 + }
114483 + goto invalid_port_id;
114484 +
114485 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
114486 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
114487 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
114488 + break;
114489 + }
114490 + goto invalid_port_id;
114491 +
114492 + default:
114493 +invalid_port_id:
114494 + XX_Free(port_params);
114495 + XX_Free(param);
114496 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
114497 + }
114498 +
114499 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
114500 + XX_Free(port_params);
114501 + }
114502 +
114503 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
114504 +
114505 + if (!param->id) {
114506 + XX_Free(param);
114507 + err = E_INVALID_VALUE;
114508 + /* Since the LLD has no errno-style error reporting,
114509 + we're left here with no other option than to report
114510 + a generic E_INVALID_VALUE */
114511 + break;
114512 + }
114513 +
114514 +#if defined(CONFIG_COMPAT)
114515 + if (compat)
114516 + {
114517 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
114518 +
114519 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
114520 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114521 + if (!compat_param)
114522 + {
114523 + XX_Free(param);
114524 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114525 + }
114526 +
114527 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114528 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
114529 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
114530 + compat_param,
114531 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
114532 + err = E_READ_FAILED;
114533 +
114534 + XX_Free(compat_param);
114535 + }
114536 + else
114537 +#endif
114538 + {
114539 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
114540 + param,
114541 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
114542 + err = E_READ_FAILED;
114543 + }
114544 +
114545 + XX_Free(param);
114546 + break;
114547 + }
114548 +
114549 +#if defined(CONFIG_COMPAT)
114550 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
114551 +#endif
114552 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
114553 + {
114554 + ioc_fm_obj_t id;
114555 +
114556 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114557 +
114558 +#if defined(CONFIG_COMPAT)
114559 + if (compat)
114560 + {
114561 + ioc_compat_fm_obj_t compat_id;
114562 +
114563 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114564 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114565 +
114566 + compat_obj_delete(&compat_id, &id);
114567 + }
114568 + else
114569 +#endif
114570 + {
114571 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114572 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114573 + }
114574 +
114575 + err = FM_PCD_PlcrProfileDelete(id.obj);
114576 + break;
114577 + }
114578 +
114579 +#if defined(CONFIG_COMPAT)
114580 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
114581 +#endif
114582 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
114583 + {
114584 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
114585 +
114586 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
114587 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
114588 + if (!param)
114589 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114590 +
114591 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
114592 +
114593 +#if defined(CONFIG_COMPAT)
114594 + if (compat)
114595 + {
114596 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
114597 +
114598 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
114599 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
114600 + if (!compat_param)
114601 + {
114602 + XX_Free(param);
114603 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114604 + }
114605 +
114606 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
114607 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
114608 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
114609 + {
114610 + XX_Free(compat_param);
114611 + XX_Free(param);
114612 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114613 + }
114614 +
114615 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
114616 +
114617 + XX_Free(compat_param);
114618 + }
114619 + else
114620 +#endif
114621 + {
114622 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
114623 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
114624 + {
114625 + XX_Free(param);
114626 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114627 + }
114628 + }
114629 +
114630 + err = FM_PCD_CcRootModifyNextEngine(param->id,
114631 + param->grp_indx,
114632 + param->indx,
114633 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
114634 +
114635 + XX_Free(param);
114636 + break;
114637 + }
114638 +
114639 +#if defined(CONFIG_COMPAT)
114640 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
114641 +#endif
114642 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
114643 + {
114644 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
114645 +
114646 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
114647 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
114648 + if (!param)
114649 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114650 +
114651 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
114652 +
114653 +#if defined(CONFIG_COMPAT)
114654 + if (compat)
114655 + {
114656 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
114657 +
114658 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
114659 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
114660 + if (!compat_param)
114661 + {
114662 + XX_Free(param);
114663 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114664 + }
114665 +
114666 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
114667 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
114668 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
114669 + {
114670 + XX_Free(compat_param);
114671 + XX_Free(param);
114672 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114673 + }
114674 +
114675 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
114676 +
114677 + XX_Free(compat_param);
114678 + }
114679 + else
114680 +#endif
114681 + {
114682 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
114683 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
114684 + {
114685 + XX_Free(param);
114686 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114687 + }
114688 + }
114689 +
114690 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
114691 + param->key_indx,
114692 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
114693 +
114694 + XX_Free(param);
114695 + break;
114696 + }
114697 +
114698 +#if defined(CONFIG_COMPAT)
114699 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
114700 +#endif
114701 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
114702 + {
114703 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
114704 +
114705 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
114706 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
114707 + if (!param)
114708 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114709 +
114710 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
114711 +
114712 +#if defined(CONFIG_COMPAT)
114713 + if (compat)
114714 + {
114715 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
114716 +
114717 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
114718 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
114719 + if (!compat_param)
114720 + {
114721 + XX_Free(param);
114722 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114723 + }
114724 +
114725 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
114726 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
114727 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
114728 + {
114729 + XX_Free(compat_param);
114730 + XX_Free(param);
114731 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114732 + }
114733 +
114734 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
114735 +
114736 + XX_Free(compat_param);
114737 + }
114738 + else
114739 +#endif
114740 + {
114741 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
114742 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
114743 + {
114744 + XX_Free(param);
114745 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114746 + }
114747 + }
114748 +
114749 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
114750 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
114751 +
114752 + XX_Free(param);
114753 + break;
114754 + }
114755 +
114756 +#if defined(CONFIG_COMPAT)
114757 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
114758 +#endif
114759 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
114760 + {
114761 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
114762 +
114763 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
114764 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
114765 + if (!param)
114766 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114767 +
114768 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
114769 +
114770 +#if defined(CONFIG_COMPAT)
114771 + if (compat)
114772 + {
114773 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
114774 +
114775 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
114776 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
114777 + if (!compat_param)
114778 + {
114779 + XX_Free(param);
114780 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114781 + }
114782 +
114783 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
114784 + if (copy_from_user(compat_param,
114785 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
114786 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
114787 + {
114788 + XX_Free(compat_param);
114789 + XX_Free(param);
114790 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114791 + }
114792 +
114793 + param->id = compat_ptr(compat_param->id);
114794 + param->key_indx = compat_param->key_indx;
114795 +
114796 + XX_Free(compat_param);
114797 + }
114798 + else
114799 +#endif
114800 + {
114801 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
114802 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
114803 + {
114804 + XX_Free(param);
114805 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114806 + }
114807 + }
114808 +
114809 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
114810 +
114811 + XX_Free(param);
114812 + break;
114813 + }
114814 +#if defined(CONFIG_COMPAT)
114815 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
114816 +#endif
114817 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
114818 + {
114819 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
114820 +
114821 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
114822 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114823 + if (!param)
114824 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114825 +
114826 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114827 +
114828 +#if defined(CONFIG_COMPAT)
114829 + if (compat)
114830 + {
114831 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
114832 +
114833 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
114834 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114835 + if (!compat_param)
114836 + {
114837 + XX_Free(param);
114838 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114839 + }
114840 +
114841 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114842 + if (copy_from_user(compat_param,
114843 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
114844 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
114845 + {
114846 + XX_Free(compat_param);
114847 + XX_Free(param);
114848 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114849 + }
114850 +
114851 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
114852 +
114853 + XX_Free(compat_param);
114854 + }
114855 + else
114856 +#endif
114857 + {
114858 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
114859 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
114860 + {
114861 + XX_Free(param);
114862 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114863 + }
114864 + }
114865 +
114866 + if (param->key_size)
114867 + {
114868 + int size = 0;
114869 +
114870 + if (param->key_params.p_key) size += param->key_size;
114871 + if (param->key_params.p_mask) size += param->key_size;
114872 +
114873 + if (size)
114874 + {
114875 + uint8_t *p_tmp;
114876 +
114877 + p_tmp = (uint8_t*) XX_Malloc(size);
114878 + if (!p_tmp)
114879 + {
114880 + XX_Free(param);
114881 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114882 + }
114883 +
114884 + if (param->key_params.p_key)
114885 + {
114886 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
114887 + {
114888 + XX_Free(p_tmp);
114889 + XX_Free(param);
114890 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114891 + }
114892 +
114893 + param->key_params.p_key = p_tmp;
114894 + }
114895 +
114896 + if (param->key_params.p_mask)
114897 + {
114898 + p_tmp += param->key_size;
114899 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
114900 + {
114901 + XX_Free(p_tmp - param->key_size);
114902 + XX_Free(param);
114903 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114904 + }
114905 +
114906 + param->key_params.p_mask = p_tmp;
114907 + }
114908 + }
114909 + }
114910 +
114911 + err = FM_PCD_MatchTableAddKey(
114912 + param->id,
114913 + param->key_indx,
114914 + param->key_size,
114915 + (t_FmPcdCcKeyParams*)&param->key_params);
114916 +
114917 + if (param->key_params.p_key)
114918 + XX_Free(param->key_params.p_key);
114919 + XX_Free(param);
114920 + break;
114921 + }
114922 +
114923 +#if defined(CONFIG_COMPAT)
114924 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
114925 +#endif
114926 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
114927 + {
114928 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
114929 +
114930 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
114931 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114932 + if (!param)
114933 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114934 +
114935 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114936 +
114937 +#if defined(CONFIG_COMPAT)
114938 + if (compat)
114939 + {
114940 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
114941 +
114942 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
114943 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114944 + if (!compat_param)
114945 + {
114946 + XX_Free(param);
114947 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114948 + }
114949 +
114950 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
114951 + if (copy_from_user(compat_param,
114952 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
114953 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
114954 + {
114955 + XX_Free(compat_param);
114956 + XX_Free(param);
114957 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114958 + }
114959 +
114960 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
114961 +
114962 + XX_Free(compat_param);
114963 + }
114964 + else
114965 +#endif
114966 + {
114967 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
114968 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
114969 + {
114970 + XX_Free(param);
114971 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114972 + }
114973 + }
114974 +
114975 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
114976 + param->key_indx,
114977 + param->key_size,
114978 + (t_FmPcdCcKeyParams*)(&param->key_params));
114979 +
114980 + XX_Free(param);
114981 + break;
114982 + }
114983 +
114984 +
114985 +#if defined(CONFIG_COMPAT)
114986 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
114987 +#endif
114988 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
114989 + {
114990 + ioc_fm_pcd_cc_tbl_get_stats_t param;
114991 +
114992 +#if defined(CONFIG_COMPAT)
114993 + if (compat)
114994 + {
114995 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
114996 +
114997 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
114998 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
114999 + if (!compat_param)
115000 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115001 +
115002 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115003 + if (copy_from_user(compat_param,
115004 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
115005 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
115006 + {
115007 + XX_Free(compat_param);
115008 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115009 + }
115010 +
115011 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
115012 +
115013 + XX_Free(compat_param);
115014 + }
115015 + else
115016 +#endif
115017 + {
115018 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115019 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115020 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115021 + }
115022 +
115023 +
115024 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
115025 + param.key_index,
115026 + (t_FmPcdCcKeyStatistics *) &param.statistics);
115027 +
115028 +#if defined(CONFIG_COMPAT)
115029 + if (compat)
115030 + {
115031 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115032 +
115033 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
115034 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115035 + if (!compat_param)
115036 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115037 +
115038 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115039 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
115040 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
115041 + compat_param,
115042 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
115043 + XX_Free(compat_param);
115044 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115045 + }
115046 + XX_Free(compat_param);
115047 + }
115048 + else
115049 +#endif
115050 + {
115051 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115052 + &param,
115053 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115054 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115055 + }
115056 +
115057 + break;
115058 + }
115059 +
115060 +
115061 +#if defined(CONFIG_COMPAT)
115062 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
115063 +#endif
115064 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
115065 + {
115066 + ioc_fm_pcd_cc_tbl_get_stats_t param;
115067 +
115068 +#if defined(CONFIG_COMPAT)
115069 + if (compat)
115070 + {
115071 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115072 +
115073 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
115074 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115075 + if (!compat_param)
115076 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115077 +
115078 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115079 + if (copy_from_user(compat_param,
115080 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
115081 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
115082 + {
115083 + XX_Free(compat_param);
115084 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115085 + }
115086 +
115087 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
115088 +
115089 + XX_Free(compat_param);
115090 + }
115091 + else
115092 +#endif
115093 + {
115094 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115095 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115096 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115097 + }
115098 +
115099 +
115100 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
115101 + (t_FmPcdCcKeyStatistics *) &param.statistics);
115102 +
115103 +#if defined(CONFIG_COMPAT)
115104 + if (compat)
115105 + {
115106 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115107 +
115108 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
115109 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115110 + if (!compat_param)
115111 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115112 +
115113 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115114 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
115115 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
115116 + compat_param,
115117 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
115118 + XX_Free(compat_param);
115119 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115120 + }
115121 + XX_Free(compat_param);
115122 + }
115123 + else
115124 +#endif
115125 + {
115126 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115127 + &param,
115128 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115129 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115130 + }
115131 +
115132 + break;
115133 + }
115134 +
115135 +
115136 +#if defined(CONFIG_COMPAT)
115137 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
115138 +#endif
115139 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
115140 + {
115141 + ioc_fm_pcd_cc_tbl_get_stats_t param;
115142 +
115143 +#if defined(CONFIG_COMPAT)
115144 + if (compat)
115145 + {
115146 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115147 +
115148 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
115149 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115150 + if (!compat_param)
115151 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115152 +
115153 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115154 + if (copy_from_user(compat_param,
115155 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
115156 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
115157 + {
115158 + XX_Free(compat_param);
115159 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115160 + }
115161 +
115162 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
115163 +
115164 + XX_Free(compat_param);
115165 + }
115166 + else
115167 +#endif
115168 + {
115169 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115170 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115171 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115172 + }
115173 +
115174 +
115175 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
115176 + (t_FmPcdCcKeyStatistics *) &param.statistics);
115177 +
115178 +#if defined(CONFIG_COMPAT)
115179 + if (compat)
115180 + {
115181 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115182 +
115183 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
115184 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115185 + if (!compat_param)
115186 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115187 +
115188 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115189 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
115190 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
115191 + compat_param,
115192 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
115193 + XX_Free(compat_param);
115194 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115195 + }
115196 + XX_Free(compat_param);
115197 + }
115198 + else
115199 +#endif
115200 + {
115201 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115202 + &param,
115203 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115204 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115205 + }
115206 +
115207 + break;
115208 + }
115209 +
115210 +#if defined(CONFIG_COMPAT)
115211 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
115212 +#endif
115213 + case FM_PCD_IOC_HASH_TABLE_SET:
115214 + {
115215 + ioc_fm_pcd_hash_table_params_t *param;
115216 +
115217 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
115218 + sizeof(ioc_fm_pcd_hash_table_params_t));
115219 + if (!param)
115220 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115221 +
115222 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
115223 +
115224 +#if defined(CONFIG_COMPAT)
115225 + if (compat)
115226 + {
115227 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
115228 +
115229 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
115230 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115231 + if (!compat_param)
115232 + {
115233 + XX_Free(param);
115234 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115235 + }
115236 +
115237 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115238 + if (copy_from_user(compat_param,
115239 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
115240 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
115241 + {
115242 + XX_Free(compat_param);
115243 + XX_Free(param);
115244 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115245 + }
115246 +
115247 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
115248 +
115249 + XX_Free(compat_param);
115250 + }
115251 + else
115252 +#endif
115253 + {
115254 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
115255 + sizeof(ioc_fm_pcd_hash_table_params_t)))
115256 + {
115257 + XX_Free(param);
115258 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115259 + }
115260 + }
115261 +
115262 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
115263 +
115264 + if (!param->id)
115265 + {
115266 + XX_Free(param);
115267 + err = E_INVALID_VALUE;
115268 + /* Since the LLD has no errno-style error reporting,
115269 + we're left here with no other option than to report
115270 + a generic E_INVALID_VALUE */
115271 + break;
115272 + }
115273 +
115274 +#if defined(CONFIG_COMPAT)
115275 + if (compat)
115276 + {
115277 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
115278 +
115279 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
115280 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115281 + if (!compat_param)
115282 + {
115283 + XX_Free(param);
115284 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115285 + }
115286 +
115287 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115288 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
115289 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
115290 + compat_param,
115291 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
115292 + err = E_READ_FAILED;
115293 +
115294 + XX_Free(compat_param);
115295 + }
115296 + else
115297 +#endif
115298 + {
115299 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
115300 + param,
115301 + sizeof(ioc_fm_pcd_hash_table_params_t)))
115302 + err = E_READ_FAILED;
115303 + }
115304 +
115305 + XX_Free(param);
115306 + break;
115307 + }
115308 +
115309 +#if defined(CONFIG_COMPAT)
115310 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
115311 +#endif
115312 + case FM_PCD_IOC_HASH_TABLE_DELETE:
115313 + {
115314 + ioc_fm_obj_t id;
115315 +
115316 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115317 +
115318 +#if defined(CONFIG_COMPAT)
115319 + if (compat)
115320 + {
115321 + ioc_compat_fm_obj_t compat_id;
115322 +
115323 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115324 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115325 +
115326 + id.obj = compat_pcd_id2ptr(compat_id.obj);
115327 + }
115328 + else
115329 +#endif
115330 + {
115331 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115332 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115333 + }
115334 +
115335 + err = FM_PCD_HashTableDelete(id.obj);
115336 + break;
115337 + }
115338 +
115339 +#if defined(CONFIG_COMPAT)
115340 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
115341 +#endif
115342 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
115343 + {
115344 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
115345 +
115346 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
115347 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
115348 + if (!param)
115349 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115350 +
115351 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
115352 +
115353 +#if defined(CONFIG_COMPAT)
115354 + if (compat)
115355 + {
115356 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
115357 +
115358 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
115359 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
115360 + if (!compat_param)
115361 + {
115362 + XX_Free(param);
115363 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115364 + }
115365 +
115366 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
115367 + if (copy_from_user(compat_param,
115368 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
115369 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
115370 + {
115371 + XX_Free(compat_param);
115372 + XX_Free(param);
115373 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115374 + }
115375 +
115376 + if (compat_param->key_size)
115377 + {
115378 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
115379 + param->key_size = compat_param->key_size;
115380 +
115381 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
115382 + }
115383 + else
115384 + {
115385 + XX_Free(compat_param);
115386 + XX_Free(param);
115387 + err = E_INVALID_VALUE;
115388 + break;
115389 + }
115390 +
115391 + XX_Free(compat_param);
115392 + }
115393 + else
115394 +#endif
115395 + {
115396 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
115397 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
115398 + {
115399 + XX_Free(param);
115400 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115401 + }
115402 + }
115403 +
115404 + if (param->key_size)
115405 + {
115406 + int size = 0;
115407 +
115408 + if (param->key_params.p_key) size += param->key_size;
115409 + if (param->key_params.p_mask) size += param->key_size;
115410 +
115411 + if (size)
115412 + {
115413 + uint8_t *p_tmp;
115414 +
115415 + p_tmp = (uint8_t*) XX_Malloc(size);
115416 + if (!p_tmp)
115417 + {
115418 + XX_Free(param);
115419 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
115420 + }
115421 +
115422 + if (param->key_params.p_key)
115423 + {
115424 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
115425 + {
115426 + XX_Free(p_tmp);
115427 + XX_Free(param);
115428 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115429 + }
115430 +
115431 + param->key_params.p_key = p_tmp;
115432 + }
115433 +
115434 + if (param->key_params.p_mask)
115435 + {
115436 + p_tmp += param->key_size;
115437 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
115438 + {
115439 + XX_Free(p_tmp - param->key_size);
115440 + XX_Free(param);
115441 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115442 + }
115443 +
115444 + param->key_params.p_mask = p_tmp;
115445 + }
115446 + }
115447 + }
115448 +
115449 + err = FM_PCD_HashTableAddKey(
115450 + param->p_hash_tbl,
115451 + param->key_size,
115452 + (t_FmPcdCcKeyParams*)&param->key_params);
115453 +
115454 + if (param->key_params.p_key)
115455 + XX_Free(param->key_params.p_key);
115456 + XX_Free(param);
115457 + break;
115458 + }
115459 +
115460 +#if defined(CONFIG_COMPAT)
115461 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
115462 +#endif
115463 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
115464 + {
115465 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
115466 +
115467 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
115468 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
115469 + if (!param)
115470 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115471 +
115472 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
115473 +
115474 +#if defined(CONFIG_COMPAT)
115475 + if (compat)
115476 + {
115477 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
115478 +
115479 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
115480 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
115481 + if (!compat_param)
115482 + {
115483 + XX_Free(param);
115484 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115485 + }
115486 +
115487 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
115488 + if (copy_from_user(compat_param,
115489 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
115490 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
115491 + {
115492 + XX_Free(compat_param);
115493 + XX_Free(param);
115494 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115495 + }
115496 +
115497 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
115498 + param->key_size = compat_param->key_size;
115499 +
115500 + XX_Free(compat_param);
115501 + }
115502 + else
115503 +#endif
115504 + {
115505 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
115506 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
115507 + {
115508 + XX_Free(param);
115509 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115510 + }
115511 + }
115512 +
115513 + if (param->key_size)
115514 + {
115515 + uint8_t *p_key;
115516 +
115517 + p_key = (uint8_t*) XX_Malloc(param->key_size);
115518 + if (!p_key)
115519 + {
115520 + XX_Free(param);
115521 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115522 + }
115523 +
115524 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
115525 + {
115526 + XX_Free(p_key);
115527 + XX_Free(param);
115528 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115529 + }
115530 + param->p_key = p_key;
115531 + }
115532 +
115533 + err = FM_PCD_HashTableRemoveKey(
115534 + param->p_hash_tbl,
115535 + param->key_size,
115536 + param->p_key);
115537 +
115538 + if (param->p_key)
115539 + XX_Free(param->p_key);
115540 + XX_Free(param);
115541 + break;
115542 + }
115543 +
115544 +#if defined(CONFIG_COMPAT)
115545 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
115546 +#endif
115547 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
115548 + {
115549 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
115550 +
115551 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
115552 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
115553 + if (!param)
115554 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115555 +
115556 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
115557 +
115558 +#if defined(CONFIG_COMPAT)
115559 + if (compat)
115560 + {
115561 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
115562 +
115563 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
115564 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
115565 + if (!compat_param)
115566 + {
115567 + XX_Free(param);
115568 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115569 + }
115570 +
115571 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
115572 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
115573 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
115574 + {
115575 + XX_Free(compat_param);
115576 + XX_Free(param);
115577 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115578 + }
115579 +
115580 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
115581 +
115582 + XX_Free(compat_param);
115583 + }
115584 + else
115585 +#endif
115586 + {
115587 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
115588 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
115589 + {
115590 + XX_Free(param);
115591 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115592 + }
115593 + }
115594 +
115595 + if (param->key_size)
115596 + {
115597 + int size = 0;
115598 +
115599 + if (param->p_key) size += param->key_size;
115600 + if (param->p_mask) size += param->key_size;
115601 +
115602 + if (size)
115603 + {
115604 + uint8_t *p_tmp;
115605 +
115606 + p_tmp = (uint8_t*) XX_Malloc(size);
115607 + if (!p_tmp)
115608 + {
115609 + XX_Free(param);
115610 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
115611 + }
115612 +
115613 + if (param->p_key)
115614 + {
115615 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
115616 + {
115617 + XX_Free(p_tmp);
115618 + XX_Free(param);
115619 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115620 + }
115621 +
115622 + param->p_key = p_tmp;
115623 + }
115624 +
115625 + if (param->p_mask)
115626 + {
115627 + p_tmp += param->key_size;
115628 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
115629 + {
115630 + XX_Free(p_tmp - param->key_size);
115631 + XX_Free(param);
115632 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115633 + }
115634 +
115635 + param->p_mask = p_tmp;
115636 + }
115637 + }
115638 + }
115639 +
115640 + err = FM_PCD_MatchTableModifyKey(param->id,
115641 + param->key_indx,
115642 + param->key_size,
115643 + param->p_key,
115644 + param->p_mask);
115645 +
115646 + if (param->p_key)
115647 + XX_Free(param->p_key);
115648 + else if (param->p_mask)
115649 + XX_Free(param->p_mask);
115650 + XX_Free(param);
115651 + break;
115652 + }
115653 +
115654 +#if defined(CONFIG_COMPAT)
115655 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
115656 +#endif
115657 + case FM_PCD_IOC_MANIP_NODE_SET:
115658 + {
115659 + ioc_fm_pcd_manip_params_t *param;
115660 + uint8_t *p_data = NULL;
115661 + uint8_t size;
115662 +
115663 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
115664 + sizeof(ioc_fm_pcd_manip_params_t));
115665 +
115666 + if (!param)
115667 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115668 +
115669 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
115670 +
115671 +#if defined(CONFIG_COMPAT)
115672 + if (compat)
115673 + {
115674 + ioc_compat_fm_pcd_manip_params_t *compat_param;
115675 +
115676 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
115677 + sizeof(ioc_compat_fm_pcd_manip_params_t));
115678 + if (!compat_param)
115679 + {
115680 + XX_Free(param);
115681 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115682 + }
115683 +
115684 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
115685 + if (copy_from_user(compat_param,
115686 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
115687 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
115688 + {
115689 + XX_Free(compat_param);
115690 + XX_Free(param);
115691 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115692 + }
115693 +
115694 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
115695 +
115696 + XX_Free(compat_param);
115697 + }
115698 + else
115699 +#endif
115700 + {
115701 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
115702 + sizeof(ioc_fm_pcd_manip_params_t)))
115703 + {
115704 + XX_Free(param);
115705 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115706 + }
115707 + }
115708 +
115709 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
115710 + {
115711 + size = param->u.hdr.insrt_params.u.generic.size;
115712 + p_data = (uint8_t *) XX_Malloc(size);
115713 + if (!p_data )
115714 + {
115715 + XX_Free(param);
115716 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
115717 + }
115718 +
115719 + if (param->u.hdr.insrt_params.u.generic.p_data &&
115720 + copy_from_user(p_data,
115721 + param->u.hdr.insrt_params.u.generic.p_data, size))
115722 + {
115723 + XX_Free(p_data);
115724 + XX_Free(param);
115725 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115726 + }
115727 +
115728 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
115729 + }
115730 +
115731 + if (param->id)
115732 + {
115733 + /* Security Hole: the user can pass any piece of garbage
115734 + in 'param->id', and that will go straight through to the LLD,
115735 + no checks being done by the wrapper! */
115736 + err = FM_PCD_ManipNodeReplace(
115737 + (t_Handle) param->id,
115738 + (t_FmPcdManipParams*) param);
115739 + if (err)
115740 + {
115741 + if (p_data)
115742 + XX_Free(p_data);
115743 + XX_Free(param);
115744 + break;
115745 + }
115746 + }
115747 + else
115748 + {
115749 + param->id = FM_PCD_ManipNodeSet(
115750 + p_LnxWrpFmDev->h_PcdDev,
115751 + (t_FmPcdManipParams*) param);
115752 + if (!param->id)
115753 + {
115754 + if (p_data)
115755 + XX_Free(p_data);
115756 + XX_Free(param);
115757 + err = E_INVALID_VALUE;
115758 + /* Since the LLD has no errno-style error reporting,
115759 + we're left here with no other option than to report
115760 + a generic E_INVALID_VALUE */
115761 + break;
115762 + }
115763 + }
115764 +
115765 +#if defined(CONFIG_COMPAT)
115766 + if (compat)
115767 + {
115768 + ioc_compat_fm_pcd_manip_params_t *compat_param;
115769 +
115770 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
115771 + sizeof(ioc_compat_fm_pcd_manip_params_t));
115772 + if (!compat_param)
115773 + {
115774 + if (p_data)
115775 + XX_Free(p_data);
115776 + XX_Free(param);
115777 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115778 + }
115779 +
115780 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
115781 +
115782 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
115783 +
115784 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
115785 + compat_param,
115786 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
115787 + err = E_READ_FAILED;
115788 +
115789 + XX_Free(compat_param);
115790 + }
115791 + else
115792 +#endif
115793 + {
115794 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
115795 + param, sizeof(ioc_fm_pcd_manip_params_t)))
115796 + err = E_READ_FAILED;
115797 + }
115798 +
115799 + if (p_data)
115800 + XX_Free(p_data);
115801 + XX_Free(param);
115802 + break;
115803 + }
115804 +
115805 +#if defined(CONFIG_COMPAT)
115806 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
115807 +#endif
115808 + case FM_PCD_IOC_MANIP_NODE_DELETE:
115809 + {
115810 + ioc_fm_obj_t id;
115811 +
115812 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115813 +#if defined(CONFIG_COMPAT)
115814 + if (compat)
115815 + {
115816 + ioc_compat_fm_obj_t compat_id;
115817 +
115818 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115819 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115820 +
115821 + compat_obj_delete(&compat_id, &id);
115822 + }
115823 + else
115824 +#endif
115825 + {
115826 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115827 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115828 + }
115829 +
115830 + err = FM_PCD_ManipNodeDelete(id.obj);
115831 + break;
115832 + }
115833 +
115834 +#if defined(CONFIG_COMPAT)
115835 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
115836 +#endif
115837 + case FM_PCD_IOC_MANIP_GET_STATS:
115838 + {
115839 + ioc_fm_pcd_manip_get_stats_t param;
115840 +
115841 +#if defined(CONFIG_COMPAT)
115842 + if (compat)
115843 + {
115844 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
115845 +
115846 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
115847 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
115848 + if (!compat_param)
115849 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115850 +
115851 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
115852 + if (copy_from_user(compat_param,
115853 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
115854 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
115855 + {
115856 + XX_Free(compat_param);
115857 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115858 + }
115859 +
115860 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
115861 +
115862 + XX_Free(compat_param);
115863 + }
115864 + else
115865 +#endif
115866 + {
115867 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
115868 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
115869 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115870 + }
115871 +
115872 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
115873 + (t_FmPcdManipStats*) &param.stats);
115874 +
115875 +#if defined(CONFIG_COMPAT)
115876 + if (compat)
115877 + {
115878 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
115879 +
115880 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
115881 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
115882 + if (!compat_param)
115883 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115884 +
115885 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
115886 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
115887 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
115888 + compat_param,
115889 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
115890 + XX_Free(compat_param);
115891 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115892 + }
115893 + XX_Free(compat_param);
115894 + }
115895 + else
115896 +#endif
115897 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
115898 + &param,
115899 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
115900 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115901 +
115902 + break;
115903 + }
115904 +
115905 +#if (DPAA_VERSION >= 11)
115906 +#if defined(CONFIG_COMPAT)
115907 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
115908 +#endif
115909 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
115910 + {
115911 + ioc_fm_pcd_frm_replic_group_params_t *param;
115912 +
115913 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
115914 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
115915 + if (!param)
115916 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115917 +
115918 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
115919 +
115920 +#if defined(CONFIG_COMPAT)
115921 + if (compat)
115922 + {
115923 + ioc_compat_fm_pcd_frm_replic_group_params_t
115924 + *compat_param;
115925 +
115926 + compat_param =
115927 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
115928 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
115929 + if (!compat_param)
115930 + {
115931 + XX_Free(param);
115932 + RETURN_ERROR(MINOR, E_NO_MEMORY,
115933 + ("IOCTL FM PCD"));
115934 + }
115935 +
115936 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
115937 + if (copy_from_user(compat_param,
115938 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
115939 + compat_ptr(arg),
115940 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
115941 + XX_Free(compat_param);
115942 + XX_Free(param);
115943 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115944 + }
115945 +
115946 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
115947 + param, COMPAT_US_TO_K);
115948 +
115949 + XX_Free(compat_param);
115950 + }
115951 + else
115952 +#endif
115953 + {
115954 + if (copy_from_user(param,
115955 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
115956 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
115957 + {
115958 + XX_Free(param);
115959 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115960 + }
115961 + }
115962 +
115963 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
115964 + (t_FmPcdFrmReplicGroupParams*)param);
115965 +
115966 + if (!param->id) {
115967 + XX_Free(param);
115968 + err = E_INVALID_VALUE;
115969 + /*
115970 + * Since the LLD has no errno-style error reporting,
115971 + * we're left here with no other option than to report
115972 + * a generic E_INVALID_VALUE
115973 + */
115974 + break;
115975 + }
115976 +
115977 +#if defined(CONFIG_COMPAT)
115978 + if (compat)
115979 + {
115980 + ioc_compat_fm_pcd_frm_replic_group_params_t
115981 + *compat_param;
115982 +
115983 + compat_param =
115984 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
115985 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
115986 + if (!compat_param)
115987 + {
115988 + XX_Free(param);
115989 + RETURN_ERROR(MINOR, E_NO_MEMORY,
115990 + ("IOCTL FM PCD"));
115991 + }
115992 +
115993 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
115994 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
115995 + param, COMPAT_K_TO_US);
115996 + if (copy_to_user(
115997 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
115998 + compat_ptr(arg),
115999 + compat_param,
116000 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
116001 + err = E_WRITE_FAILED;
116002 +
116003 + XX_Free(compat_param);
116004 + }
116005 + else
116006 +#endif
116007 + {
116008 + if (copy_to_user(
116009 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
116010 + param,
116011 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
116012 + err = E_WRITE_FAILED;
116013 + }
116014 +
116015 + XX_Free(param);
116016 + break;
116017 + }
116018 + break;
116019 +
116020 +#if defined(CONFIG_COMPAT)
116021 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
116022 +#endif
116023 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
116024 + {
116025 + ioc_fm_obj_t id;
116026 +
116027 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116028 +#if defined(CONFIG_COMPAT)
116029 + if (compat)
116030 + {
116031 + ioc_compat_fm_obj_t compat_id;
116032 +
116033 + if (copy_from_user(&compat_id,
116034 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
116035 + sizeof(ioc_compat_fm_obj_t)))
116036 + break;
116037 + compat_obj_delete(&compat_id, &id);
116038 + }
116039 + else
116040 +#endif
116041 + {
116042 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
116043 + sizeof(ioc_fm_obj_t)))
116044 + break;
116045 + }
116046 +
116047 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
116048 + }
116049 + break;
116050 +
116051 +#if defined(CONFIG_COMPAT)
116052 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
116053 +#endif
116054 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
116055 + {
116056 + ioc_fm_pcd_frm_replic_member_params_t param;
116057 +
116058 +#if defined(CONFIG_COMPAT)
116059 + if (compat)
116060 + {
116061 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
116062 +
116063 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116064 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116065 +
116066 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
116067 + }
116068 + else
116069 +#endif
116070 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116071 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116072 +
116073 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
116074 + param.member.member_index,
116075 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
116076 + }
116077 + break;
116078 +
116079 +#if defined(CONFIG_COMPAT)
116080 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
116081 +#endif
116082 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
116083 + {
116084 + ioc_fm_pcd_frm_replic_member_t param;
116085 +
116086 +#if defined(CONFIG_COMPAT)
116087 + if (compat)
116088 + {
116089 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
116090 +
116091 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116092 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116093 +
116094 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
116095 + }
116096 + else
116097 +#endif
116098 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116099 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116100 +
116101 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
116102 + }
116103 + break;
116104 +
116105 +#if defined(CONFIG_COMPAT)
116106 + case FM_IOC_VSP_CONFIG_COMPAT:
116107 +#endif
116108 + case FM_IOC_VSP_CONFIG:
116109 + {
116110 + ioc_fm_vsp_params_t param;
116111 +
116112 +#if defined(CONFIG_COMPAT)
116113 + if (compat)
116114 + {
116115 + ioc_compat_fm_vsp_params_t compat_param;
116116 +
116117 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116118 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116119 +
116120 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
116121 + }
116122 + else
116123 +#endif
116124 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116125 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116126 + {
116127 + uint8_t portId = param.port_params.port_id;
116128 + param.liodn_offset =
116129 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
116130 + }
116131 + param.p_fm = p_LnxWrpFmDev->h_Dev;
116132 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
116133 +
116134 +#if defined(CONFIG_COMPAT)
116135 + if (compat)
116136 + {
116137 + ioc_compat_fm_vsp_params_t compat_param;
116138 +
116139 + memset(&compat_param, 0, sizeof(compat_param));
116140 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
116141 +
116142 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
116143 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116144 + }
116145 + else
116146 +#endif
116147 + if (copy_to_user((void *)arg, &param, sizeof(param)))
116148 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116149 + break;
116150 + }
116151 +
116152 +#if defined(CONFIG_COMPAT)
116153 + case FM_IOC_VSP_INIT_COMPAT:
116154 +#endif
116155 + case FM_IOC_VSP_INIT:
116156 + {
116157 + ioc_fm_obj_t id;
116158 +
116159 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116160 +#if defined(CONFIG_COMPAT)
116161 + if (compat)
116162 + {
116163 + ioc_compat_fm_obj_t compat_id;
116164 +
116165 + if (copy_from_user(&compat_id,
116166 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
116167 + sizeof(ioc_compat_fm_obj_t)))
116168 + break;
116169 + id.obj = compat_pcd_id2ptr(compat_id.obj);
116170 + }
116171 + else
116172 +#endif
116173 + {
116174 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
116175 + sizeof(ioc_fm_obj_t)))
116176 + break;
116177 + }
116178 +
116179 + return FM_VSP_Init(id.obj);
116180 + }
116181 +
116182 +#if defined(CONFIG_COMPAT)
116183 + case FM_IOC_VSP_FREE_COMPAT:
116184 +#endif
116185 + case FM_IOC_VSP_FREE:
116186 + {
116187 + ioc_fm_obj_t id;
116188 +
116189 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116190 +#if defined(CONFIG_COMPAT)
116191 + if (compat)
116192 + {
116193 + ioc_compat_fm_obj_t compat_id;
116194 +
116195 + if (copy_from_user(&compat_id,
116196 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
116197 + sizeof(ioc_compat_fm_obj_t)))
116198 + break;
116199 + compat_obj_delete(&compat_id, &id);
116200 + }
116201 + else
116202 +#endif
116203 + {
116204 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
116205 + sizeof(ioc_fm_obj_t)))
116206 + break;
116207 + }
116208 +
116209 + return FM_VSP_Free(id.obj);
116210 + }
116211 +
116212 +#if defined(CONFIG_COMPAT)
116213 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
116214 +#endif
116215 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
116216 + {
116217 + ioc_fm_buf_pool_depletion_params_t param;
116218 +
116219 +#if defined(CONFIG_COMPAT)
116220 + if (compat)
116221 + {
116222 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
116223 +
116224 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116225 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116226 +
116227 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
116228 + }
116229 + else
116230 +#endif
116231 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116232 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116233 +
116234 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
116235 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
116236 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116237 +
116238 + break;
116239 + }
116240 +
116241 +
116242 +#if defined(CONFIG_COMPAT)
116243 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
116244 +#endif
116245 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
116246 + {
116247 + ioc_fm_buffer_prefix_content_params_t param;
116248 +
116249 +#if defined(CONFIG_COMPAT)
116250 + if (compat)
116251 + {
116252 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
116253 +
116254 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116255 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116256 +
116257 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
116258 + }
116259 + else
116260 +#endif
116261 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116262 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116263 +
116264 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
116265 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
116266 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116267 +
116268 + break;
116269 + }
116270 +
116271 +#if defined(CONFIG_COMPAT)
116272 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
116273 +#endif
116274 + case FM_IOC_VSP_CONFIG_NO_SG:
116275 + {
116276 + ioc_fm_vsp_config_no_sg_params_t param;
116277 +
116278 +#if defined(CONFIG_COMPAT)
116279 + if (compat)
116280 + {
116281 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
116282 +
116283 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116284 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116285 +
116286 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
116287 + }
116288 + else
116289 +#endif
116290 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116291 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116292 +
116293 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
116294 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116295 +
116296 + break;
116297 + }
116298 +
116299 +#if defined(CONFIG_COMPAT)
116300 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
116301 +#endif
116302 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
116303 + {
116304 + ioc_fm_vsp_prs_result_params_t param;
116305 +
116306 +#if defined(CONFIG_COMPAT)
116307 + if (compat)
116308 + {
116309 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
116310 +
116311 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116312 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116313 +
116314 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
116315 + }
116316 + else
116317 +#endif
116318 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116319 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116320 +
116321 + /* this call just adds the parse results offset to p_data */
116322 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
116323 +
116324 + if (!param.p_data)
116325 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116326 +
116327 +#if defined(CONFIG_COMPAT)
116328 + if (compat)
116329 + {
116330 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
116331 +
116332 + memset(&compat_param, 0, sizeof(compat_param));
116333 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
116334 +
116335 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
116336 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116337 + }
116338 + else
116339 +#endif
116340 + if (copy_to_user((void *)arg, &param, sizeof(param)))
116341 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116342 +
116343 + break;
116344 + }
116345 +#endif /* (DPAA_VERSION >= 11) */
116346 +
116347 +#ifdef FM_CAPWAP_SUPPORT
116348 +#warning "feature not supported!"
116349 +#if defined(CONFIG_COMPAT)
116350 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
116351 +#endif
116352 + case FM_PCD_IOC_STATISTICS_SET_NODE:
116353 + {
116354 +/* ioc_fm_pcd_stats_params_t param;
116355 + ...
116356 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
116357 + (t_FmPcdStatsParams *)&param);
116358 +*/
116359 + err = E_NOT_SUPPORTED;
116360 + break;
116361 + }
116362 +#endif /* FM_CAPWAP_SUPPORT */
116363 +
116364 + default:
116365 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116366 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
116367 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116368 + }
116369 +
116370 + if (err)
116371 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
116372 +
116373 + return E_OK;
116374 +}
116375 +
116376 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
116377 +{
116378 + p_version->version.major = FMD_API_VERSION_MAJOR;
116379 + p_version->version.minor = FMD_API_VERSION_MINOR;
116380 + p_version->version.respin = FMD_API_VERSION_RESPIN;
116381 + p_version->version.reserved = 0;
116382 +}
116383 +
116384 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
116385 +{
116386 + t_Error err = E_OK;
116387 +
116388 + switch (cmd)
116389 + {
116390 + case FM_IOC_SET_PORTS_BANDWIDTH:
116391 + {
116392 + ioc_fm_port_bandwidth_params *param;
116393 +
116394 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
116395 + if (!param)
116396 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116397 +
116398 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
116399 +
116400 +#if defined(CONFIG_COMPAT)
116401 + if (compat)
116402 + {
116403 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
116404 + {
116405 + XX_Free(param);
116406 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116407 + }
116408 + }
116409 + else
116410 +#endif
116411 + {
116412 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
116413 + {
116414 + XX_Free(param);
116415 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116416 + }
116417 + }
116418 +
116419 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
116420 +
116421 + XX_Free(param);
116422 + break;
116423 + }
116424 +
116425 + case FM_IOC_GET_REVISION:
116426 + {
116427 + ioc_fm_revision_info_t *param;
116428 +
116429 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
116430 + if (!param)
116431 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116432 +
116433 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
116434 + /* This one never returns anything other than E_OK */
116435 +
116436 +#if defined(CONFIG_COMPAT)
116437 + if (compat)
116438 + {
116439 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
116440 + param,
116441 + sizeof(ioc_fm_revision_info_t))){
116442 + XX_Free(param);
116443 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116444 + }
116445 + }
116446 + else
116447 +#endif
116448 + {
116449 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
116450 + param,
116451 + sizeof(ioc_fm_revision_info_t))){
116452 + XX_Free(param);
116453 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116454 + }
116455 + }
116456 + XX_Free(param);
116457 + break;
116458 + }
116459 +
116460 + case FM_IOC_SET_COUNTER:
116461 + {
116462 + ioc_fm_counters_params_t *param;
116463 +
116464 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
116465 + if (!param)
116466 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116467 +
116468 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
116469 +
116470 +#if defined(CONFIG_COMPAT)
116471 + if (compat)
116472 + {
116473 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
116474 + {
116475 + XX_Free(param);
116476 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116477 + }
116478 + }
116479 + else
116480 +#endif
116481 + {
116482 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
116483 + {
116484 + XX_Free(param);
116485 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116486 + }
116487 + }
116488 +
116489 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
116490 +
116491 + XX_Free(param);
116492 + break;
116493 + }
116494 +
116495 + case FM_IOC_GET_COUNTER:
116496 + {
116497 + ioc_fm_counters_params_t *param;
116498 +
116499 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
116500 + if (!param)
116501 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116502 +
116503 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
116504 +
116505 +#if defined(CONFIG_COMPAT)
116506 + if (compat)
116507 + {
116508 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
116509 + {
116510 + XX_Free(param);
116511 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116512 + }
116513 + }
116514 + else
116515 +#endif
116516 + {
116517 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
116518 + {
116519 + XX_Free(param);
116520 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116521 + }
116522 + }
116523 +
116524 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
116525 +
116526 +#if defined(CONFIG_COMPAT)
116527 + if (compat)
116528 + {
116529 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
116530 + err = E_READ_FAILED;
116531 + }
116532 + else
116533 +#endif
116534 + {
116535 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
116536 + err = E_READ_FAILED;
116537 + }
116538 +
116539 + XX_Free(param);
116540 + break;
116541 + }
116542 +
116543 + case FM_IOC_FORCE_INTR:
116544 + {
116545 + ioc_fm_exceptions param;
116546 +
116547 +#if defined(CONFIG_COMPAT)
116548 + if (compat)
116549 + {
116550 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
116551 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116552 + }
116553 + else
116554 +#endif
116555 + {
116556 + if (get_user(param, (ioc_fm_exceptions*)arg))
116557 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116558 + }
116559 +
116560 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
116561 + break;
116562 + }
116563 +
116564 + case FM_IOC_GET_API_VERSION:
116565 + {
116566 + ioc_fm_api_version_t version;
116567 +
116568 + FM_Get_Api_Version(&version);
116569 +
116570 +#if defined(CONFIG_COMPAT)
116571 + if (compat)
116572 + {
116573 + if (copy_to_user(
116574 + (ioc_fm_api_version_t *)compat_ptr(arg),
116575 + &version, sizeof(version)))
116576 + err = E_READ_FAILED;
116577 + }
116578 + else
116579 +#endif
116580 + {
116581 + if (copy_to_user((ioc_fm_api_version_t *)arg,
116582 + &version, sizeof(version)))
116583 + err = E_READ_FAILED;
116584 + }
116585 + }
116586 + break;
116587 +
116588 + case FM_IOC_CTRL_MON_START:
116589 + {
116590 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
116591 + }
116592 + break;
116593 +
116594 + case FM_IOC_CTRL_MON_STOP:
116595 + {
116596 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
116597 + }
116598 + break;
116599 +
116600 +#if defined(CONFIG_COMPAT)
116601 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
116602 +#endif
116603 + case FM_IOC_CTRL_MON_GET_COUNTERS:
116604 + {
116605 + ioc_fm_ctrl_mon_counters_params_t param;
116606 + t_FmCtrlMon mon;
116607 +
116608 +#if defined(CONFIG_COMPAT)
116609 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
116610 +
116611 + if (compat)
116612 + {
116613 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
116614 + sizeof(compat_param)))
116615 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116616 +
116617 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
116618 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
116619 + }
116620 + else
116621 +#endif
116622 + {
116623 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
116624 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116625 + }
116626 +
116627 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
116628 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116629 +
116630 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
116631 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116632 + }
116633 + break;
116634 +
116635 + default:
116636 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
116637 + }
116638 +
116639 + if (err)
116640 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
116641 +
116642 + return E_OK;
116643 +}
116644 +
116645 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
116646 +{
116647 + t_Error err = E_OK;
116648 +
116649 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
116650 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
116651 +
116652 + switch (cmd)
116653 + {
116654 + case FM_PORT_IOC_DISABLE:
116655 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
116656 + /* deliberately ignoring error codes here */
116657 + return E_OK;
116658 +
116659 + case FM_PORT_IOC_ENABLE:
116660 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
116661 + /* deliberately ignoring error codes here */
116662 + return E_OK;
116663 +
116664 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
116665 + {
116666 + ioc_fm_port_frame_err_select_t errs;
116667 +
116668 +#if defined(CONFIG_COMPAT)
116669 + if (compat)
116670 + {
116671 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
116672 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116673 + }
116674 + else
116675 +#endif
116676 + {
116677 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
116678 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116679 + }
116680 +
116681 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
116682 + break;
116683 + }
116684 +
116685 + case FM_PORT_IOC_SET_RATE_LIMIT:
116686 + {
116687 + ioc_fm_port_rate_limit_t *param;
116688 +
116689 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
116690 + if (!param)
116691 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116692 +
116693 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
116694 +
116695 +#if defined(CONFIG_COMPAT)
116696 + if (compat)
116697 + {
116698 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
116699 + {
116700 + XX_Free(param);
116701 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116702 + }
116703 + }
116704 + else
116705 +#endif
116706 + {
116707 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
116708 + {
116709 + XX_Free(param);
116710 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116711 + }
116712 + }
116713 +
116714 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
116715 +
116716 + XX_Free(param);
116717 + break;
116718 + }
116719 +
116720 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
116721 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
116722 + /* deliberately ignoring error codes here */
116723 + return E_OK;
116724 +
116725 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
116726 + {
116727 + ioc_fm_port_pcd_fqids_params_t *param;
116728 +
116729 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
116730 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
116731 +
116732 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
116733 + if (!param)
116734 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116735 +
116736 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
116737 +
116738 +#if defined(CONFIG_COMPAT)
116739 + if (compat)
116740 + {
116741 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
116742 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
116743 + {
116744 + XX_Free(param);
116745 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116746 + }
116747 + }
116748 + else
116749 +#endif
116750 + {
116751 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
116752 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
116753 + {
116754 + XX_Free(param);
116755 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116756 + }
116757 + }
116758 +
116759 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
116760 + param->num_fqids,
116761 + param->alignment,
116762 + &param->base_fqid))
116763 + {
116764 + XX_Free(param);
116765 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
116766 + }
116767 +
116768 +#if defined(CONFIG_COMPAT)
116769 + if (compat)
116770 + {
116771 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
116772 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
116773 + err = E_READ_FAILED;
116774 + }
116775 + else
116776 +#endif
116777 + {
116778 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
116779 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
116780 + err = E_READ_FAILED;
116781 + }
116782 +
116783 + XX_Free(param);
116784 + break;
116785 + }
116786 +
116787 + case FM_PORT_IOC_FREE_PCD_FQIDS:
116788 + {
116789 + uint32_t base_fqid;
116790 +
116791 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
116792 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
116793 +
116794 +#if defined(CONFIG_COMPAT)
116795 + if (compat)
116796 + {
116797 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
116798 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116799 + }
116800 + else
116801 +#endif
116802 + {
116803 + if (get_user(base_fqid, (uint32_t*)arg))
116804 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116805 + }
116806 +
116807 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
116808 + err = E_WRITE_FAILED;
116809 +
116810 + break;
116811 + }
116812 +
116813 +#if defined(CONFIG_COMPAT)
116814 + case FM_PORT_IOC_SET_PCD_COMPAT:
116815 +#endif
116816 + case FM_PORT_IOC_SET_PCD:
116817 + {
116818 + ioc_fm_port_pcd_params_t *port_pcd_params;
116819 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
116820 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
116821 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
116822 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
116823 +
116824 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
116825 + sizeof(ioc_fm_port_pcd_params_t) +
116826 + sizeof(ioc_fm_port_pcd_prs_params_t) +
116827 + sizeof(ioc_fm_port_pcd_cc_params_t) +
116828 + sizeof(ioc_fm_port_pcd_kg_params_t) +
116829 + sizeof(ioc_fm_port_pcd_plcr_params_t));
116830 + if (!port_pcd_params)
116831 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116832 +
116833 + memset(port_pcd_params, 0,
116834 + sizeof(ioc_fm_port_pcd_params_t) +
116835 + sizeof(ioc_fm_port_pcd_prs_params_t) +
116836 + sizeof(ioc_fm_port_pcd_cc_params_t) +
116837 + sizeof(ioc_fm_port_pcd_kg_params_t) +
116838 + sizeof(ioc_fm_port_pcd_plcr_params_t));
116839 +
116840 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
116841 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
116842 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
116843 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
116844 +
116845 +#if defined(CONFIG_COMPAT)
116846 + if (compat)
116847 + {
116848 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
116849 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
116850 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
116851 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
116852 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
116853 +
116854 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
116855 + sizeof(ioc_compat_fm_port_pcd_params_t) +
116856 + sizeof(ioc_fm_port_pcd_prs_params_t) +
116857 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
116858 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
116859 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
116860 + if (!compat_port_pcd_params)
116861 + {
116862 + XX_Free(port_pcd_params);
116863 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116864 + }
116865 +
116866 + memset(compat_port_pcd_params, 0,
116867 + sizeof(ioc_compat_fm_port_pcd_params_t) +
116868 + sizeof(ioc_fm_port_pcd_prs_params_t) +
116869 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
116870 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
116871 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
116872 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
116873 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
116874 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
116875 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
116876 +
116877 + if (copy_from_user(compat_port_pcd_params,
116878 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
116879 + sizeof(ioc_compat_fm_port_pcd_params_t)))
116880 + err = E_WRITE_FAILED;
116881 +
116882 + while (!err) /* pseudo-while */
116883 + {
116884 + /* set pointers from where to copy from: */
116885 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
116886 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
116887 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
116888 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
116889 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
116890 +#if (DPAA_VERSION >= 11)
116891 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
116892 +#endif
116893 + /* the prs member is the same, no compat structure...memcpy only */
116894 + if (port_pcd_params->p_prs_params)
116895 + {
116896 + if (copy_from_user(same_port_pcd_prs_params,
116897 + port_pcd_params->p_prs_params,
116898 + sizeof(ioc_fm_port_pcd_prs_params_t)))
116899 + {
116900 + err = E_WRITE_FAILED;
116901 + break; /* from pseudo-while */
116902 + }
116903 +
116904 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
116905 + port_pcd_params->p_prs_params = port_pcd_prs_params;
116906 + }
116907 +
116908 + if (port_pcd_params->p_cc_params)
116909 + {
116910 + if (copy_from_user(compat_port_pcd_cc_params,
116911 + port_pcd_params->p_cc_params,
116912 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
116913 + {
116914 + err = E_WRITE_FAILED;
116915 + break; /* from pseudo-while */
116916 + }
116917 +
116918 + port_pcd_params->p_cc_params = port_pcd_cc_params;
116919 + }
116920 +
116921 + if (port_pcd_params->p_kg_params)
116922 + {
116923 + if (copy_from_user(compat_port_pcd_kg_params,
116924 + port_pcd_params->p_kg_params,
116925 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
116926 + {
116927 + err = E_WRITE_FAILED;
116928 + break; /* from pseudo-while */
116929 + }
116930 +
116931 + port_pcd_params->p_kg_params = port_pcd_kg_params;
116932 + }
116933 +
116934 + if (port_pcd_params->p_plcr_params)
116935 + {
116936 + if (copy_from_user(compat_port_pcd_plcr_params,
116937 + port_pcd_params->p_plcr_params,
116938 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
116939 + {
116940 + err = E_WRITE_FAILED;
116941 + break; /* from pseudo-while */
116942 + }
116943 +
116944 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
116945 + }
116946 +
116947 + break; /* pseudo-while: always run once! */
116948 + }
116949 +
116950 + if (!err)
116951 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
116952 +
116953 + XX_Free(compat_port_pcd_params);
116954 + }
116955 + else
116956 +#endif
116957 + {
116958 + if (copy_from_user(port_pcd_params,
116959 + (ioc_fm_port_pcd_params_t*) arg,
116960 + sizeof(ioc_fm_port_pcd_params_t)))
116961 + err = E_WRITE_FAILED;
116962 +
116963 + while (!err) /* pseudo-while */
116964 + {
116965 + if (port_pcd_params->p_prs_params)
116966 + {
116967 + if (copy_from_user(port_pcd_prs_params,
116968 + port_pcd_params->p_prs_params,
116969 + sizeof(ioc_fm_port_pcd_prs_params_t)))
116970 + {
116971 + err = E_WRITE_FAILED;
116972 + break; /* from pseudo-while */
116973 + }
116974 +
116975 + port_pcd_params->p_prs_params = port_pcd_prs_params;
116976 + }
116977 +
116978 + if (port_pcd_params->p_cc_params)
116979 + {
116980 + if (copy_from_user(port_pcd_cc_params,
116981 + port_pcd_params->p_cc_params,
116982 + sizeof(ioc_fm_port_pcd_cc_params_t)))
116983 + {
116984 + err = E_WRITE_FAILED;
116985 + break; /* from pseudo-while */
116986 + }
116987 +
116988 + port_pcd_params->p_cc_params = port_pcd_cc_params;
116989 + }
116990 +
116991 + if (port_pcd_params->p_kg_params)
116992 + {
116993 + if (copy_from_user(port_pcd_kg_params,
116994 + port_pcd_params->p_kg_params,
116995 + sizeof(ioc_fm_port_pcd_kg_params_t)))
116996 + {
116997 + err = E_WRITE_FAILED;
116998 + break; /* from pseudo-while */
116999 + }
117000 +
117001 + port_pcd_params->p_kg_params = port_pcd_kg_params;
117002 + }
117003 +
117004 + if (port_pcd_params->p_plcr_params)
117005 + {
117006 + if (copy_from_user(port_pcd_plcr_params,
117007 + port_pcd_params->p_plcr_params,
117008 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
117009 + {
117010 + err = E_WRITE_FAILED;
117011 + break; /* from pseudo-while */
117012 + }
117013 +
117014 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
117015 + }
117016 +
117017 + break; /* pseudo-while: always run once! */
117018 + }
117019 + }
117020 +
117021 + if (!err)
117022 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
117023 +
117024 + XX_Free(port_pcd_params);
117025 + break;
117026 + }
117027 +
117028 + case FM_PORT_IOC_DELETE_PCD:
117029 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
117030 + break;
117031 +
117032 +#if defined(CONFIG_COMPAT)
117033 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
117034 +#endif
117035 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
117036 + {
117037 + ioc_fm_pcd_kg_scheme_select_t *param;
117038 +
117039 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
117040 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
117041 + if (!param)
117042 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117043 +
117044 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
117045 +
117046 +#if defined(CONFIG_COMPAT)
117047 + if (compat)
117048 + {
117049 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
117050 +
117051 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
117052 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
117053 + if (!compat_param)
117054 + {
117055 + XX_Free(param);
117056 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117057 + }
117058 +
117059 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
117060 + if (copy_from_user(compat_param,
117061 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
117062 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
117063 + {
117064 + XX_Free(compat_param);
117065 + XX_Free(param);
117066 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117067 + }
117068 +
117069 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
117070 +
117071 + XX_Free(compat_param);
117072 + }
117073 + else
117074 +#endif
117075 + {
117076 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
117077 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
117078 + {
117079 + XX_Free(param);
117080 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117081 + }
117082 + }
117083 +
117084 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
117085 +
117086 + XX_Free(param);
117087 + break;
117088 + }
117089 +
117090 +#if defined(CONFIG_COMPAT)
117091 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
117092 +#endif
117093 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
117094 + {
117095 + ioc_fm_obj_t id;
117096 +
117097 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
117098 +
117099 +#if defined(CONFIG_COMPAT)
117100 + if (compat)
117101 + {
117102 + ioc_compat_fm_obj_t compat_id;
117103 +
117104 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
117105 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117106 +
117107 + id.obj = compat_ptr(compat_id.obj);
117108 + }
117109 + else
117110 +#endif
117111 + {
117112 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
117113 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117114 + }
117115 +
117116 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
117117 + break;
117118 + }
117119 +
117120 +#if defined(CONFIG_COMPAT)
117121 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
117122 +#endif
117123 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
117124 + {
117125 + ioc_fm_pcd_port_schemes_params_t *param;
117126 +
117127 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
117128 + sizeof(ioc_fm_pcd_port_schemes_params_t));
117129 + if (!param)
117130 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117131 +
117132 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
117133 +
117134 +#if defined(CONFIG_COMPAT)
117135 + if (compat)
117136 + {
117137 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
117138 +
117139 + if (copy_from_user(&compat_param,
117140 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
117141 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
117142 + {
117143 + XX_Free(param);
117144 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117145 + }
117146 +
117147 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
117148 + }
117149 + else
117150 +#endif
117151 + {
117152 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
117153 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
117154 + {
117155 + XX_Free(param);
117156 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117157 + }
117158 + }
117159 +
117160 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
117161 +
117162 + XX_Free(param);
117163 + break;
117164 + }
117165 +
117166 +#if defined(CONFIG_COMPAT)
117167 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
117168 +#endif
117169 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
117170 + {
117171 + ioc_fm_pcd_port_schemes_params_t *param;
117172 +
117173 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
117174 + sizeof(ioc_fm_pcd_port_schemes_params_t));
117175 + if (!param)
117176 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117177 +
117178 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
117179 +
117180 +#if defined(CONFIG_COMPAT)
117181 + if (compat)
117182 + {
117183 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
117184 +
117185 + if (copy_from_user(&compat_param,
117186 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
117187 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
117188 + {
117189 + XX_Free(param);
117190 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117191 + }
117192 +
117193 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
117194 + }
117195 + else
117196 +#endif
117197 + {
117198 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
117199 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
117200 + {
117201 + XX_Free(param);
117202 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117203 + }
117204 + }
117205 +
117206 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
117207 +
117208 + XX_Free(param);
117209 + break;
117210 + }
117211 +
117212 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
117213 + {
117214 + uint16_t num;
117215 + if (get_user(num, (uint16_t*) arg))
117216 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117217 +
117218 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
117219 + break;
117220 + }
117221 +
117222 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
117223 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
117224 + break;
117225 +
117226 + case FM_PORT_IOC_DETACH_PCD:
117227 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
117228 + break;
117229 +
117230 + case FM_PORT_IOC_ATTACH_PCD:
117231 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
117232 + break;
117233 +
117234 +#if defined(CONFIG_COMPAT)
117235 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
117236 +#endif
117237 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
117238 + {
117239 + ioc_fm_obj_t id;
117240 +
117241 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
117242 +
117243 +#if defined(CONFIG_COMPAT)
117244 + if (compat)
117245 + {
117246 + ioc_compat_fm_obj_t compat_id;
117247 +
117248 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
117249 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117250 +
117251 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
117252 + }
117253 + else
117254 +#endif
117255 + {
117256 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
117257 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117258 + }
117259 +
117260 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
117261 + break;
117262 + }
117263 +
117264 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
117265 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
117266 + {
117267 + ioc_fm_port_congestion_groups_t *param;
117268 +
117269 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
117270 + if (!param)
117271 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117272 +
117273 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
117274 +
117275 +#if defined(CONFIG_COMPAT)
117276 + if (compat)
117277 + {
117278 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
117279 + sizeof(t_FmPortCongestionGrps)))
117280 + {
117281 + XX_Free(param);
117282 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117283 + }
117284 + }
117285 + else
117286 +#endif /* CONFIG_COMPAT */
117287 + {
117288 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
117289 + sizeof(t_FmPortCongestionGrps)))
117290 + {
117291 + XX_Free(param);
117292 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117293 + }
117294 + }
117295 +
117296 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
117297 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
117298 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
117299 + ;
117300 +
117301 + XX_Free(param);
117302 + break;
117303 + }
117304 +
117305 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
117306 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
117307 + {
117308 + ioc_fm_port_mac_addr_params_t *param;
117309 +
117310 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
117311 + sizeof(ioc_fm_port_mac_addr_params_t));
117312 + if (!param)
117313 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117314 +
117315 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
117316 +
117317 +#if defined(CONFIG_COMPAT)
117318 + if (compat)
117319 + {
117320 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
117321 + sizeof(ioc_fm_port_mac_addr_params_t)))
117322 + {
117323 + XX_Free(param);
117324 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117325 + }
117326 + }
117327 + else
117328 +#endif /* CONFIG_COMPAT */
117329 + {
117330 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
117331 + sizeof(ioc_fm_port_mac_addr_params_t)))
117332 + {
117333 + XX_Free(param);
117334 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117335 + }
117336 + }
117337 +
117338 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
117339 + {
117340 + int id = -1;
117341 +
117342 + switch(p_LnxWrpFmPortDev->settings.param.portType)
117343 + {
117344 + case e_FM_PORT_TYPE_RX:
117345 + case e_FM_PORT_TYPE_TX:
117346 + id = p_LnxWrpFmPortDev->id;
117347 + break;
117348 + case e_FM_PORT_TYPE_RX_10G:
117349 + case e_FM_PORT_TYPE_TX_10G:
117350 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
117351 + break;
117352 + default:
117353 + err = E_NOT_AVAILABLE;
117354 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
117355 + }
117356 + if (id >= 0)
117357 + {
117358 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117359 + t_Handle mac_handle = fm->macs[id].h_Dev;
117360 +
117361 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
117362 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
117363 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
117364 + }
117365 + }
117366 + else
117367 + {
117368 + err = E_NOT_AVAILABLE;
117369 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
117370 + }
117371 +
117372 + XX_Free(param);
117373 + break;
117374 + }
117375 +
117376 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
117377 + {
117378 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117379 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117380 + ioc_fm_port_tx_pause_frames_params_t param;
117381 + int mac_id = p_LnxWrpFmPortDev->id;
117382 +
117383 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
117384 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
117385 +
117386 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
117387 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
117388 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117389 +
117390 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
117391 + {
117392 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
117393 + param.priority,
117394 + param.pause_time,
117395 + param.thresh_time);
117396 + }
117397 + else
117398 + {
117399 + err = E_NOT_AVAILABLE;
117400 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
117401 + }
117402 +
117403 + break;
117404 + }
117405 +
117406 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
117407 + {
117408 + ioc_fm_buffer_prefix_content_t *param;
117409 +
117410 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
117411 + if (!param)
117412 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117413 +
117414 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
117415 +
117416 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
117417 + sizeof(ioc_fm_buffer_prefix_content_t)))
117418 + {
117419 + XX_Free(param);
117420 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117421 + }
117422 +
117423 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
117424 + (t_FmBufferPrefixContent *)param))
117425 + {
117426 + XX_Free(param);
117427 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117428 + }
117429 +
117430 + XX_Free(param);
117431 + break;
117432 + }
117433 +
117434 +#if (DPAA_VERSION >= 11)
117435 +#if defined(CONFIG_COMPAT)
117436 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
117437 +#endif
117438 + case FM_PORT_IOC_VSP_ALLOC:
117439 + {
117440 + ioc_fm_port_vsp_alloc_params_t *param;
117441 + t_LnxWrpFmDev *p_LnxWrpFmDev;
117442 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
117443 +
117444 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
117445 + sizeof(ioc_fm_port_vsp_alloc_params_t));
117446 + if (!param)
117447 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117448 +
117449 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
117450 +
117451 +#if defined(CONFIG_COMPAT)
117452 + if (compat)
117453 + {
117454 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
117455 +
117456 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
117457 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
117458 + if (!compat_param)
117459 + {
117460 + XX_Free(param);
117461 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117462 + }
117463 +
117464 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
117465 + if (copy_from_user(compat_param,
117466 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
117467 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
117468 + {
117469 + XX_Free(compat_param);
117470 + XX_Free(param);
117471 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117472 + }
117473 +
117474 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
117475 +
117476 + XX_Free(compat_param);
117477 + }
117478 + else
117479 +#endif
117480 + {
117481 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
117482 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
117483 + {
117484 + XX_Free(param);
117485 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117486 + }
117487 + }
117488 +
117489 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
117490 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
117491 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
117492 + {
117493 + /* Determine the Tx port t_Handle from the Rx port id */
117494 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117495 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
117496 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
117497 + }
117498 +
117499 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
117500 + {
117501 + XX_Free(param);
117502 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117503 + }
117504 +
117505 + XX_Free(param);
117506 + break;
117507 + }
117508 +#endif /* (DPAA_VERSION >= 11) */
117509 +
117510 + case FM_PORT_IOC_GET_MAC_STATISTICS:
117511 + {
117512 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117513 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117514 + ioc_fm_port_mac_statistics_t param;
117515 + int mac_id = p_LnxWrpFmPortDev->id;
117516 +
117517 + if (!p_LnxWrpFmDev)
117518 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117519 +
117520 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
117521 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
117522 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
117523 +
117524 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
117525 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117526 +
117527 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
117528 + (t_FmMacStatistics *)&param))
117529 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117530 +
117531 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
117532 + sizeof(ioc_fm_port_mac_statistics_t)))
117533 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117534 +
117535 + break;
117536 + }
117537 +
117538 + case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
117539 + {
117540 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117541 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117542 + ioc_fm_port_mac_frame_size_counters_t param;
117543 + t_FmMacFrameSizeCounters frameSizeCounters;
117544 + int mac_id = p_LnxWrpFmPortDev->id;
117545 +
117546 + if (!p_LnxWrpFmDev)
117547 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117548 +
117549 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
117550 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
117551 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
117552 +
117553 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
117554 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117555 +
117556 + if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
117557 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
117558 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117559 +
117560 + if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
117561 + &frameSizeCounters, param.type))
117562 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117563 +
117564 + param.count_pkts_64 = frameSizeCounters.count_pkts_64;
117565 + param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
117566 + param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
117567 + param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
117568 + param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
117569 + param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
117570 + param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
117571 +
117572 + if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
117573 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
117574 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117575 +
117576 + break;
117577 + }
117578 +
117579 + case FM_PORT_IOC_GET_BMI_COUNTERS:
117580 + {
117581 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117582 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117583 + ioc_fm_port_bmi_stats_t param;
117584 +
117585 + if (!p_LnxWrpFmDev)
117586 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117587 +
117588 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
117589 + (t_FmPortBmiStats *)&param))
117590 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117591 +
117592 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
117593 + sizeof(ioc_fm_port_bmi_stats_t)))
117594 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117595 +
117596 + break;
117597 + }
117598 +
117599 + default:
117600 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
117601 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
117602 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
117603 + }
117604 +
117605 + if (err)
117606 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
117607 +
117608 + return E_OK;
117609 +}
117610 +
117611 +/*****************************************************************************/
117612 +/* API routines for the FM Linux Device */
117613 +/*****************************************************************************/
117614 +
117615 +static int fm_open(struct inode *inode, struct file *file)
117616 +{
117617 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
117618 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
117619 + unsigned int major = imajor(inode);
117620 + unsigned int minor = iminor(inode);
117621 + struct device_node *fm_node;
117622 + static struct of_device_id fm_node_of_match[] = {
117623 + { .compatible = "fsl,fman", },
117624 + { /* end of list */ },
117625 + };
117626 +
117627 + DBG(TRACE, ("Opening minor - %d - ", minor));
117628 +
117629 + if (file->private_data != NULL)
117630 + return 0;
117631 +
117632 + /* Get all the FM nodes */
117633 + for_each_matching_node(fm_node, fm_node_of_match) {
117634 + struct platform_device *of_dev;
117635 +
117636 + of_dev = of_find_device_by_node(fm_node);
117637 + if (unlikely(of_dev == NULL)) {
117638 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
117639 + return -ENXIO;
117640 + }
117641 +
117642 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
117643 + if (p_LnxWrpFmDev->major == major)
117644 + break;
117645 + fm_unbind((struct fm *)p_LnxWrpFmDev);
117646 + p_LnxWrpFmDev = NULL;
117647 + }
117648 +
117649 + if (!p_LnxWrpFmDev)
117650 + return -ENODEV;
117651 +
117652 + if (minor == DEV_FM_MINOR_BASE)
117653 + file->private_data = p_LnxWrpFmDev;
117654 + else if (minor == DEV_FM_PCD_MINOR_BASE)
117655 + file->private_data = p_LnxWrpFmDev;
117656 + else {
117657 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
117658 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
117659 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
117660 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
117661 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
117662 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
117663 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
117664 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
117665 + else
117666 + return -EINVAL;
117667 +
117668 + /* if trying to open port, check if it initialized */
117669 + if (!p_LnxWrpFmPortDev->h_Dev)
117670 + return -ENODEV;
117671 +
117672 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
117673 + file->private_data = p_LnxWrpFmPortDev;
117674 + fm_unbind((struct fm *)p_LnxWrpFmDev);
117675 + }
117676 +
117677 + if (file->private_data == NULL)
117678 + return -ENXIO;
117679 +
117680 + return 0;
117681 +}
117682 +
117683 +static int fm_close(struct inode *inode, struct file *file)
117684 +{
117685 + t_LnxWrpFmDev *p_LnxWrpFmDev;
117686 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
117687 + unsigned int minor = iminor(inode);
117688 + int err = 0;
117689 +
117690 + DBG(TRACE, ("Closing minor - %d - ", minor));
117691 +
117692 + if ((minor == DEV_FM_MINOR_BASE) ||
117693 + (minor == DEV_FM_PCD_MINOR_BASE))
117694 + {
117695 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
117696 + if (!p_LnxWrpFmDev)
117697 + return -ENODEV;
117698 + fm_unbind((struct fm *)p_LnxWrpFmDev);
117699 + }
117700 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
117701 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
117702 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
117703 + {
117704 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
117705 + if (!p_LnxWrpFmPortDev)
117706 + return -ENODEV;
117707 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
117708 + }
117709 +
117710 + return err;
117711 +}
117712 +
117713 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
117714 +{
117715 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
117716 +
117717 + if ((minor == DEV_FM_MINOR_BASE) ||
117718 + (minor == DEV_FM_PCD_MINOR_BASE))
117719 + {
117720 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
117721 + if (!p_LnxWrpFmDev)
117722 + return -ENODEV;
117723 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
117724 + return -EFAULT;
117725 + }
117726 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
117727 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
117728 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
117729 + {
117730 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
117731 + if (!p_LnxWrpFmPortDev)
117732 + return -ENODEV;
117733 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
117734 + return -EFAULT;
117735 + }
117736 + else
117737 + {
117738 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
117739 + return -ENODEV;
117740 + }
117741 +
117742 + return 0;
117743 +}
117744 +
117745 +#ifdef CONFIG_COMPAT
117746 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
117747 +{
117748 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
117749 + long res;
117750 +
117751 + fm_mutex_lock();
117752 + res = fm_ioctls(minor, file, cmd, arg, true);
117753 + fm_mutex_unlock();
117754 +
117755 + return res;
117756 +}
117757 +#endif
117758 +
117759 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
117760 +{
117761 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
117762 + long res;
117763 +
117764 + fm_mutex_lock();
117765 + res = fm_ioctls(minor, file, cmd, arg, false);
117766 + fm_mutex_unlock();
117767 +
117768 + return res;
117769 +}
117770 +
117771 +/* Globals for FM character device */
117772 +struct file_operations fm_fops =
117773 +{
117774 + .owner = THIS_MODULE,
117775 + .unlocked_ioctl = fm_ioctl,
117776 +#ifdef CONFIG_COMPAT
117777 + .compat_ioctl = fm_compat_ioctl,
117778 +#endif
117779 + .open = fm_open,
117780 + .release = fm_close,
117781 +};
117782 --- /dev/null
117783 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
117784 @@ -0,0 +1,1297 @@
117785 +/*
117786 + * Copyright 2008-2012 Freescale Semiconductor Inc.
117787 + *
117788 + * Redistribution and use in source and binary forms, with or without
117789 + * modification, are permitted provided that the following conditions are met:
117790 + * * Redistributions of source code must retain the above copyright
117791 + * notice, this list of conditions and the following disclaimer.
117792 + * * Redistributions in binary form must reproduce the above copyright
117793 + * notice, this list of conditions and the following disclaimer in the
117794 + * documentation and/or other materials provided with the distribution.
117795 + * * Neither the name of Freescale Semiconductor nor the
117796 + * names of its contributors may be used to endorse or promote products
117797 + * derived from this software without specific prior written permission.
117798 + *
117799 + *
117800 + * ALTERNATIVELY, this software may be distributed under the terms of the
117801 + * GNU General Public License ("GPL") as published by the Free Software
117802 + * Foundation, either version 2 of that License or (at your option) any
117803 + * later version.
117804 + *
117805 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
117806 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
117807 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117808 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
117809 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
117810 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
117811 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
117812 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
117813 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117814 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117815 + */
117816 +
117817 +/*
117818 + @File lnxwrp_fm_compat_ioctls.c
117819 +
117820 + @Description FM PCD compat functions
117821 +
117822 +*/
117823 +
117824 +#if !defined(CONFIG_COMPAT)
117825 +#error "missing COMPAT layer..."
117826 +#endif
117827 +
117828 +
117829 +#include <linux/kernel.h>
117830 +#include <linux/module.h>
117831 +#include <linux/fs.h>
117832 +#include <linux/cdev.h>
117833 +#include <linux/device.h>
117834 +#include <linux/irq.h>
117835 +#include <linux/interrupt.h>
117836 +#include <linux/io.h>
117837 +#include <linux/ioport.h>
117838 +#include <asm/uaccess.h>
117839 +#include <asm/errno.h>
117840 +#ifndef CONFIG_FMAN_ARM
117841 +#include <sysdev/fsl_soc.h>
117842 +#endif
117843 +
117844 +#include "part_ext.h"
117845 +#include "fm_ioctls.h"
117846 +#include "fm_pcd_ioctls.h"
117847 +#include "fm_port_ioctls.h"
117848 +#include "lnxwrp_ioctls_fm_compat.h"
117849 +
117850 +#if defined(FM_COMPAT_DBG)
117851 +static void hex_dump(void * p_addr, unsigned int size)
117852 +{
117853 + int i;
117854 +
117855 + for(i=0; i<size; i+=16)
117856 + {
117857 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
117858 + *(unsigned int *)(p_addr + i),
117859 + *(unsigned int *)(p_addr + i + 4),
117860 + *(unsigned int *)(p_addr + i + 8),
117861 + *(unsigned int *)(p_addr + i +12)
117862 + );
117863 + }
117864 +}
117865 +#endif
117866 +
117867 +/* maping kernel pointers w/ UserSpace id's { */
117868 +struct map_node {
117869 + void *ptr;
117870 + u8 node_type;
117871 +};
117872 +
117873 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
117874 +
117875 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
117876 +{
117877 + compat_uptr_t k;
117878 +
117879 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
117880 +
117881 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
117882 + if(compat_ptr2id_array[k].ptr == p){
117883 + compat_ptr2id_array[k].ptr = NULL;
117884 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
117885 + }
117886 +}
117887 +EXPORT_SYMBOL(compat_del_ptr2id);
117888 +
117889 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
117890 +{
117891 + compat_uptr_t k;
117892 +
117893 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
117894 +
117895 + if(!p)
117896 + return 0;
117897 +
117898 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
117899 + if(compat_ptr2id_array[k].ptr == NULL)
117900 + {
117901 + compat_ptr2id_array[k].ptr = p;
117902 + compat_ptr2id_array[k].node_type = node_type;
117903 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
117904 + return k | COMPAT_PTR2ID_WATERMARK;
117905 + }
117906 +
117907 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
117908 + return 0;
117909 +}
117910 +EXPORT_SYMBOL(compat_add_ptr2id);
117911 +
117912 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
117913 +{
117914 + compat_uptr_t k;
117915 +
117916 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
117917 +
117918 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
117919 + if(compat_ptr2id_array[k].ptr == p &&
117920 + compat_ptr2id_array[k].node_type == node_type) {
117921 +
117922 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
117923 + return k | COMPAT_PTR2ID_WATERMARK;
117924 + }
117925 +
117926 + return 0;
117927 +}
117928 +EXPORT_SYMBOL(compat_get_ptr2id);
117929 +
117930 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
117931 +{
117932 +
117933 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
117934 +
117935 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
117936 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
117937 + dump_stack();
117938 + return compat_ptr(comp);
117939 + }
117940 +
117941 + comp &= ~COMPAT_PTR2ID_WM_MASK;
117942 +
117943 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
117944 + && compat_ptr2id_array[comp].node_type == node_type)) {
117945 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
117946 + return compat_ptr2id_array[comp].ptr;
117947 + }
117948 + return NULL;
117949 +}
117950 +EXPORT_SYMBOL(compat_get_id2ptr);
117951 +/* } maping kernel pointers w/ UserSpace id's */
117952 +
117953 +void compat_obj_delete(
117954 + ioc_compat_fm_obj_t *compat_id,
117955 + ioc_fm_obj_t *id)
117956 +{
117957 + id->obj = compat_pcd_id2ptr(compat_id->obj);
117958 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
117959 +}
117960 +
117961 +static inline void compat_copy_fm_pcd_plcr_next_engine(
117962 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
117963 + ioc_fm_pcd_plcr_next_engine_params_u *param,
117964 + ioc_fm_pcd_engine next_engine,
117965 + uint8_t compat)
117966 +{
117967 + _fm_cpt_dbg (compat, " {->...\n");
117968 +
117969 + switch (next_engine)
117970 + {
117971 + case e_IOC_FM_PCD_PLCR:
117972 + if (compat == COMPAT_US_TO_K)
117973 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
117974 + else
117975 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
117976 + break;
117977 + case e_IOC_FM_PCD_KG:
117978 + if (compat == COMPAT_US_TO_K)
117979 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
117980 + else
117981 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
117982 + break;
117983 + default:
117984 + if (compat == COMPAT_US_TO_K)
117985 + param->action = compat_param->action;
117986 + else
117987 + compat_param->action = param->action;
117988 + break;
117989 + }
117990 +
117991 + _fm_cpt_dbg (compat, " ...->}\n");
117992 +}
117993 +
117994 +void compat_copy_fm_pcd_plcr_profile(
117995 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
117996 + ioc_fm_pcd_plcr_profile_params_t *param,
117997 + uint8_t compat)
117998 +{
117999 + _fm_cpt_dbg (compat, " {->...\n");
118000 +
118001 + if (compat == COMPAT_US_TO_K)
118002 + {
118003 + param->modify = compat_param->modify;
118004 +
118005 + /* profile_select */
118006 + if (!compat_param->modify)
118007 + {
118008 + param->profile_select.new_params.profile_type =
118009 + compat_param->profile_select.new_params.profile_type;
118010 + param->profile_select.new_params.p_fm_port =
118011 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
118012 + param->profile_select.new_params.relative_profile_id =
118013 + compat_param->profile_select.new_params.relative_profile_id;
118014 + }
118015 + else
118016 + param->profile_select.p_profile =
118017 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
118018 +
118019 + param->alg_selection = compat_param->alg_selection;
118020 + param->color_mode = compat_param->color_mode;
118021 +
118022 + /* both parameters in the union has the same size, so memcpy works */
118023 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
118024 +
118025 + memcpy(&param->non_passthrough_alg_param,
118026 + &compat_param->non_passthrough_alg_param,
118027 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
118028 +
118029 + param->next_engine_on_green = compat_param->next_engine_on_green;
118030 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
118031 + param->next_engine_on_red = compat_param->next_engine_on_red;
118032 +
118033 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
118034 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
118035 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
118036 + }
118037 + else
118038 + {
118039 + compat_param->modify = param->modify;
118040 +
118041 + /* profile_select */
118042 + if (!param->modify)
118043 + {
118044 + compat_param->profile_select.new_params.profile_type =
118045 + param->profile_select.new_params.profile_type;
118046 + compat_param->profile_select.new_params.p_fm_port =
118047 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
118048 + compat_param->profile_select.new_params.relative_profile_id =
118049 + param->profile_select.new_params.relative_profile_id;
118050 + }
118051 + else
118052 + compat_param->profile_select.p_profile =
118053 + compat_pcd_ptr2id(param->profile_select.p_profile);
118054 +
118055 + compat_param->alg_selection = param->alg_selection;
118056 + compat_param->color_mode = param->color_mode;
118057 +
118058 + /* both parameters in the union has the same size, so memcpy works */
118059 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
118060 +
118061 + memcpy(&compat_param->non_passthrough_alg_param,
118062 + &param->non_passthrough_alg_param,
118063 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
118064 +
118065 + compat_param->next_engine_on_green = param->next_engine_on_green;
118066 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
118067 + compat_param->next_engine_on_red = param->next_engine_on_red;
118068 +
118069 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
118070 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
118071 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
118072 +
118073 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118074 + }
118075 +
118076 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
118077 + &param->params_on_green, param->next_engine_on_green, compat);
118078 +
118079 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
118080 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
118081 +
118082 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
118083 + &param->params_on_red, param->next_engine_on_red, compat);
118084 +
118085 + _fm_cpt_dbg (compat, " ...->}\n");
118086 +}
118087 +
118088 +static inline void compat_copy_fm_pcd_cc_next_kg(
118089 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
118090 + ioc_fm_pcd_cc_next_kg_params_t *param,
118091 + uint8_t compat)
118092 +{
118093 + _fm_cpt_dbg (compat, " {->...\n");
118094 +
118095 + if (compat == COMPAT_US_TO_K)
118096 + {
118097 + param->new_fqid = compat_param->new_fqid;
118098 + param->override_fqid = compat_param->override_fqid;
118099 +#if DPAA_VERSION >= 11
118100 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
118101 +#endif
118102 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
118103 + }
118104 + else
118105 + {
118106 + compat_param->new_fqid = param->new_fqid;
118107 + compat_param->override_fqid = param->override_fqid;
118108 +#if DPAA_VERSION >= 11
118109 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
118110 +#endif
118111 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
118112 + }
118113 +
118114 + _fm_cpt_dbg (compat, " ...->}\n");
118115 +}
118116 +
118117 +static inline void compat_copy_fm_pcd_cc_next_cc(
118118 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
118119 + ioc_fm_pcd_cc_next_cc_params_t *param,
118120 + uint8_t compat)
118121 +{
118122 + _fm_cpt_dbg (compat, " {->...\n");
118123 +
118124 + if (compat == COMPAT_US_TO_K)
118125 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
118126 + else
118127 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
118128 +
118129 + _fm_cpt_dbg (compat, " ...->}\n");
118130 +}
118131 +
118132 +static inline void compat_copy_fm_pcd_cc_next_engine(
118133 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
118134 + ioc_fm_pcd_cc_next_engine_params_t *param,
118135 + uint8_t compat)
118136 +{
118137 + _fm_cpt_dbg (compat, " {->...\n");
118138 +
118139 + if (compat == COMPAT_US_TO_K)
118140 + {
118141 + param->next_engine = compat_param->next_engine;
118142 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
118143 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
118144 +
118145 + switch (param->next_engine)
118146 + {
118147 +#if DPAA_VERSION >= 11
118148 + case e_IOC_FM_PCD_FR:
118149 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
118150 + break;
118151 +#endif /* DPAA_VERSION >= 11 */
118152 + case e_IOC_FM_PCD_CC:
118153 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
118154 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
118155 + break;
118156 + case e_IOC_FM_PCD_KG:
118157 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
118158 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
118159 + break;
118160 + case e_IOC_FM_PCD_DONE:
118161 + case e_IOC_FM_PCD_PLCR:
118162 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
118163 + default:
118164 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
118165 + }
118166 + param->statistics_en = compat_param->statistics_en;
118167 + }
118168 + else
118169 + {
118170 + compat_param->next_engine = param->next_engine;
118171 +
118172 + switch (compat_param->next_engine)
118173 + {
118174 +#if DPAA_VERSION >= 11
118175 + case e_IOC_FM_PCD_FR:
118176 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
118177 + break;
118178 +#endif /* DPAA_VERSION >= 11 */
118179 + case e_IOC_FM_PCD_CC:
118180 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
118181 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
118182 + break;
118183 + case e_IOC_FM_PCD_KG:
118184 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
118185 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
118186 + break;
118187 + case e_IOC_FM_PCD_DONE:
118188 + case e_IOC_FM_PCD_PLCR:
118189 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
118190 + default:
118191 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
118192 + }
118193 + compat_param->statistics_en = param->statistics_en;
118194 + }
118195 +
118196 + _fm_cpt_dbg (compat, " ...->}\n");
118197 +}
118198 +
118199 +void compat_copy_fm_pcd_cc_key(
118200 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118201 + ioc_fm_pcd_cc_key_params_t *param,
118202 + uint8_t compat)
118203 +{
118204 + if (compat == COMPAT_US_TO_K)
118205 + {
118206 + param->p_key = compat_ptr(compat_param->p_key);
118207 + param->p_mask = compat_ptr(compat_param->p_mask);
118208 + }
118209 + else
118210 + {
118211 + compat_param->p_key = ptr_to_compat(param->p_key);
118212 + compat_param->p_mask = ptr_to_compat(param->p_mask);
118213 + }
118214 +
118215 + compat_copy_fm_pcd_cc_next_engine(
118216 + &compat_param->cc_next_engine_params,
118217 + &param->cc_next_engine_params,
118218 + compat);
118219 +}
118220 +
118221 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118222 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118223 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118224 + uint8_t compat)
118225 +{
118226 + if (compat == COMPAT_US_TO_K)
118227 + {
118228 + param->id = compat_pcd_id2ptr(compat_param->id);
118229 + param->key_indx = compat_param->key_indx;
118230 + param->key_size = compat_param->key_size;
118231 + compat_copy_fm_pcd_cc_key(
118232 + &compat_param->key_params,
118233 + &param->key_params,
118234 + compat);
118235 + }
118236 + else
118237 + {
118238 + compat_param->id = compat_pcd_ptr2id(param->id);
118239 + compat_param->key_indx = param->key_indx;
118240 + compat_param->key_size = param->key_size;
118241 + compat_copy_fm_pcd_cc_key(
118242 + &compat_param->key_params,
118243 + &param->key_params,
118244 + compat);
118245 + }
118246 +}
118247 +
118248 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118249 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118250 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118251 + uint8_t compat)
118252 +{
118253 + if (compat == COMPAT_US_TO_K)
118254 + {
118255 + param->id = compat_pcd_id2ptr(compat_param->id);
118256 + param->key_indx = compat_param->key_indx;
118257 + param->key_size = compat_param->key_size;
118258 + }
118259 + else
118260 + {
118261 + compat_param->id = compat_pcd_ptr2id(param->id);
118262 + compat_param->key_indx = param->key_indx;
118263 + compat_param->key_size = param->key_size;
118264 + }
118265 +
118266 + compat_copy_fm_pcd_cc_next_engine(
118267 + &compat_param->cc_next_engine_params,
118268 + &param->cc_next_engine_params,
118269 + compat);
118270 +}
118271 +
118272 +void compat_fm_pcd_cc_tree_modify_next_engine(
118273 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118274 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118275 + uint8_t compat)
118276 +{
118277 + if (compat == COMPAT_US_TO_K)
118278 + {
118279 + param->id = compat_pcd_id2ptr(compat_param->id);
118280 + param->grp_indx = compat_param->grp_indx;
118281 + param->indx = compat_param->indx;
118282 + }
118283 + else
118284 + {
118285 + compat_param->id = compat_pcd_ptr2id(param->id);
118286 + compat_param->grp_indx = param->grp_indx;
118287 + compat_param->indx = param->indx;
118288 + }
118289 +
118290 + compat_copy_fm_pcd_cc_next_engine(
118291 + &compat_param->cc_next_engine_params,
118292 + &param->cc_next_engine_params,
118293 + compat);
118294 +}
118295 +
118296 +void compat_copy_fm_pcd_hash_table(
118297 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118298 + ioc_fm_pcd_hash_table_params_t *param,
118299 + uint8_t compat)
118300 +{
118301 + if (compat == COMPAT_US_TO_K)
118302 + {
118303 + param->max_num_of_keys = compat_param->max_num_of_keys;
118304 + param->statistics_mode = compat_param->statistics_mode;
118305 + param->kg_hash_shift = compat_param->kg_hash_shift;
118306 + param->hash_res_mask = compat_param->hash_res_mask;
118307 + param->hash_shift = compat_param->hash_shift;
118308 + param->match_key_size = compat_param->match_key_size;
118309 + param->id = compat_pcd_id2ptr(compat_param->id);
118310 + }
118311 + else
118312 + {
118313 + compat_param->max_num_of_keys = param->max_num_of_keys;
118314 + compat_param->statistics_mode = param->statistics_mode;
118315 + compat_param->kg_hash_shift = param->kg_hash_shift;
118316 + compat_param->hash_res_mask = param->hash_res_mask;
118317 + compat_param->hash_shift = param->hash_shift;
118318 + compat_param->match_key_size = param->match_key_size;
118319 +
118320 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118321 + }
118322 +
118323 + compat_copy_fm_pcd_cc_next_engine(
118324 + &compat_param->cc_next_engine_params_for_miss,
118325 + &param->cc_next_engine_params_for_miss,
118326 + compat);
118327 +}
118328 +
118329 +void compat_copy_fm_pcd_cc_grp(
118330 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118331 + ioc_fm_pcd_cc_grp_params_t *param,
118332 + uint8_t compat)
118333 +{
118334 + int k;
118335 +
118336 + _fm_cpt_dbg (compat, " {->...\n");
118337 +
118338 + if (compat == COMPAT_US_TO_K)
118339 + {
118340 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
118341 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
118342 + }
118343 + else
118344 + {
118345 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
118346 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
118347 + }
118348 +
118349 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
118350 + compat_copy_fm_pcd_cc_next_engine(
118351 + &compat_param->next_engine_per_entries_in_grp[k],
118352 + &param->next_engine_per_entries_in_grp[k],
118353 + compat);
118354 +
118355 + _fm_cpt_dbg (compat, " ...->}\n");
118356 +}
118357 +
118358 +void compat_copy_fm_pcd_cc_tree(
118359 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118360 + ioc_fm_pcd_cc_tree_params_t *param,
118361 + uint8_t compat)
118362 +{
118363 + int k;
118364 + _fm_cpt_dbg (compat, " {->...\n");
118365 +
118366 + if (compat == COMPAT_US_TO_K)
118367 + {
118368 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
118369 + param->num_of_groups = compat_param->num_of_groups;
118370 + }
118371 + else
118372 + {
118373 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
118374 + compat_param->num_of_groups = param->num_of_groups;
118375 +
118376 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118377 + }
118378 +
118379 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
118380 + compat_copy_fm_pcd_cc_grp(
118381 + &compat_param->fm_pcd_cc_group_params[k],
118382 + &param->fm_pcd_cc_group_params[k],
118383 + compat);
118384 +
118385 + _fm_cpt_dbg (compat, " ...->}\n");
118386 +}
118387 +
118388 +void compat_fm_pcd_prs_sw(
118389 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118390 + ioc_fm_pcd_prs_sw_params_t *param,
118391 + uint8_t compat)
118392 +{
118393 + if (compat == COMPAT_US_TO_K)
118394 + {
118395 + param->override = compat_param->override;
118396 + param->size = compat_param->size;
118397 + param->base = compat_param->base;
118398 + param->p_code = compat_ptr(compat_param->p_code);
118399 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
118400 + param->num_of_labels = compat_param->num_of_labels;
118401 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
118402 + }
118403 +}
118404 +
118405 +void compat_copy_fm_pcd_kg_scheme(
118406 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118407 + ioc_fm_pcd_kg_scheme_params_t *param,
118408 + uint8_t compat)
118409 +{
118410 + _fm_cpt_dbg(compat," {->...\n");
118411 +
118412 + if (compat == COMPAT_US_TO_K)
118413 + {
118414 + param->modify = compat_param->modify;
118415 +
118416 + /* scm_id */
118417 + if (compat_param->modify)
118418 + {
118419 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
118420 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
118421 + }
118422 + else
118423 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
118424 +
118425 + param->always_direct = compat_param->always_direct;
118426 + /* net_env_params */
118427 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
118428 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
118429 + memcpy(param->net_env_params.unit_ids,
118430 + compat_param->net_env_params.unit_ids,
118431 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
118432 +
118433 + param->use_hash = compat_param->use_hash;
118434 + memcpy(&param->key_extract_and_hash_params,
118435 + &compat_param->key_extract_and_hash_params,
118436 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
118437 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
118438 + param->base_fqid = compat_param->base_fqid;
118439 +#if DPAA_VERSION >= 11
118440 + param->override_storage_profile =
118441 + compat_param->override_storage_profile;
118442 + param->storage_profile = compat_param->storage_profile;
118443 +#endif
118444 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
118445 + memcpy(param->extracted_ors,
118446 + compat_param->extracted_ors,
118447 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
118448 + param->next_engine = compat_param->next_engine;
118449 +
118450 + /* kg_next_engine_params */
118451 + if (param->next_engine == e_IOC_FM_PCD_CC)
118452 + {
118453 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
118454 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
118455 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
118456 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
118457 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
118458 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
118459 + &compat_param->kg_next_engine_params.cc.plcr_profile,
118460 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
118461 + }
118462 + else
118463 + memcpy(&param->kg_next_engine_params,
118464 + &compat_param->kg_next_engine_params,
118465 + sizeof(param->kg_next_engine_params));
118466 +
118467 + memcpy(&param->scheme_counter,
118468 + &compat_param->scheme_counter,
118469 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
118470 + }
118471 + else
118472 + {
118473 + compat_param->modify = param->modify;
118474 +
118475 + /* scm_id */
118476 + if (param->modify)
118477 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
118478 + else
118479 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
118480 +
118481 + compat_param->always_direct = param->always_direct;
118482 +
118483 + /* net_env_params */
118484 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
118485 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
118486 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
118487 +
118488 + compat_param->use_hash = param->use_hash;
118489 + 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));
118490 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
118491 + compat_param->base_fqid = param->base_fqid;
118492 +#if DPAA_VERSION >= 11
118493 + compat_param->override_storage_profile =
118494 + param->override_storage_profile;
118495 + compat_param->storage_profile = param->storage_profile;
118496 +#endif
118497 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
118498 + 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));
118499 + compat_param->next_engine = param->next_engine;
118500 +
118501 + /* kg_next_engine_params */
118502 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
118503 + {
118504 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
118505 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
118506 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
118507 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
118508 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
118509 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
118510 + &param->kg_next_engine_params.cc.plcr_profile,
118511 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
118512 + }
118513 + else
118514 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
118515 +
118516 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
118517 +
118518 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118519 + }
118520 +
118521 + _fm_cpt_dbg(compat," ...->}\n");
118522 +}
118523 +
118524 +void compat_copy_fm_pcd_kg_scheme_spc(
118525 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118526 + ioc_fm_pcd_kg_scheme_spc_t *param,
118527 + uint8_t compat)
118528 +{
118529 + if (compat == COMPAT_US_TO_K)
118530 + {
118531 + param->id = compat_pcd_id2ptr(compat_param->id);
118532 + param->val = compat_param->val;
118533 + } else {
118534 + compat_param->id = compat_pcd_ptr2id(param->id);
118535 + compat_param->val = param->val;
118536 + }
118537 +}
118538 +
118539 +
118540 +void compat_copy_fm_pcd_kg_scheme_select(
118541 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118542 + ioc_fm_pcd_kg_scheme_select_t *param,
118543 + uint8_t compat)
118544 +{
118545 + if (compat == COMPAT_US_TO_K)
118546 + {
118547 + param->direct = compat_param->direct;
118548 + if (param->direct)
118549 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
118550 + }
118551 +}
118552 +
118553 +void compat_copy_fm_pcd_kg_schemes_params(
118554 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118555 + ioc_fm_pcd_port_schemes_params_t *param,
118556 + uint8_t compat)
118557 +{
118558 + int k;
118559 +
118560 + if (compat == COMPAT_US_TO_K) {
118561 + param->num_of_schemes = compat_param->num_of_schemes;
118562 + for(k=0; k < compat_param->num_of_schemes; k++)
118563 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
118564 + }
118565 +}
118566 +
118567 +void compat_copy_fm_port_pcd_cc(
118568 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
118569 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
118570 + uint8_t compat)
118571 +{
118572 + if (compat == COMPAT_US_TO_K){
118573 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
118574 + }
118575 +}
118576 +
118577 +void compat_copy_fm_port_pcd_kg(
118578 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118579 + ioc_fm_port_pcd_kg_params_t *param,
118580 + uint8_t compat)
118581 +{
118582 + if (compat == COMPAT_US_TO_K){
118583 + uint8_t k;
118584 +
118585 + param->num_of_schemes = compat_param->num_of_schemes;
118586 + for(k=0; k<compat_param->num_of_schemes; k++)
118587 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
118588 +
118589 + param->direct_scheme = compat_param->direct_scheme;
118590 + if (param->direct_scheme)
118591 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
118592 + }
118593 +}
118594 +
118595 +void compat_copy_fm_port_pcd(
118596 + ioc_compat_fm_port_pcd_params_t *compat_param,
118597 + ioc_fm_port_pcd_params_t *param,
118598 + uint8_t compat)
118599 +{
118600 + if (compat == COMPAT_US_TO_K)
118601 + {
118602 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
118603 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
118604 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
118605 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
118606 +
118607 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
118608 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
118609 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
118610 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
118611 +
118612 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
118613 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
118614 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
118615 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
118616 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
118617 +#if (DPAA_VERSION >= 11)
118618 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
118619 +#endif
118620 + param->pcd_support = compat_param->pcd_support;
118621 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
118622 +
118623 + if (param->p_cc_params)
118624 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
118625 + if (param->p_kg_params)
118626 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
118627 + if (param->p_plcr_params)
118628 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
118629 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
118630 +#if (DPAA_VERSION >= 11)
118631 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
118632 +#endif
118633 + }
118634 +}
118635 +
118636 +void compat_copy_fm_port_pcd_modify_tree(
118637 + ioc_compat_fm_obj_t *compat_id,
118638 + ioc_fm_obj_t *id,
118639 + uint8_t compat)
118640 +{
118641 + if (compat == COMPAT_US_TO_K)
118642 + id->obj = compat_pcd_id2ptr(compat_id->obj);
118643 +}
118644 +
118645 +#if (DPAA_VERSION >= 11)
118646 +void compat_copy_fm_port_vsp_alloc_params(
118647 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
118648 + ioc_fm_port_vsp_alloc_params_t *param,
118649 + uint8_t compat)
118650 +{
118651 + if (compat == COMPAT_US_TO_K)
118652 + {
118653 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
118654 +
118655 + param->dflt_relative_id = compat_param->dflt_relative_id;
118656 + param->num_of_profiles = compat_param->num_of_profiles;
118657 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
118658 + }
118659 +}
118660 +#endif /* (DPAA_VERSION >= 11) */
118661 +
118662 +void compat_copy_fm_pcd_cc_tbl_get_stats(
118663 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
118664 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
118665 + uint8_t compat)
118666 +{
118667 + if (compat == COMPAT_US_TO_K)
118668 + {
118669 + param->id = compat_pcd_id2ptr(compat_param->id);
118670 + param->key_index = compat_param->key_index;
118671 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
118672 + } else {
118673 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118674 + compat_param->key_index = param->key_index;
118675 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
118676 + }
118677 +}
118678 +
118679 +
118680 +void compat_copy_fm_pcd_net_env(
118681 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
118682 + ioc_fm_pcd_net_env_params_t *param,
118683 + uint8_t compat)
118684 +{
118685 + if (compat == COMPAT_US_TO_K)
118686 + {
118687 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
118688 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
118689 + param->id = NULL; /* to avoid passing garbage to the kernel */
118690 + }
118691 + else
118692 + {
118693 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
118694 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
118695 +
118696 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118697 + }
118698 +}
118699 +
118700 +void compat_copy_fm_pcd_cc_node_modify_key(
118701 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
118702 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
118703 + uint8_t compat)
118704 +{
118705 + if (compat == COMPAT_US_TO_K)
118706 + {
118707 + param->key_indx = compat_param->key_indx;
118708 + param->key_size = compat_param->key_size;
118709 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
118710 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
118711 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
118712 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
118713 + param->id = compat_pcd_id2ptr(compat_param->id);
118714 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
118715 + }
118716 + else
118717 + {
118718 + compat_param->key_indx = param->key_indx;
118719 + compat_param->key_size = param->key_size;
118720 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
118721 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
118722 +
118723 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118724 + }
118725 +}
118726 +
118727 +void compat_copy_keys(
118728 + ioc_compat_keys_params_t *compat_param,
118729 + ioc_keys_params_t *param,
118730 + uint8_t compat)
118731 +{
118732 + int k = 0;
118733 +
118734 + _fm_cpt_dbg(compat," {->...\n");
118735 +
118736 + if (compat == COMPAT_US_TO_K) {
118737 + param->max_num_of_keys = compat_param->max_num_of_keys;
118738 + param->mask_support = compat_param->mask_support;
118739 + param->statistics_mode = compat_param->statistics_mode;
118740 + param->num_of_keys = compat_param->num_of_keys;
118741 + param->key_size = compat_param->key_size;
118742 +#if (DPAA_VERSION >= 11)
118743 + memcpy(&param->frame_length_ranges,
118744 + &compat_param->frame_length_ranges,
118745 + sizeof(param->frame_length_ranges[0]) *
118746 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
118747 +#endif /* (DPAA_VERSION >= 11) */
118748 + }
118749 + else {
118750 + compat_param->max_num_of_keys = param->max_num_of_keys;
118751 + compat_param->mask_support = param->mask_support;
118752 + compat_param->statistics_mode = param->statistics_mode;
118753 + compat_param->num_of_keys = param->num_of_keys;
118754 + compat_param->key_size = param->key_size;
118755 +#if (DPAA_VERSION >= 11)
118756 + memcpy(&compat_param->frame_length_ranges,
118757 + &param->frame_length_ranges,
118758 + sizeof(compat_param->frame_length_ranges[0]) *
118759 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
118760 +#endif /* (DPAA_VERSION >= 11) */
118761 + }
118762 +
118763 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
118764 + compat_copy_fm_pcd_cc_key(
118765 + &compat_param->key_params[k],
118766 + &param->key_params[k],
118767 + compat);
118768 +
118769 + compat_copy_fm_pcd_cc_next_engine(
118770 + &compat_param->cc_next_engine_params_for_miss,
118771 + &param->cc_next_engine_params_for_miss,
118772 + compat);
118773 +
118774 + _fm_cpt_dbg(compat," ...->}\n");
118775 +}
118776 +
118777 +void compat_copy_fm_pcd_cc_node(
118778 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
118779 + ioc_fm_pcd_cc_node_params_t *param,
118780 + uint8_t compat)
118781 +{
118782 + _fm_cpt_dbg(compat," {->...\n");
118783 +
118784 + if (compat == COMPAT_US_TO_K)
118785 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
118786 +
118787 + else
118788 + {
118789 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
118790 +
118791 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118792 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
118793 + }
118794 +
118795 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
118796 +
118797 + _fm_cpt_dbg(compat," ...->}\n");
118798 +}
118799 +
118800 +void compat_fm_pcd_manip_set_node(
118801 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118802 + ioc_fm_pcd_manip_params_t *param,
118803 + uint8_t compat)
118804 +{
118805 + if (compat == COMPAT_US_TO_K) {
118806 + param->type = compat_param->type;
118807 + switch (param->type) {
118808 + case e_IOC_FM_PCD_MANIP_HDR:
118809 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
118810 + memcpy(&param->u.hdr.rmv_params,
118811 + &compat_param->u.hdr.rmv_params,
118812 + sizeof(param->u.hdr.rmv_params));
118813 +
118814 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
118815 + param->u.hdr.insrt_params.type =
118816 + compat_param->u.hdr.insrt_params.type;
118817 + switch (compat_param->u.hdr.insrt_params.type)
118818 + {
118819 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
118820 + param->u.hdr.insrt_params.u.generic.offset =
118821 + compat_param->u.hdr.insrt_params.u.generic.offset;
118822 + param->u.hdr.insrt_params.u.generic.size =
118823 + compat_param->u.hdr.insrt_params.u.generic.size;
118824 + param->u.hdr.insrt_params.u.generic.replace =
118825 + compat_param->u.hdr.insrt_params.u.generic.replace;
118826 + param->u.hdr.insrt_params.u.generic.p_data =
118827 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
118828 + break;
118829 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
118830 + param->u.hdr.insrt_params.u.by_hdr.type =
118831 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
118832 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
118833 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
118834 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
118835 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
118836 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
118837 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
118838 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
118839 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
118840 + break;
118841 + default:
118842 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
118843 + }
118844 +
118845 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
118846 + memcpy(&param->u.hdr.field_update_params,
118847 + &compat_param->u.hdr.field_update_params,
118848 + sizeof(param->u.hdr.field_update_params));
118849 +
118850 + param->u.hdr.custom = compat_param->u.hdr.custom;
118851 + memcpy(&param->u.hdr.custom_params,
118852 + &compat_param->u.hdr.custom_params,
118853 + sizeof(param->u.hdr.custom_params));
118854 +
118855 + param->u.hdr.dont_parse_after_manip =
118856 + compat_param->u.hdr.dont_parse_after_manip;
118857 + break;
118858 + case e_IOC_FM_PCD_MANIP_REASSEM:
118859 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
118860 + break;
118861 + case e_IOC_FM_PCD_MANIP_FRAG:
118862 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
118863 + break;
118864 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
118865 + memcpy(&param->u.special_offload,
118866 + &compat_param->u.special_offload,
118867 + sizeof(param->u.special_offload));
118868 + break;
118869 + }
118870 +
118871 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
118872 + param->id = compat_pcd_id2ptr(compat_param->id);
118873 + }
118874 + else {
118875 + compat_param->type = param->type;
118876 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
118877 +
118878 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
118879 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
118880 + compat_param->u.hdr.insrt_params.u.generic.p_data =
118881 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
118882 +
118883 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
118884 + /* ... should be one that was added previously by the very call to
118885 + compat_add_ptr2id() below: */
118886 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118887 + }
118888 +}
118889 +
118890 +void compat_copy_fm_pcd_manip_get_stats(
118891 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118892 + ioc_fm_pcd_manip_get_stats_t *param,
118893 + uint8_t compat)
118894 +{
118895 + _fm_cpt_dbg (compat, " {->...\n");
118896 +
118897 + if (compat == COMPAT_US_TO_K)
118898 + {
118899 + param->id = compat_pcd_id2ptr(compat_param->id);
118900 + memcpy(&param->stats, &compat_param->stats,
118901 + sizeof(ioc_fm_pcd_manip_stats_t));
118902 + }
118903 + else
118904 + {
118905 + compat_param->id = compat_add_ptr2id(param->id,
118906 + FM_MAP_TYPE_PCD_NODE);
118907 + memcpy(&compat_param->stats, &param->stats,
118908 + sizeof(ioc_fm_pcd_manip_stats_t));
118909 + }
118910 +
118911 + _fm_cpt_dbg (compat, " ...->}\n");
118912 +}
118913 +
118914 +#if (DPAA_VERSION >= 11)
118915 +void compat_copy_fm_pcd_frm_replic_group_params(
118916 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118917 + ioc_fm_pcd_frm_replic_group_params_t *param,
118918 + uint8_t compat)
118919 +{
118920 + int k;
118921 +
118922 + _fm_cpt_dbg (compat, " {->...\n");
118923 +
118924 + if (compat == COMPAT_US_TO_K)
118925 + {
118926 + param->max_num_of_entries = compat_param->max_num_of_entries;
118927 + param->num_of_entries = compat_param->num_of_entries;
118928 + param->id = compat_pcd_id2ptr(compat_param->id);
118929 + }
118930 + else
118931 + {
118932 + compat_param->max_num_of_entries = param->max_num_of_entries;
118933 + compat_param->num_of_entries = param->num_of_entries;
118934 + compat_param->id = compat_add_ptr2id(param->id,
118935 + FM_MAP_TYPE_PCD_NODE);
118936 + }
118937 +
118938 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
118939 + compat_copy_fm_pcd_cc_next_engine(
118940 + &compat_param->next_engine_params[k],
118941 + &param->next_engine_params[k],
118942 + compat);
118943 +
118944 + _fm_cpt_dbg (compat, " ...->}\n");
118945 +}
118946 +
118947 +void compat_copy_fm_pcd_frm_replic_member(
118948 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118949 + ioc_fm_pcd_frm_replic_member_t *param,
118950 + uint8_t compat)
118951 +{
118952 + _fm_cpt_dbg (compat, " {->...\n");
118953 +
118954 + if (compat == COMPAT_US_TO_K)
118955 + {
118956 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
118957 + param->member_index = compat_param->member_index;
118958 + }
118959 +
118960 + _fm_cpt_dbg (compat, " ...->}\n");
118961 +}
118962 +
118963 +void compat_copy_fm_pcd_frm_replic_member_params(
118964 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118965 + ioc_fm_pcd_frm_replic_member_params_t *param,
118966 + uint8_t compat)
118967 +{
118968 + _fm_cpt_dbg (compat, " {->...\n");
118969 +
118970 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
118971 + &param->member, compat);
118972 +
118973 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
118974 + &param->next_engine_params, compat);
118975 +
118976 + _fm_cpt_dbg (compat, " ...->}\n");
118977 +}
118978 +
118979 +void compat_copy_fm_vsp_params(
118980 + ioc_compat_fm_vsp_params_t *compat_param,
118981 + ioc_fm_vsp_params_t *param,
118982 + uint8_t compat)
118983 +{
118984 + _fm_cpt_dbg (compat, " {->...\n");
118985 +
118986 + if (compat == COMPAT_US_TO_K)
118987 + {
118988 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
118989 + param->liodn_offset = compat_param->liodn_offset;
118990 + param->port_params.port_id = compat_param->port_params.port_id;
118991 + param->port_params.port_type = compat_param->port_params.port_type;
118992 + param->relative_profile_id = compat_param->relative_profile_id;
118993 + }
118994 + else
118995 + {
118996 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
118997 + compat_param->liodn_offset = param->liodn_offset;
118998 + compat_param->port_params.port_id = param->port_params.port_id;
118999 + compat_param->port_params.port_type = param->port_params.port_type;
119000 + compat_param->relative_profile_id = param->relative_profile_id;
119001 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119002 + }
119003 +
119004 + _fm_cpt_dbg (compat, " ...->}\n");
119005 +}
119006 +
119007 +void compat_copy_fm_buf_pool_depletion_params(
119008 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
119009 + ioc_fm_buf_pool_depletion_params_t *param,
119010 + uint8_t compat)
119011 +{
119012 + _fm_cpt_dbg (compat, " {->...\n");
119013 +
119014 + if (compat == COMPAT_US_TO_K)
119015 + {
119016 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119017 + memcpy(&param->fm_buf_pool_depletion,
119018 + &compat_param->fm_buf_pool_depletion,
119019 + sizeof(ioc_fm_buf_pool_depletion_t));
119020 + }
119021 +
119022 + _fm_cpt_dbg (compat, " ...->}\n");
119023 +}
119024 +
119025 +void compat_copy_fm_buffer_prefix_content_params(
119026 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
119027 + ioc_fm_buffer_prefix_content_params_t *param,
119028 + uint8_t compat)
119029 +{
119030 + _fm_cpt_dbg (compat, " {->...\n");
119031 +
119032 + if (compat == COMPAT_US_TO_K)
119033 + {
119034 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119035 + memcpy(&param->fm_buffer_prefix_content,
119036 + &compat_param->fm_buffer_prefix_content,
119037 + sizeof(ioc_fm_buffer_prefix_content_t));
119038 + }
119039 +
119040 + _fm_cpt_dbg (compat, " ...->}\n");
119041 +}
119042 +
119043 +void compat_copy_fm_vsp_config_no_sg_params(
119044 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
119045 + ioc_fm_vsp_config_no_sg_params_t *param,
119046 + uint8_t compat)
119047 +{
119048 + _fm_cpt_dbg (compat, " {->...\n");
119049 +
119050 + if (compat == COMPAT_US_TO_K)
119051 + {
119052 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119053 + param->no_sg = compat_param->no_sg;
119054 + }
119055 +
119056 + _fm_cpt_dbg (compat, " ...->}\n");
119057 +}
119058 +
119059 +void compat_copy_fm_vsp_prs_result_params(
119060 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
119061 + ioc_fm_vsp_prs_result_params_t *param,
119062 + uint8_t compat)
119063 +{
119064 + _fm_cpt_dbg (compat, " {->...\n");
119065 +
119066 + if (compat == COMPAT_US_TO_K)
119067 + {
119068 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119069 + /* p_data is an user-space pointer that needs to remain unmodified */
119070 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
119071 + }
119072 + else
119073 + {
119074 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
119075 + /* p_data is an user-space pointer that needs to remain unmodified */
119076 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
119077 + }
119078 +
119079 + _fm_cpt_dbg (compat, " ...->}\n");
119080 +}
119081 +#endif /* (DPAA_VERSION >= 11) */
119082 --- /dev/null
119083 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
119084 @@ -0,0 +1,755 @@
119085 +/*
119086 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119087 + *
119088 + * Redistribution and use in source and binary forms, with or without
119089 + * modification, are permitted provided that the following conditions are met:
119090 + * * Redistributions of source code must retain the above copyright
119091 + * notice, this list of conditions and the following disclaimer.
119092 + * * Redistributions in binary form must reproduce the above copyright
119093 + * notice, this list of conditions and the following disclaimer in the
119094 + * documentation and/or other materials provided with the distribution.
119095 + * * Neither the name of Freescale Semiconductor nor the
119096 + * names of its contributors may be used to endorse or promote products
119097 + * derived from this software without specific prior written permission.
119098 + *
119099 + *
119100 + * ALTERNATIVELY, this software may be distributed under the terms of the
119101 + * GNU General Public License ("GPL") as published by the Free Software
119102 + * Foundation, either version 2 of that License or (at your option) any
119103 + * later version.
119104 + *
119105 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119106 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119107 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119108 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119109 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119110 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119111 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119112 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119113 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119114 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119115 + */
119116 +
119117 +/*
119118 + @File lnxwrp_ioctls_fm_compat.h
119119 +
119120 + @Description FM PCD compat structures definition.
119121 +
119122 +*/
119123 +
119124 +#ifndef __FM_COMPAT_IOCTLS_H
119125 +#define __FM_COMPAT_IOCTLS_H
119126 +
119127 +#include <linux/compat.h>
119128 +
119129 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
119130 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
119131 +#define COMPAT_GENERIC 2
119132 +
119133 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
119134 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
119135 +
119136 +/* mapping kernel pointers w/ UserSpace id's { */
119137 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
119138 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
119139 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
119140 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
119141 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
119142 +
119143 +/* define it for debug trace */
119144 +/*#define FM_COMPAT_DBG*/
119145 +
119146 +#define _fm_cpt_prk(stage, format, arg...) \
119147 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
119148 +
119149 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
119150 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
119151 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
119152 +
119153 +/* used for compat IOCTL debugging */
119154 +#if defined(FM_COMPAT_DBG)
119155 + #define _fm_cpt_dbg(from, format, arg...) \
119156 + do{ \
119157 + if (from == COMPAT_US_TO_K) \
119158 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
119159 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
119160 + else if (from == COMPAT_K_TO_US) \
119161 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
119162 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
119163 + else \
119164 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
119165 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
119166 + }while(0)
119167 +#else
119168 +# define _fm_cpt_dbg(arg...)
119169 +#endif
119170 +
119171 +/*TODO: per FMan module:
119172 + *
119173 + * Parser: FM_MAP_TYPE_PARSER_NODE,
119174 + * Kg: FM_MAP_TYPE_KG_NODE,
119175 + * Policer: FM_MAP_TYPE_POLICER_NODE
119176 + * Manip: FM_MAP_TYPE_MANIP_NODE
119177 + **/
119178 +enum fm_map_node_type {
119179 + FM_MAP_TYPE_UNSPEC = 0,
119180 + FM_MAP_TYPE_PCD_NODE,
119181 +
119182 + /* add types here, update the policy */
119183 +
119184 + __FM_MAP_TYPE_AFTER_LAST,
119185 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
119186 +};
119187 +
119188 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
119189 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
119190 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
119191 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
119192 +
119193 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
119194 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
119195 + : (compat_uptr_t) 0;
119196 +}
119197 +
119198 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
119199 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
119200 + : NULL;
119201 +}
119202 +
119203 +/* other similar inlines may be added as new nodes are added
119204 + to enum fm_map_node_type above... */
119205 +/* } mapping kernel pointers w/ UserSpace id's */
119206 +
119207 +/* pcd compat structures { */
119208 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
119209 + compat_uptr_t id;
119210 + uint16_t key_indx;
119211 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
119212 +
119213 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
119214 + ioc_fm_pcd_done_action action;
119215 + compat_uptr_t p_profile;
119216 + compat_uptr_t p_direct_scheme;
119217 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
119218 +
119219 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
119220 + bool modify;
119221 + union {
119222 + struct {
119223 + ioc_fm_pcd_profile_type_selection profile_type;
119224 + compat_uptr_t p_fm_port;
119225 + uint16_t relative_profile_id;
119226 + } new_params;
119227 + compat_uptr_t p_profile;
119228 + } profile_select;
119229 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
119230 + ioc_fm_pcd_plcr_color_mode color_mode;
119231 +
119232 + union {
119233 + ioc_fm_pcd_plcr_color dflt_color;
119234 + ioc_fm_pcd_plcr_color override;
119235 + } color;
119236 +
119237 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
119238 +
119239 + ioc_fm_pcd_engine next_engine_on_green;
119240 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
119241 +
119242 + ioc_fm_pcd_engine next_engine_on_yellow;
119243 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
119244 +
119245 + ioc_fm_pcd_engine next_engine_on_red;
119246 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
119247 +
119248 + bool trap_profile_on_flow_A;
119249 + bool trap_profile_on_flow_B;
119250 + bool trap_profile_on_flow_C;
119251 + compat_uptr_t id;
119252 +} ioc_compat_fm_pcd_plcr_profile_params_t;
119253 +
119254 +typedef struct ioc_compat_fm_obj_t {
119255 + compat_uptr_t obj;
119256 +} ioc_compat_fm_obj_t;
119257 +
119258 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
119259 + bool direct;
119260 + compat_uptr_t scheme_id;
119261 +} ioc_compat_fm_pcd_kg_scheme_select_t;
119262 +
119263 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
119264 + uint8_t num_of_schemes;
119265 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
119266 +} ioc_compat_fm_pcd_port_schemes_params_t;
119267 +
119268 +#if (DPAA_VERSION >= 11)
119269 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
119270 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
119271 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
119272 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
119273 + if relevant function called for Rx port */
119274 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
119275 +}ioc_compat_fm_port_vsp_alloc_params_t;
119276 +#endif /* (DPAA_VERSION >= 11) */
119277 +
119278 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
119279 + uint8_t num_of_distinction_units;
119280 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
119281 + compat_uptr_t id;
119282 +} ioc_compat_fm_pcd_net_env_params_t;
119283 +
119284 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
119285 + bool override;
119286 + uint32_t size;
119287 + uint16_t base;
119288 + compat_uptr_t p_code;
119289 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
119290 + uint8_t num_of_labels;
119291 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
119292 +} ioc_compat_fm_pcd_prs_sw_params_t;
119293 +
119294 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
119295 + bool override_fqid;
119296 + uint32_t new_fqid;
119297 +#if DPAA_VERSION >= 11
119298 + uint8_t new_relative_storage_profile_id;
119299 +#endif
119300 + compat_uptr_t p_direct_scheme;
119301 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
119302 +
119303 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
119304 + compat_uptr_t cc_node_id;
119305 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
119306 +
119307 +#if DPAA_VERSION >= 11
119308 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
119309 + compat_uptr_t frm_replic_id;
119310 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
119311 +#endif /* DPAA_VERSION >= 11 */
119312 +
119313 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
119314 + ioc_fm_pcd_engine next_engine;
119315 + union {
119316 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
119317 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
119318 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
119319 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
119320 +#if DPAA_VERSION >= 11
119321 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
119322 +#endif /* DPAA_VERSION >= 11 */
119323 + } params;
119324 + compat_uptr_t manip_id;
119325 + bool statistics_en;
119326 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
119327 +
119328 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
119329 + uint8_t num_of_distinction_units;
119330 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
119331 + 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];
119332 +} ioc_compat_fm_pcd_cc_grp_params_t;
119333 +
119334 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
119335 + compat_uptr_t net_env_id;
119336 + uint8_t num_of_groups;
119337 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
119338 + compat_uptr_t id;
119339 +} ioc_compat_fm_pcd_cc_tree_params_t;
119340 +
119341 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
119342 + compat_uptr_t id;
119343 + uint8_t grp_indx;
119344 + uint8_t indx;
119345 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
119346 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
119347 +
119348 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
119349 + compat_uptr_t p_key;
119350 + compat_uptr_t p_mask;
119351 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
119352 +} ioc_compat_fm_pcd_cc_key_params_t;
119353 +
119354 +typedef struct ioc_compat_keys_params_t {
119355 + uint16_t max_num_of_keys;
119356 + bool mask_support;
119357 + ioc_fm_pcd_cc_stats_mode statistics_mode;
119358 +#if (DPAA_VERSION >= 11)
119359 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
119360 +#endif /* (DPAA_VERSION >= 11) */
119361 + uint16_t num_of_keys;
119362 + uint8_t key_size;
119363 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
119364 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
119365 +} ioc_compat_keys_params_t;
119366 +
119367 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
119368 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
119369 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
119370 + compat_uptr_t id;
119371 +} ioc_compat_fm_pcd_cc_node_params_t;
119372 +
119373 +/**************************************************************************//**
119374 + @Description Parameters for defining a hash table
119375 +*//***************************************************************************/
119376 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
119377 + uint16_t max_num_of_keys;
119378 + ioc_fm_pcd_cc_stats_mode statistics_mode;
119379 + uint8_t kg_hash_shift;
119380 + uint16_t hash_res_mask;
119381 + uint8_t hash_shift;
119382 + uint8_t match_key_size;
119383 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
119384 + compat_uptr_t id;
119385 +} ioc_compat_fm_pcd_hash_table_params_t;
119386 +
119387 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
119388 + compat_uptr_t p_hash_tbl;
119389 + uint8_t key_size;
119390 + ioc_compat_fm_pcd_cc_key_params_t key_params;
119391 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
119392 +
119393 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
119394 + compat_uptr_t id;
119395 + uint16_t key_indx;
119396 + uint8_t key_size;
119397 + compat_uptr_t p_key;
119398 + compat_uptr_t p_mask;
119399 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
119400 +
119401 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
119402 + compat_uptr_t p_hash_tbl;
119403 + uint8_t key_size;
119404 + compat_uptr_t p_key;
119405 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
119406 +
119407 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
119408 + compat_uptr_t id;
119409 + uint16_t key_indx;
119410 + uint8_t key_size;
119411 + ioc_compat_fm_pcd_cc_key_params_t key_params;
119412 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
119413 +
119414 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
119415 + compat_uptr_t plcr_profile_id;
119416 +} ioc_compat_fm_port_pcd_plcr_params_t;
119417 +
119418 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
119419 + compat_uptr_t cc_tree_id;
119420 +} ioc_compat_fm_port_pcd_cc_params_t;
119421 +
119422 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
119423 + uint8_t num_of_schemes;
119424 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
119425 + bool direct_scheme;
119426 + compat_uptr_t direct_scheme_id;
119427 +} ioc_compat_fm_port_pcd_kg_params_t;
119428 +
119429 +typedef struct ioc_compat_fm_port_pcd_params_t {
119430 + ioc_fm_port_pcd_support pcd_support;
119431 + compat_uptr_t net_env_id;
119432 + compat_uptr_t p_prs_params;
119433 + compat_uptr_t p_cc_params;
119434 + compat_uptr_t p_kg_params;
119435 + compat_uptr_t p_plcr_params;
119436 + compat_uptr_t p_ip_reassembly_manip;
119437 +#if DPAA_VERSION >= 11
119438 + compat_uptr_t p_capwap_reassembly_manip;
119439 +#endif
119440 +} ioc_compat_fm_port_pcd_params_t;
119441 +
119442 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
119443 + compat_uptr_t tree_id;
119444 + uint8_t grp_id;
119445 + bool plcr_next;
119446 + bool bypass_plcr_profile_generation;
119447 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
119448 +} ioc_compat_fm_pcd_kg_cc_t;
119449 +
119450 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
119451 + bool modify;
119452 + union {
119453 + uint8_t relative_scheme_id;
119454 + compat_uptr_t scheme_id;
119455 + } scm_id;
119456 + bool always_direct;
119457 + struct {
119458 + compat_uptr_t net_env_id;
119459 + uint8_t num_of_distinction_units;
119460 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
119461 + } net_env_params;
119462 + bool use_hash;
119463 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
119464 + bool bypass_fqid_generation;
119465 + uint32_t base_fqid;
119466 + uint8_t num_of_used_extracted_ors;
119467 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
119468 +#if DPAA_VERSION >= 11
119469 + bool override_storage_profile;
119470 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
119471 +#endif /* DPAA_VERSION >= 11 */
119472 + ioc_fm_pcd_engine next_engine;
119473 + union{
119474 + ioc_fm_pcd_done_action done_action;
119475 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
119476 + ioc_compat_fm_pcd_kg_cc_t cc;
119477 + } kg_next_engine_params;
119478 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
119479 + compat_uptr_t id;
119480 +} ioc_compat_fm_pcd_kg_scheme_params_t;
119481 +
119482 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
119483 + compat_uptr_t id;
119484 + uint16_t key_indx;
119485 + uint8_t key_size;
119486 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
119487 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
119488 +
119489 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
119490 + uint8_t offset;
119491 + uint8_t size;
119492 + bool replace;
119493 + compat_uptr_t p_data;
119494 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
119495 +
119496 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
119497 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
119498 + bool update;
119499 + uint8_t size;
119500 + compat_uptr_t p_data;
119501 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
119502 +
119503 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
119504 + uint8_t size; /**< size of inserted section */
119505 + compat_uptr_t p_data; /**< data to be inserted */
119506 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
119507 +
119508 +#if (DPAA_VERSION >= 11)
119509 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
119510 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
119511 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
119512 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
119513 + the inserted header */
119514 + uint16_t id; /**< 16 bit New IP ID */
119515 + bool dont_frag_overwrite;
119516 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
119517 + * This byte is configured to be overwritten when RPD is set. */
119518 + uint8_t last_dst_offset;
119519 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
119520 + * in order to calculate UDP checksum pseudo header;
119521 + * Otherwise set it to '0'. */
119522 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
119523 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
119524 +#endif /* (DPAA_VERSION >= 11) */
119525 +
119526 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
119527 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
119528 + union {
119529 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
119530 +#if (DPAA_VERSION >= 11)
119531 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
119532 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
119533 +#endif /* (DPAA_VERSION >= 11) */
119534 + } u;
119535 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
119536 +
119537 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
119538 + ioc_fm_pcd_manip_hdr_insrt_type type;
119539 + union {
119540 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
119541 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
119542 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
119543 +#error "FM_CAPWAP_SUPPORT feature not supported!"
119544 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
119545 +#endif /* FM_CAPWAP_SUPPORT */
119546 + } u;
119547 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
119548 +
119549 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
119550 + bool rmv;
119551 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
119552 + bool insrt;
119553 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
119554 + bool field_update;
119555 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
119556 + bool custom;
119557 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
119558 + bool dont_parse_after_manip;
119559 +} ioc_compat_fm_pcd_manip_hdr_params_t;
119560 +
119561 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
119562 + bool decryption;
119563 + bool ecn_copy;
119564 + bool dscp_copy;
119565 + bool variable_ip_hdr_len;
119566 + bool variable_ip_version;
119567 + uint8_t outer_ip_hdr_len;
119568 + uint16_t arw_size;
119569 + compat_uptr_t arw_addr;
119570 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
119571 +
119572 +typedef struct ioc_compat_fm_pcd_manip_params_t {
119573 + ioc_fm_pcd_manip_type type;
119574 + union {
119575 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
119576 + ioc_fm_pcd_manip_reassem_params_t reassem;
119577 + ioc_fm_pcd_manip_frag_params_t frag;
119578 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
119579 + } u;
119580 + compat_uptr_t p_next_manip;
119581 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
119582 +#error "FM_CAPWAP_SUPPORT feature not supported!"
119583 + bool frag_or_reasm;
119584 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
119585 +#endif /* FM_CAPWAP_SUPPORT */
119586 + compat_uptr_t id;
119587 +} ioc_compat_fm_pcd_manip_params_t;
119588 +
119589 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
119590 + compat_uptr_t id;
119591 + ioc_fm_pcd_manip_stats_t stats;
119592 +} ioc_compat_fm_pcd_manip_get_stats_t;
119593 +
119594 +#if (DPAA_VERSION >= 11)
119595 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
119596 + uint8_t max_num_of_entries;
119597 + uint8_t num_of_entries;
119598 + ioc_compat_fm_pcd_cc_next_engine_params_t
119599 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
119600 + compat_uptr_t id;
119601 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
119602 +
119603 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
119604 + compat_uptr_t h_replic_group;
119605 + uint16_t member_index;
119606 +} ioc_compat_fm_pcd_frm_replic_member_t;
119607 +
119608 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
119609 + ioc_compat_fm_pcd_frm_replic_member_t member;
119610 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
119611 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
119612 +
119613 +typedef struct ioc_compat_fm_vsp_params_t {
119614 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
119615 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
119616 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
119617 + parameter associated with Rx / OP port */
119618 + uint16_t liodn_offset; /**< VSP's LIODN offset */
119619 + struct {
119620 + ioc_fm_port_type port_type; /**< Port type */
119621 + uint8_t port_id; /**< Port Id - relative to type */
119622 + } port_params;
119623 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
119624 + defined in relevant FM object */
119625 + compat_uptr_t id; /**< return value */
119626 +} ioc_compat_fm_vsp_params_t;
119627 +
119628 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
119629 + compat_uptr_t p_fm_vsp;
119630 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
119631 +} ioc_compat_fm_buf_pool_depletion_params_t;
119632 +
119633 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
119634 + compat_uptr_t p_fm_vsp;
119635 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
119636 +} ioc_compat_fm_buffer_prefix_content_params_t;
119637 +
119638 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
119639 + compat_uptr_t p_fm_vsp;
119640 + bool no_sg;
119641 +} ioc_compat_fm_vsp_config_no_sg_params_t;
119642 +
119643 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
119644 + compat_uptr_t p_fm_vsp;
119645 + compat_uptr_t p_data;
119646 +} ioc_compat_fm_vsp_prs_result_params_t;
119647 +
119648 +#endif /* (DPAA_VERSION >= 11) */
119649 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
119650 + uint32_t val;
119651 + compat_uptr_t id;
119652 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
119653 +
119654 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
119655 + uint8_t fm_ctrl_index;
119656 + compat_uptr_t p_mon;
119657 +} ioc_compat_fm_ctrl_mon_counters_params_t;
119658 +
119659 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
119660 + compat_uptr_t id;
119661 + uint16_t key_index;
119662 + ioc_fm_pcd_cc_key_statistics_t statistics;
119663 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
119664 +
119665 +
119666 +/* } pcd compat structures */
119667 +
119668 +void compat_obj_delete(
119669 + ioc_compat_fm_obj_t *compat_id,
119670 + ioc_fm_obj_t *id);
119671 +
119672 +/* pcd compat functions { */
119673 +void compat_copy_fm_pcd_plcr_profile(
119674 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
119675 + ioc_fm_pcd_plcr_profile_params_t *param,
119676 + uint8_t compat);
119677 +
119678 +void compat_copy_fm_pcd_cc_key(
119679 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
119680 + ioc_fm_pcd_cc_key_params_t *param,
119681 + uint8_t compat);
119682 +
119683 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
119684 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
119685 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
119686 + uint8_t compat);
119687 +
119688 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
119689 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
119690 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
119691 + uint8_t compat);
119692 +
119693 +void compat_fm_pcd_cc_tree_modify_next_engine(
119694 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
119695 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
119696 + uint8_t compat);
119697 +
119698 +void compat_copy_fm_pcd_hash_table(
119699 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
119700 + ioc_fm_pcd_hash_table_params_t *param,
119701 + uint8_t compat);
119702 +
119703 +void compat_copy_fm_pcd_cc_grp(
119704 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
119705 + ioc_fm_pcd_cc_grp_params_t *param,
119706 + uint8_t compat);
119707 +
119708 +void compat_copy_fm_pcd_cc_tree(
119709 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
119710 + ioc_fm_pcd_cc_tree_params_t *param,
119711 + uint8_t compat);
119712 +
119713 +void compat_copy_fm_pcd_cc_tbl_get_stats(
119714 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
119715 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
119716 + uint8_t compat);
119717 +
119718 +void compat_fm_pcd_prs_sw(
119719 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
119720 + ioc_fm_pcd_prs_sw_params_t *param,
119721 + uint8_t compat);
119722 +
119723 +void compat_copy_fm_pcd_kg_scheme(
119724 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
119725 + ioc_fm_pcd_kg_scheme_params_t *param,
119726 + uint8_t compat);
119727 +
119728 +void compat_copy_fm_pcd_kg_scheme_select(
119729 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
119730 + ioc_fm_pcd_kg_scheme_select_t *param,
119731 + uint8_t compat);
119732 +
119733 +void compat_copy_fm_pcd_kg_schemes_params(
119734 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
119735 + ioc_fm_pcd_port_schemes_params_t *param,
119736 + uint8_t compat);
119737 +
119738 +void compat_copy_fm_port_pcd_kg(
119739 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
119740 + ioc_fm_port_pcd_kg_params_t *param,
119741 + uint8_t compat);
119742 +
119743 +void compat_copy_fm_port_pcd(
119744 + ioc_compat_fm_port_pcd_params_t *compat_param,
119745 + ioc_fm_port_pcd_params_t *param,
119746 + uint8_t compat);
119747 +
119748 +#if (DPAA_VERSION >= 11)
119749 +void compat_copy_fm_port_vsp_alloc_params(
119750 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
119751 + ioc_fm_port_vsp_alloc_params_t *param,
119752 + uint8_t compat);
119753 +#endif /* (DPAA_VERSION >= 11) */
119754 +
119755 +void compat_copy_fm_pcd_net_env(
119756 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
119757 + ioc_fm_pcd_net_env_params_t *param,
119758 + uint8_t compat);
119759 +
119760 +void compat_copy_fm_pcd_cc_node_modify_key(
119761 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
119762 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
119763 + uint8_t compat);
119764 +
119765 +void compat_copy_keys(
119766 + ioc_compat_keys_params_t *compat_param,
119767 + ioc_keys_params_t *param,
119768 + uint8_t compat);
119769 +
119770 +void compat_copy_fm_pcd_cc_node(
119771 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
119772 + ioc_fm_pcd_cc_node_params_t *param,
119773 + uint8_t compat);
119774 +
119775 +void compat_fm_pcd_manip_set_node(
119776 + ioc_compat_fm_pcd_manip_params_t *compat_param,
119777 + ioc_fm_pcd_manip_params_t *param,
119778 + uint8_t compat);
119779 +
119780 +void compat_copy_fm_pcd_manip_get_stats(
119781 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
119782 + ioc_fm_pcd_manip_get_stats_t *param,
119783 + uint8_t compat);
119784 +
119785 +void compat_copy_fm_port_pcd_modify_tree(
119786 + ioc_compat_fm_obj_t *compat_id,
119787 + ioc_fm_obj_t *id,
119788 + uint8_t compat);
119789 +
119790 +#if (DPAA_VERSION >= 11)
119791 +void compat_copy_fm_pcd_frm_replic_group_params(
119792 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
119793 + ioc_fm_pcd_frm_replic_group_params_t *param,
119794 + uint8_t compat);
119795 +
119796 +void compat_copy_fm_pcd_frm_replic_member(
119797 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
119798 + ioc_fm_pcd_frm_replic_member_t *param,
119799 + uint8_t compat);
119800 +
119801 +void compat_copy_fm_pcd_frm_replic_member_params(
119802 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
119803 + ioc_fm_pcd_frm_replic_member_params_t *param,
119804 + uint8_t compat);
119805 +
119806 +void compat_copy_fm_vsp_params(
119807 + ioc_compat_fm_vsp_params_t *compat_param,
119808 + ioc_fm_vsp_params_t *param,
119809 + uint8_t compat);
119810 +
119811 +void compat_copy_fm_buf_pool_depletion_params(
119812 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
119813 + ioc_fm_buf_pool_depletion_params_t *param,
119814 + uint8_t compat);
119815 +
119816 +void compat_copy_fm_buffer_prefix_content_params(
119817 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
119818 + ioc_fm_buffer_prefix_content_params_t *param,
119819 + uint8_t compat);
119820 +
119821 +void compat_copy_fm_vsp_config_no_sg_params(
119822 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
119823 + ioc_fm_vsp_config_no_sg_params_t *param,
119824 + uint8_t compat);
119825 +
119826 +void compat_copy_fm_vsp_prs_result_params(
119827 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
119828 + ioc_fm_vsp_prs_result_params_t *param,
119829 + uint8_t compat);
119830 +
119831 +#endif /* (DPAA_VERSION >= 11) */
119832 +
119833 +void compat_copy_fm_pcd_kg_scheme_spc(
119834 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
119835 + ioc_fm_pcd_kg_scheme_spc_t *param,
119836 + uint8_t compat);
119837 +
119838 +/* } pcd compat functions */
119839 +#endif
119840 --- /dev/null
119841 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
119842 @@ -0,0 +1,121 @@
119843 +/*
119844 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119845 + *
119846 + * Redistribution and use in source and binary forms, with or without
119847 + * modification, are permitted provided that the following conditions are met:
119848 + * * Redistributions of source code must retain the above copyright
119849 + * notice, this list of conditions and the following disclaimer.
119850 + * * Redistributions in binary form must reproduce the above copyright
119851 + * notice, this list of conditions and the following disclaimer in the
119852 + * documentation and/or other materials provided with the distribution.
119853 + * * Neither the name of Freescale Semiconductor nor the
119854 + * names of its contributors may be used to endorse or promote products
119855 + * derived from this software without specific prior written permission.
119856 + *
119857 + *
119858 + * ALTERNATIVELY, this software may be distributed under the terms of the
119859 + * GNU General Public License ("GPL") as published by the Free Software
119860 + * Foundation, either version 2 of that License or (at your option) any
119861 + * later version.
119862 + *
119863 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119864 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119865 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119866 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119867 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119868 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119869 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119870 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119871 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119872 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119873 + */
119874 +
119875 +/*
119876 + @File lnxwrp_resources.h
119877 +
119878 + @Description FMD wrapper resource allocation functions.
119879 +
119880 +*/
119881 +
119882 +#ifndef LNXWRP_RESOURCES_H_
119883 +#define LNXWRP_RESOURCES_H_
119884 +
119885 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
119886 +#include "lnxwrp_fm.h"
119887 +#else
119888 +#include "lnxwrp_resources_ut.h"
119889 +#endif
119890 +
119891 +#define ROUND(X) ((2*(X)+1)/2)
119892 +#define CEIL(X) ((X)+1)
119893 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
119894 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
119895 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
119896 +
119897 +/* used for resource calculus */
119898 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
119899 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
119900 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
119901 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
119902 +
119903 +int fm_set_active_fman_ports(struct platform_device *of_dev,
119904 + t_LnxWrpFmDev *p_LnxWrpFmDev);
119905 +
119906 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
119907 + * value and s/g software support (! Kernel does not suport s/g).
119908 + *
119909 + * Algorithm summary:
119910 + * - Calculate the the minimum fifosize required for every type of port
119911 + * (TX,RX for 1G, 2.5G and 10G).
119912 + * - Set TX the minimum fifosize required.
119913 + * - Distribute the remaining buffers (after all TX were set) to RX ports
119914 + * based on:
119915 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
119916 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
119917 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
119918 + * - if the RX is smaller than the minimum required, then set the minimum
119919 + * required
119920 + * - In the end distribuite the leftovers if there are any (due to
119921 + * unprecise calculus) or if over allocation cat some buffers from all RX
119922 + * ports w/o pass over minimum required treshold, but if there must be
119923 + * pass the treshold in order to cat the over allocation ,then this
119924 + * configuration can not be set - KERN_ALERT.
119925 +*/
119926 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
119927 + int muram_fifo_size);
119928 +
119929 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
119930 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
119931 +#endif
119932 +
119933 +/* Compute FMan open DMA based on total number of open DMAs and
119934 + * number of available fman ports.
119935 + *
119936 + * By default 10g ports are set to input parameters. The other ports
119937 + * tries to keep the proportion rx=2tx open dmas or tresholds.
119938 + *
119939 + * If leftovers, then those will be set as shared.
119940 + *
119941 + * If after computing overflow appears, then it decrements open dma
119942 + * for all ports w/o cross the tresholds. If the tresholds are meet
119943 + * and is still overflow, then it returns error.
119944 +*/
119945 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
119946 + int max_fm_open_dma,
119947 + int default_tx_10g_dmas,
119948 + int default_rx_10g_dmas,
119949 + int min_tx_10g_treshold, int min_rx_10g_treshold);
119950 +
119951 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
119952 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
119953 +#endif
119954 +
119955 +/* Compute FMan tnums based on available tnums and number of ports.
119956 + * Set defaults (minim tresholds) and then distribute leftovers.*/
119957 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
119958 +
119959 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
119960 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
119961 +#endif
119962 +
119963 +#endif /* LNXWRP_RESOURCES_H_ */
119964 --- /dev/null
119965 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
119966 @@ -0,0 +1,191 @@
119967 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
119968 + * All rights reserved.
119969 + *
119970 + * Redistribution and use in source and binary forms, with or without
119971 + * modification, are permitted provided that the following conditions are met:
119972 + * * Redistributions of source code must retain the above copyright
119973 + * notice, this list of conditions and the following disclaimer.
119974 + * * Redistributions in binary form must reproduce the above copyright
119975 + * notice, this list of conditions and the following disclaimer in the
119976 + * documentation and/or other materials provided with the distribution.
119977 + * * Neither the name of Freescale Semiconductor nor the
119978 + * names of its contributors may be used to endorse or promote products
119979 + * derived from this software without specific prior written permission.
119980 + *
119981 + *
119982 + * ALTERNATIVELY, this software may be distributed under the terms of the
119983 + * GNU General Public License ("GPL") as published by the Free Software
119984 + * Foundation, either version 2 of that License or (at your option) any
119985 + * later version.
119986 + *
119987 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119988 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119989 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119990 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119991 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119992 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119993 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119994 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119995 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119996 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119997 + */
119998 +
119999 +#include "lnxwrp_resources.h"
120000 +#include "lnxwrp_resources_ut.h"
120001 +
120002 +#define KILOBYTE 0x400 /* 1024 */
120003 +
120004 +typedef enum e_board_type {
120005 + e_p3041,
120006 + e_p4080,
120007 + e_p5020,
120008 + e_p1023
120009 +} e_board_type;
120010 +
120011 +uint8_t board_type;
120012 +uint32_t muram_size = 0;
120013 +uint32_t dmas_num = 0;
120014 +uint32_t task_num = 0;
120015 +uint32_t frame_size = 0;
120016 +uint32_t oh_num = 0;
120017 +uint32_t num_ports_1g = 0;
120018 +uint32_t num_ports_10g = 0;
120019 +uint32_t num_ports_2g5 = 0;
120020 +uint32_t fsl_fman_phy_maxfrm = 0;
120021 +uint32_t dpa_rx_extra_headroom = 0;
120022 +
120023 +void show_help(void){
120024 + printf(" help: \n");
120025 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
120026 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
120027 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
120028 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
120029 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
120030 + printf(" Number of ports:\n");
120031 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
120032 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
120033 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
120034 + printf(" MTU: Default:1522, Jumbo:9600 \n");
120035 +}
120036 +
120037 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
120038 + struct fm_active_ports *fm_active_ports_info = NULL;
120039 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
120040 +
120041 + switch(board_type){
120042 + case e_p3041:
120043 + case e_p5020:
120044 + muram_size = 160*KILOBYTE;
120045 + dmas_num = 32;
120046 + task_num = 128;
120047 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
120048 + goto err_fm_set_param;
120049 + break;
120050 + case e_p4080:
120051 + muram_size = 160*KILOBYTE;
120052 + dmas_num = 32;
120053 + task_num = 128;
120054 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
120055 + goto err_fm_set_param;
120056 + break;
120057 + case e_p1023:
120058 + muram_size = 64*KILOBYTE;
120059 + dmas_num = 16;
120060 + task_num = 128;
120061 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
120062 + goto err_fm_set_param;
120063 + break;
120064 + default:
120065 + goto err_fm_set_param;
120066 + break;
120067 + }
120068 +
120069 + p_LnxWrpFmDev->id = 0;
120070 + fsl_fman_phy_maxfrm = frame_size;
120071 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
120072 + fm_active_ports_info->num_oh_ports = oh_num;
120073 + fm_active_ports_info->num_tx_ports = num_ports_1g;
120074 + fm_active_ports_info->num_rx_ports = num_ports_1g;
120075 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
120076 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
120077 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
120078 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
120079 +
120080 + return 0;
120081 +
120082 +err_fm_set_param:
120083 + printf(" ERR: To many ports!!! \n");
120084 + return -1;
120085 +}
120086 +
120087 +int main (int argc, char *argv[]){
120088 + t_LnxWrpFmDev LnxWrpFmDev;
120089 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
120090 + int tokens_cnt = 1;
120091 +
120092 + char *token = NULL;
120093 +
120094 + while(tokens_cnt < argc)
120095 + {
120096 + token = argv[tokens_cnt++];
120097 + if (strcmp(token, "-b") == 0){
120098 + if(strcmp(argv[tokens_cnt],"p3") == 0)
120099 + board_type = e_p3041;
120100 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
120101 + board_type = e_p4080;
120102 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
120103 + board_type = e_p5020;
120104 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
120105 + board_type = e_p1023;
120106 + else
120107 + show_help();
120108 + tokens_cnt++;
120109 + }
120110 + else if(strcmp(token, "-d") == 0){
120111 + dmas_num = atoi(argv[tokens_cnt++]);
120112 + }
120113 + else if(strcmp(token, "-t") == 0)
120114 + task_num = atoi(argv[tokens_cnt++]);
120115 + else if(strcmp(token, "-f") == 0)
120116 + frame_size = atoi(argv[tokens_cnt++]);
120117 + else if(strcmp(token, "-o") == 0)
120118 + oh_num = atoi(argv[tokens_cnt++]);
120119 + else if(strcmp(token, "-g1") == 0)
120120 + num_ports_1g = atoi(argv[tokens_cnt++]);
120121 + else if(strcmp(token, "-g10") == 0)
120122 + num_ports_10g = atoi(argv[tokens_cnt++]);
120123 + else if(strcmp(token, "-g25") == 0)
120124 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
120125 + else {
120126 + show_help();
120127 + return -1;
120128 + }
120129 + }
120130 +
120131 + if(fm_set_param(p_LnxWrpFmDev) < 0){
120132 + show_help();
120133 + return -1;
120134 + }
120135 +
120136 + if(fm_precalculate_fifosizes(
120137 + p_LnxWrpFmDev,
120138 + 128*KILOBYTE)
120139 + != 0)
120140 + return -1;
120141 + if(fm_precalculate_open_dma(
120142 + p_LnxWrpFmDev,
120143 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
120144 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
120145 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
120146 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
120147 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
120148 + != 0)
120149 + return -1;
120150 + if(fm_precalculate_tnums(
120151 + p_LnxWrpFmDev,
120152 + task_num) /* max TNUMS: dpa integration file. */
120153 + != 0)
120154 + return -1;
120155 +
120156 + return 0;
120157 +}
120158 --- /dev/null
120159 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
120160 @@ -0,0 +1,144 @@
120161 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
120162 + * All rights reserved.
120163 + *
120164 + * Redistribution and use in source and binary forms, with or without
120165 + * modification, are permitted provided that the following conditions are met:
120166 + * * Redistributions of source code must retain the above copyright
120167 + * notice, this list of conditions and the following disclaimer.
120168 + * * Redistributions in binary form must reproduce the above copyright
120169 + * notice, this list of conditions and the following disclaimer in the
120170 + * documentation and/or other materials provided with the distribution.
120171 + * * Neither the name of Freescale Semiconductor nor the
120172 + * names of its contributors may be used to endorse or promote products
120173 + * derived from this software without specific prior written permission.
120174 + *
120175 + *
120176 + * ALTERNATIVELY, this software may be distributed under the terms of the
120177 + * GNU General Public License ("GPL") as published by the Free Software
120178 + * Foundation, either version 2 of that License or (at your option) any
120179 + * later version.
120180 + *
120181 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120182 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120183 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120184 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120185 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120186 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120187 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120188 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120189 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120190 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120191 + */
120192 +
120193 +#ifndef FM_RESS_TEST_H_
120194 +#define FM_RESS_TEST_H_
120195 +
120196 +#include <stdint.h>
120197 +#include <stdbool.h>
120198 +#include <stdio.h>
120199 +#include <assert.h>
120200 +#include <string.h>
120201 +#include <stdlib.h>
120202 +
120203 +#define _Packed
120204 +#define _PackedType __attribute__ ((packed))
120205 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
120206 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
120207 +#define KERN_ALERT ""
120208 +#define KERN_INFO ""
120209 +#define ASSERT_COND assert
120210 +#define printk printf
120211 +#define NET_IP_ALIGN 0
120212 +#define FM_FIFO_ALLOCATION_OLD_ALG
120213 +
120214 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
120215 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
120216 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
120217 +#else
120218 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
120219 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
120220 +#endif
120221 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
120222 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
120223 +
120224 +/* information about all active ports for an FMan.
120225 + * !Some ports may be disabled by u-boot, thus will not be available */
120226 +struct fm_active_ports {
120227 + uint32_t num_oh_ports;
120228 + uint32_t num_tx_ports;
120229 + uint32_t num_rx_ports;
120230 + uint32_t num_tx25_ports;
120231 + uint32_t num_rx25_ports;
120232 + uint32_t num_tx10_ports;
120233 + uint32_t num_rx10_ports;
120234 +};
120235 +
120236 +/* FMan resources precalculated at fm probe based
120237 + * on available FMan port. */
120238 +struct fm_resource_settings {
120239 + /* buffers - fifo sizes */
120240 + uint32_t tx1g_num_buffers;
120241 + uint32_t rx1g_num_buffers;
120242 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
120243 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
120244 + uint32_t tx10g_num_buffers;
120245 + uint32_t rx10g_num_buffers;
120246 + uint32_t oh_num_buffers;
120247 + uint32_t shared_ext_buffers;
120248 +
120249 +
120250 + /* open DMAs */
120251 + uint32_t tx_1g_dmas;
120252 + uint32_t rx_1g_dmas;
120253 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
120254 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
120255 + uint32_t tx_10g_dmas;
120256 + uint32_t rx_10g_dmas;
120257 + uint32_t oh_dmas;
120258 + uint32_t shared_ext_open_dma;
120259 +
120260 + /* Tnums */
120261 + uint32_t tx_1g_tnums;
120262 + uint32_t rx_1g_tnums;
120263 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
120264 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
120265 + uint32_t tx_10g_tnums;
120266 + uint32_t rx_10g_tnums;
120267 + uint32_t oh_tnums;
120268 + uint32_t shared_ext_tnums;
120269 +};
120270 +
120271 +typedef struct {
120272 + uint8_t id;
120273 + struct fm_active_ports fm_active_ports_info;
120274 + struct fm_resource_settings fm_resource_settings_info;
120275 +} t_LnxWrpFmDev;
120276 +
120277 +typedef struct {
120278 + uint8_t id;
120279 +} t_LnxWrpFmPortDev;
120280 +
120281 +typedef _Packed struct t_FmPrsResult {
120282 + volatile uint8_t lpid; /**< Logical port id */
120283 + volatile uint8_t shimr; /**< Shim header result */
120284 + volatile uint16_t l2r; /**< Layer 2 result */
120285 + volatile uint16_t l3r; /**< Layer 3 result */
120286 + volatile uint8_t l4r; /**< Layer 4 result */
120287 + volatile uint8_t cplan; /**< Classification plan id */
120288 + volatile uint16_t nxthdr; /**< Next Header */
120289 + volatile uint16_t cksum; /**< Checksum */
120290 + volatile uint32_t lcv; /**< LCV */
120291 + volatile uint8_t shim_off[3]; /**< Shim offset */
120292 + volatile uint8_t eth_off; /**< ETH offset */
120293 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
120294 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
120295 + volatile uint8_t etype_off; /**< ETYPE offset */
120296 + volatile uint8_t pppoe_off; /**< PPP offset */
120297 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
120298 + volatile uint8_t ip_off[2]; /**< IP offset */
120299 + volatile uint8_t gre_off; /**< GRE offset */
120300 + volatile uint8_t l4_off; /**< Layer 4 offset */
120301 + volatile uint8_t nxthdr_off; /**< Parser end point */
120302 +} _PackedType t_FmPrsResult;
120303 +
120304 +#endif
120305 --- /dev/null
120306 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
120307 @@ -0,0 +1,28 @@
120308 +CC=gcc
120309 +
120310 +LNXWRP_RESS_UT=lnxwrp_resources_ut
120311 +OBJ=lnxwrp_resources
120312 +
120313 +INC_PATH=
120314 +LIB_PATH=
120315 +
120316 +INC=$(addprefix -I,$(INC_PATH))
120317 +LIB=$(addprefix -L,$(LIB_PATH))
120318 +
120319 +CFLAGS= -gdwarf-2 -g -O0 -Wall
120320 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
120321 +
120322 +all: $(LNXWRP_RESS_UT)
120323 +
120324 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
120325 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
120326 +
120327 +%.o: %.c
120328 + @(echo " (CC) $@")
120329 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
120330 +
120331 +.PHONY: clean
120332 +
120333 +clean:
120334 + rm -f *.o
120335 + rm -f $(LNXWRP_RESS_UT)
120336 --- /dev/null
120337 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
120338 @@ -0,0 +1,60 @@
120339 +/*
120340 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120341 + *
120342 + * Redistribution and use in source and binary forms, with or without
120343 + * modification, are permitted provided that the following conditions are met:
120344 + * * Redistributions of source code must retain the above copyright
120345 + * notice, this list of conditions and the following disclaimer.
120346 + * * Redistributions in binary form must reproduce the above copyright
120347 + * notice, this list of conditions and the following disclaimer in the
120348 + * documentation and/or other materials provided with the distribution.
120349 + * * Neither the name of Freescale Semiconductor nor the
120350 + * names of its contributors may be used to endorse or promote products
120351 + * derived from this software without specific prior written permission.
120352 + *
120353 + *
120354 + * ALTERNATIVELY, this software may be distributed under the terms of the
120355 + * GNU General Public License ("GPL") as published by the Free Software
120356 + * Foundation, either version 2 of that License or (at your option) any
120357 + * later version.
120358 + *
120359 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120360 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120361 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120362 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120363 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120364 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120365 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120366 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120367 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120368 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120369 + */
120370 +
120371 +/*
120372 + @File lnxwrp_sysfs.c
120373 +
120374 + @Description FM wrapper sysfs related functions.
120375 +
120376 +*/
120377 +
120378 +#include <linux/types.h>
120379 +#include "lnxwrp_sysfs.h"
120380 +
120381 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
120382 + const struct sysfs_stats_t *sysfs_stats,
120383 + uint8_t *offset)
120384 +{
120385 + int i = 0;
120386 +
120387 + while (sysfs_stats[i].stat_name != NULL) {
120388 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
120389 + if (offset != NULL)
120390 + *offset = i;
120391 + return sysfs_stats[i].stat_counter;
120392 + }
120393 +
120394 + i++;
120395 + }
120396 + WARN(1, "FMD: Should never get here!");
120397 + return 0;
120398 +}
120399 --- /dev/null
120400 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
120401 @@ -0,0 +1,60 @@
120402 +/*
120403 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120404 + *
120405 + * Redistribution and use in source and binary forms, with or without
120406 + * modification, are permitted provided that the following conditions are met:
120407 + * * Redistributions of source code must retain the above copyright
120408 + * notice, this list of conditions and the following disclaimer.
120409 + * * Redistributions in binary form must reproduce the above copyright
120410 + * notice, this list of conditions and the following disclaimer in the
120411 + * documentation and/or other materials provided with the distribution.
120412 + * * Neither the name of Freescale Semiconductor nor the
120413 + * names of its contributors may be used to endorse or promote products
120414 + * derived from this software without specific prior written permission.
120415 + *
120416 + *
120417 + * ALTERNATIVELY, this software may be distributed under the terms of the
120418 + * GNU General Public License ("GPL") as published by the Free Software
120419 + * Foundation, either version 2 of that License or (at your option) any
120420 + * later version.
120421 + *
120422 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120423 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120424 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120425 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120426 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120427 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120428 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120429 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120430 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120431 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120432 + */
120433 +
120434 +#ifndef LNXWRP_SYSFS_H_
120435 +#define LNXWRP_SYSFS_H_
120436 +
120437 +/* Linux Headers ------------------- */
120438 +#include <linux/version.h>
120439 +
120440 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
120441 +#define MODVERSIONS
120442 +#endif
120443 +#ifdef MODVERSIONS
120444 +#include <config/modversions.h>
120445 +#endif /* MODVERSIONS */
120446 +
120447 +#include <linux/kernel.h>
120448 +#include <linux/module.h>
120449 +#include <linux/device.h>
120450 +#include <linux/sysfs.h>
120451 +
120452 +struct sysfs_stats_t {
120453 + const char *stat_name;
120454 + uint8_t stat_counter;
120455 +};
120456 +
120457 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
120458 + const struct sysfs_stats_t *sysfs_stats,
120459 + uint8_t *offset);
120460 +
120461 +#endif /* LNXWRP_SYSFS_H_ */
120462 --- /dev/null
120463 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
120464 @@ -0,0 +1,1855 @@
120465 +/*
120466 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120467 + *
120468 + * Redistribution and use in source and binary forms, with or without
120469 + * modification, are permitted provided that the following conditions are met:
120470 + * * Redistributions of source code must retain the above copyright
120471 + * notice, this list of conditions and the following disclaimer.
120472 + * * Redistributions in binary form must reproduce the above copyright
120473 + * notice, this list of conditions and the following disclaimer in the
120474 + * documentation and/or other materials provided with the distribution.
120475 + * * Neither the name of Freescale Semiconductor nor the
120476 + * names of its contributors may be used to endorse or promote products
120477 + * derived from this software without specific prior written permission.
120478 + *
120479 + *
120480 + * ALTERNATIVELY, this software may be distributed under the terms of the
120481 + * GNU General Public License ("GPL") as published by the Free Software
120482 + * Foundation, either version 2 of that License or (at your option) any
120483 + * later version.
120484 + *
120485 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120486 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120487 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120488 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120489 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120490 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120491 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120492 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120493 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120494 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120495 + */
120496 +
120497 +#include "lnxwrp_sysfs.h"
120498 +#include "lnxwrp_sysfs_fm.h"
120499 +#include "lnxwrp_fm.h"
120500 +
120501 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
120502 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
120503 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
120504 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
120505 +
120506 +#if defined(__ERR_MODULE__)
120507 +#undef __ERR_MODULE__
120508 +#endif
120509 +
120510 +#include "../../sdk_fman/Peripherals/FM/fm.h"
120511 +#include <linux/delay.h>
120512 +
120513 +
120514 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
120515 +
120516 +enum fm_dma_match_stats {
120517 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
120518 + FM_DMA_COUNTERS_BUS_ERROR,
120519 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
120520 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
120521 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
120522 +};
120523 +
120524 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
120525 + /* FM statistics */
120526 + {
120527 + .stat_name = "enq_total_frame",
120528 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
120529 + },
120530 + {
120531 + .stat_name = "deq_total_frame",
120532 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
120533 + },
120534 + {
120535 + .stat_name = "deq_0",
120536 + .stat_counter = e_FM_COUNTERS_DEQ_0,
120537 + },
120538 + {
120539 + .stat_name = "deq_1",
120540 + .stat_counter = e_FM_COUNTERS_DEQ_1,
120541 + },
120542 + {
120543 + .stat_name = "deq_2",
120544 + .stat_counter = e_FM_COUNTERS_DEQ_2,
120545 + },
120546 + {
120547 + .stat_name = "deq_3",
120548 + .stat_counter = e_FM_COUNTERS_DEQ_3,
120549 + },
120550 + {
120551 + .stat_name = "deq_from_default",
120552 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
120553 + },
120554 + {
120555 + .stat_name = "deq_from_context",
120556 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
120557 + },
120558 + {
120559 + .stat_name = "deq_from_fd",
120560 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
120561 + },
120562 + {
120563 + .stat_name = "deq_confirm",
120564 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
120565 + },
120566 + /* FM:DMA statistics */
120567 + {
120568 + .stat_name = "cmq_not_empty",
120569 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
120570 + },
120571 + {
120572 + .stat_name = "bus_error",
120573 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
120574 + },
120575 + {
120576 + .stat_name = "read_buf_ecc_error",
120577 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
120578 + },
120579 + {
120580 + .stat_name = "write_buf_ecc_sys_error",
120581 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
120582 + },
120583 + {
120584 + .stat_name = "write_buf_ecc_fm_error",
120585 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
120586 + },
120587 + /* FM:PCD statistics */
120588 + {
120589 + .stat_name = "pcd_kg_total",
120590 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
120591 + },
120592 + {
120593 + .stat_name = "pcd_plcr_yellow",
120594 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
120595 + },
120596 + {
120597 + .stat_name = "pcd_plcr_red",
120598 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
120599 + },
120600 + {
120601 + .stat_name = "pcd_plcr_recolored_to_red",
120602 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
120603 + },
120604 + {
120605 + .stat_name = "pcd_plcr_recolored_to_yellow",
120606 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
120607 + },
120608 + {
120609 + .stat_name = "pcd_plcr_total",
120610 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
120611 + },
120612 + {
120613 + .stat_name = "pcd_plcr_length_mismatch",
120614 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
120615 + },
120616 + {
120617 + .stat_name = "pcd_prs_parse_dispatch",
120618 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
120619 + },
120620 + {
120621 + .stat_name = "pcd_prs_l2_parse_result_returned",
120622 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
120623 + },
120624 + {
120625 + .stat_name = "pcd_prs_l3_parse_result_returned",
120626 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
120627 + },
120628 + {
120629 + .stat_name = "pcd_prs_l4_parse_result_returned",
120630 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
120631 + },
120632 + {
120633 + .stat_name = "pcd_prs_shim_parse_result_returned",
120634 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
120635 + },
120636 + {
120637 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
120638 + .stat_counter =
120639 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
120640 + },
120641 + {
120642 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
120643 + .stat_counter =
120644 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
120645 + },
120646 + {
120647 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
120648 + .stat_counter =
120649 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
120650 + },
120651 + {
120652 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
120653 + .stat_counter =
120654 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
120655 + },
120656 + {
120657 + .stat_name = "pcd_prs_soft_prs_cycles",
120658 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
120659 + },
120660 + {
120661 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
120662 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
120663 + },
120664 + {
120665 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
120666 + .stat_counter =
120667 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
120668 + },
120669 + {
120670 + .stat_name = "pcd_prs_muram_read_cycles",
120671 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
120672 + },
120673 + {
120674 + .stat_name = "pcd_prs_muram_read_stall_cycles",
120675 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
120676 + },
120677 + {
120678 + .stat_name = "pcd_prs_muram_write_cycles",
120679 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
120680 + },
120681 + {
120682 + .stat_name = "pcd_prs_muram_write_stall_cycles",
120683 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
120684 + },
120685 + {
120686 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
120687 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
120688 + },
120689 + {}
120690 +};
120691 +
120692 +
120693 +static ssize_t show_fm_risc_load(struct device *dev,
120694 + struct device_attribute *attr, char *buf)
120695 +{
120696 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120697 + unsigned long flags;
120698 + int m =0;
120699 + int err =0;
120700 + unsigned n = 0;
120701 + t_FmCtrlMon util;
120702 + uint8_t i =0 ;
120703 +
120704 + if (attr == NULL || buf == NULL || dev == NULL)
120705 + return -EINVAL;
120706 +
120707 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120708 + if (WARN_ON(p_wrp_fm_dev == NULL))
120709 + return -EINVAL;
120710 +
120711 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120712 + return -EIO;
120713 +
120714 + local_irq_save(flags);
120715 +
120716 + /* Calculate risc load */
120717 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
120718 + msleep(1000);
120719 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
120720 +
120721 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
120722 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
120723 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
120724 + i, util.percentCnt[0], util.percentCnt[1]);
120725 + n=m+n;
120726 + }
120727 +
120728 + local_irq_restore(flags);
120729 +
120730 + return n;
120731 +}
120732 +
120733 +/* Fm stats and regs dumps via sysfs */
120734 +static ssize_t show_fm_dma_stats(struct device *dev,
120735 + struct device_attribute *attr, char *buf)
120736 +{
120737 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120738 + t_FmDmaStatus dma_status;
120739 + unsigned long flags = 0;
120740 + unsigned n = 0;
120741 + uint8_t counter_value = 0, counter = 0;
120742 +
120743 + if (attr == NULL || buf == NULL || dev == NULL)
120744 + return -EINVAL;
120745 +
120746 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120747 + if (WARN_ON(p_wrp_fm_dev == NULL))
120748 + return -EINVAL;
120749 +
120750 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120751 + return -EIO;
120752 +
120753 + counter = fm_find_statistic_counter_by_name(
120754 + attr->attr.name,
120755 + fm_sysfs_stats, NULL);
120756 +
120757 + local_irq_save(flags);
120758 +
120759 + memset(&dma_status, 0, sizeof(dma_status));
120760 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
120761 +
120762 + switch (counter) {
120763 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
120764 + counter_value = dma_status.cmqNotEmpty;
120765 + break;
120766 + case FM_DMA_COUNTERS_BUS_ERROR:
120767 + counter_value = dma_status.busError;
120768 + break;
120769 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
120770 + counter_value = dma_status.readBufEccError;
120771 + break;
120772 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
120773 + counter_value = dma_status.writeBufEccSysError;
120774 + break;
120775 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
120776 + counter_value = dma_status.writeBufEccFmError;
120777 + break;
120778 + default:
120779 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
120780 + __func__);
120781 + break;
120782 + };
120783 +
120784 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
120785 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
120786 +
120787 + local_irq_restore(flags);
120788 +
120789 + return n;
120790 +}
120791 +
120792 +static ssize_t show_fm_stats(struct device *dev,
120793 + struct device_attribute *attr, char *buf)
120794 +{
120795 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120796 + unsigned long flags = 0;
120797 + unsigned n = 0, cnt_e = 0;
120798 + uint32_t cnt_val;
120799 + int err;
120800 +
120801 + if (attr == NULL || buf == NULL || dev == NULL)
120802 + return -EINVAL;
120803 +
120804 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120805 + if (WARN_ON(p_wrp_fm_dev == NULL))
120806 + return -EINVAL;
120807 +
120808 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120809 + return -EIO;
120810 +
120811 + cnt_e = fm_find_statistic_counter_by_name(
120812 + attr->attr.name,
120813 + fm_sysfs_stats, NULL);
120814 +
120815 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
120816 + (e_FmCounters) cnt_e, &cnt_val);
120817 +
120818 + if (err)
120819 + return err;
120820 +
120821 + local_irq_save(flags);
120822 +
120823 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
120824 + p_wrp_fm_dev->id, cnt_val);
120825 +
120826 + local_irq_restore(flags);
120827 +
120828 + return n;
120829 +}
120830 +
120831 +static ssize_t show_fm_muram_free_sz(struct device *dev,
120832 + struct device_attribute *attr, char *buf)
120833 +{
120834 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120835 + unsigned long flags = 0;
120836 + unsigned n = 0;
120837 + uint64_t muram_free_size = 0;
120838 +
120839 + if (attr == NULL || buf == NULL || dev == NULL)
120840 + return -EINVAL;
120841 +
120842 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120843 + if (WARN_ON(p_wrp_fm_dev == NULL))
120844 + return -EINVAL;
120845 +
120846 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120847 + return -EIO;
120848 +
120849 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
120850 +
120851 + local_irq_save(flags);
120852 +
120853 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
120854 + p_wrp_fm_dev->id, muram_free_size);
120855 +
120856 + local_irq_restore(flags);
120857 +
120858 + return n;
120859 +}
120860 +
120861 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
120862 + struct device_attribute *attr, char *buf)
120863 +{
120864 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120865 + unsigned long flags = 0;
120866 + unsigned n = 0;
120867 + t_FmCtrlCodeRevisionInfo rv_info;
120868 +
120869 + if (attr == NULL || buf == NULL || dev == NULL)
120870 + return -EINVAL;
120871 +
120872 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120873 + if (WARN_ON(p_wrp_fm_dev == NULL))
120874 + return -EINVAL;
120875 +
120876 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120877 + return -EIO;
120878 +
120879 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
120880 +
120881 + local_irq_save(flags);
120882 +
120883 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
120884 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
120885 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
120886 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
120887 +
120888 + local_irq_restore(flags);
120889 +
120890 + return n;
120891 +}
120892 +
120893 +static ssize_t show_fm_pcd_stats(struct device *dev,
120894 + struct device_attribute *attr, char *buf)
120895 +{
120896 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120897 + unsigned long flags = 0;
120898 + unsigned n = 0, counter = 0;
120899 +
120900 + if (attr == NULL || buf == NULL || dev == NULL)
120901 + return -EINVAL;
120902 +
120903 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120904 + if (WARN_ON(p_wrp_fm_dev == NULL))
120905 + return -EINVAL;
120906 +
120907 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
120908 + !p_wrp_fm_dev->h_PcdDev)
120909 + return -EIO;
120910 +
120911 + counter = fm_find_statistic_counter_by_name(
120912 + attr->attr.name,
120913 + fm_sysfs_stats, NULL);
120914 +
120915 + local_irq_save(flags);
120916 +
120917 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
120918 + p_wrp_fm_dev->id,
120919 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
120920 + (e_FmPcdCounters) counter));
120921 +
120922 + local_irq_restore(flags);
120923 +
120924 + return n;
120925 +}
120926 +
120927 +static ssize_t show_fm_tnum_dbg(struct device *dev,
120928 + struct device_attribute *attr,
120929 + char *buf)
120930 +{
120931 + unsigned long flags;
120932 + unsigned n = 0;
120933 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120934 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120935 +#endif
120936 +
120937 + if (attr == NULL || buf == NULL || dev == NULL)
120938 + return -EINVAL;
120939 +
120940 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120941 +
120942 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120943 + if (WARN_ON(p_wrp_fm_dev == NULL))
120944 + return -EINVAL;
120945 +
120946 + local_irq_save(flags);
120947 +
120948 + if (!p_wrp_fm_dev->active)
120949 + return -EIO;
120950 + else {
120951 + int tn_s;
120952 +
120953 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
120954 + return -EINVAL;
120955 +
120956 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
120957 + tn_s, tn_s + 15, buf, n);
120958 + }
120959 + local_irq_restore(flags);
120960 +#else
120961 +
120962 + local_irq_save(flags);
120963 + n = snprintf(buf, PAGE_SIZE,
120964 + "Debug level is too low to dump registers!!!\n");
120965 + local_irq_restore(flags);
120966 +#endif /* (defined(DEBUG_ERRORS) && ... */
120967 +
120968 + return n;
120969 +}
120970 +
120971 +static ssize_t show_fm_cls_plan(struct device *dev,
120972 + struct device_attribute *attr,
120973 + char *buf)
120974 +{
120975 + unsigned long flags;
120976 + unsigned n = 0;
120977 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120978 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120979 +#endif
120980 +
120981 + if (attr == NULL || buf == NULL || dev == NULL)
120982 + return -EINVAL;
120983 +
120984 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120985 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120986 + if (WARN_ON(p_wrp_fm_dev == NULL))
120987 + return -EINVAL;
120988 +
120989 + local_irq_save(flags);
120990 +
120991 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
120992 +
120993 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120994 + return -EIO;
120995 + else {
120996 + int cpn;
120997 +
120998 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
120999 + return -EINVAL;
121000 +
121001 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
121002 + }
121003 + local_irq_restore(flags);
121004 +#else
121005 + local_irq_save(flags);
121006 + n = snprintf(buf, PAGE_SIZE,
121007 + "Debug level is too low to dump registers!!!\n");
121008 + local_irq_restore(flags);
121009 +#endif /* (defined(DEBUG_ERRORS) && ... */
121010 +
121011 + return n;
121012 +}
121013 +
121014 +static ssize_t show_fm_profiles(struct device *dev,
121015 + struct device_attribute *attr,
121016 + char *buf)
121017 +{
121018 + unsigned long flags;
121019 + unsigned n = 0;
121020 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121021 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121022 +#endif
121023 +
121024 + if (attr == NULL || buf == NULL || dev == NULL)
121025 + return -EINVAL;
121026 +
121027 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121028 +
121029 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121030 + if (WARN_ON(p_wrp_fm_dev == NULL))
121031 + return -EINVAL;
121032 +
121033 + local_irq_save(flags);
121034 +
121035 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
121036 +
121037 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121038 + return -EIO;
121039 + else {
121040 + int pn;
121041 +
121042 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
121043 + return -EINVAL;
121044 +
121045 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
121046 + }
121047 + local_irq_restore(flags);
121048 +#else
121049 + local_irq_save(flags);
121050 + n = snprintf(buf, PAGE_SIZE,
121051 + "Debug level is too low to dump registers!!!\n");
121052 + local_irq_restore(flags);
121053 +#endif /* (defined(DEBUG_ERRORS) && ... */
121054 +
121055 + return n;
121056 +}
121057 +
121058 +static ssize_t show_fm_schemes(struct device *dev,
121059 + struct device_attribute *attr,
121060 + char *buf)
121061 +{
121062 + unsigned long flags;
121063 + unsigned n = 0;
121064 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121065 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121066 +#endif
121067 +
121068 + if (attr == NULL || buf == NULL || dev == NULL)
121069 + return -EINVAL;
121070 +
121071 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121072 +
121073 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121074 + if (WARN_ON(p_wrp_fm_dev == NULL))
121075 + return -EINVAL;
121076 +
121077 + local_irq_save(flags);
121078 +
121079 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
121080 +
121081 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121082 + return -EIO;
121083 + else {
121084 + int sn;
121085 +
121086 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
121087 + return -EINVAL;
121088 +
121089 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
121090 + }
121091 + local_irq_restore(flags);
121092 +#else
121093 +
121094 + local_irq_save(flags);
121095 + n = snprintf(buf, PAGE_SIZE,
121096 + "Debug level is too low to dump registers!!!\n");
121097 + local_irq_restore(flags);
121098 +#endif /* (defined(DEBUG_ERRORS) && ... */
121099 +
121100 + return n;
121101 +}
121102 +
121103 +/* FM */
121104 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
121105 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
121106 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
121107 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
121108 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
121109 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
121110 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
121111 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
121112 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
121113 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
121114 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
121115 +/* FM:DMA */
121116 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
121117 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
121118 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
121119 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
121120 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
121121 +/* FM:PCD */
121122 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
121123 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
121124 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
121125 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
121126 + NULL);
121127 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
121128 + NULL);
121129 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
121130 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
121131 + NULL);
121132 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
121133 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
121134 + show_fm_pcd_stats, NULL);
121135 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
121136 + show_fm_pcd_stats, NULL);
121137 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
121138 + show_fm_pcd_stats, NULL);
121139 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
121140 + show_fm_pcd_stats, NULL);
121141 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
121142 + show_fm_pcd_stats, NULL);
121143 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
121144 + show_fm_pcd_stats, NULL);
121145 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
121146 + show_fm_pcd_stats, NULL);
121147 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
121148 + show_fm_pcd_stats, NULL);
121149 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
121150 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
121151 + NULL);
121152 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
121153 + show_fm_pcd_stats, NULL);
121154 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
121155 + NULL);
121156 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
121157 + show_fm_pcd_stats, NULL);
121158 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
121159 + NULL);
121160 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
121161 + show_fm_pcd_stats, NULL);
121162 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
121163 + show_fm_pcd_stats, NULL);
121164 +
121165 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
121166 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
121167 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
121168 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
121169 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
121170 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
121171 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
121172 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
121173 +
121174 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
121175 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
121176 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
121177 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
121178 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
121179 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
121180 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
121181 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
121182 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
121183 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
121184 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
121185 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
121186 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
121187 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
121188 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
121189 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
121190 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
121191 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
121192 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
121193 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
121194 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
121195 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
121196 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
121197 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
121198 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
121199 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
121200 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
121201 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
121202 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
121203 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
121204 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
121205 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
121206 +
121207 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
121208 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
121209 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
121210 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
121211 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
121212 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
121213 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
121214 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
121215 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
121216 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
121217 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
121218 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
121219 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
121220 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
121221 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
121222 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
121223 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
121224 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
121225 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
121226 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
121227 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
121228 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
121229 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
121230 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
121231 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
121232 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
121233 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
121234 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
121235 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
121236 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
121237 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
121238 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
121239 +
121240 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
121241 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
121242 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
121243 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
121244 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
121245 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
121246 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
121247 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
121248 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
121249 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
121250 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
121251 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
121252 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
121253 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
121254 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
121255 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
121256 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
121257 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
121258 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
121259 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
121260 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
121261 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
121262 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
121263 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
121264 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
121265 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
121266 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
121267 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
121268 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
121269 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
121270 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
121271 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
121272 +
121273 +
121274 +static struct attribute *fm_dev_stats_attributes[] = {
121275 + &dev_attr_enq_total_frame.attr,
121276 + &dev_attr_deq_total_frame.attr,
121277 + &dev_attr_deq_0.attr,
121278 + &dev_attr_deq_1.attr,
121279 + &dev_attr_deq_2.attr,
121280 + &dev_attr_deq_3.attr,
121281 + &dev_attr_deq_from_default.attr,
121282 + &dev_attr_deq_from_context.attr,
121283 + &dev_attr_deq_from_fd.attr,
121284 + &dev_attr_deq_confirm.attr,
121285 + &dev_attr_cmq_not_empty.attr,
121286 + &dev_attr_bus_error.attr,
121287 + &dev_attr_read_buf_ecc_error.attr,
121288 + &dev_attr_write_buf_ecc_sys_error.attr,
121289 + &dev_attr_write_buf_ecc_fm_error.attr,
121290 + &dev_attr_pcd_kg_total.attr,
121291 + &dev_attr_pcd_plcr_yellow.attr,
121292 + &dev_attr_pcd_plcr_red.attr,
121293 + &dev_attr_pcd_plcr_recolored_to_red.attr,
121294 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
121295 + &dev_attr_pcd_plcr_total.attr,
121296 + &dev_attr_pcd_plcr_length_mismatch.attr,
121297 + &dev_attr_pcd_prs_parse_dispatch.attr,
121298 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
121299 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
121300 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
121301 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
121302 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
121303 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
121304 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
121305 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
121306 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
121307 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
121308 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
121309 + &dev_attr_pcd_prs_muram_read_cycles.attr,
121310 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
121311 + &dev_attr_pcd_prs_muram_write_cycles.attr,
121312 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
121313 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
121314 + NULL
121315 +};
121316 +
121317 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
121318 + &dev_attr_tnum_dbg_0.attr,
121319 + &dev_attr_tnum_dbg_16.attr,
121320 + &dev_attr_tnum_dbg_32.attr,
121321 + &dev_attr_tnum_dbg_48.attr,
121322 + &dev_attr_tnum_dbg_64.attr,
121323 + &dev_attr_tnum_dbg_80.attr,
121324 + &dev_attr_tnum_dbg_96.attr,
121325 + &dev_attr_tnum_dbg_112.attr,
121326 + NULL
121327 +};
121328 +
121329 +static struct attribute *fm_dev_cls_plans_attributes[] = {
121330 + &dev_attr_cls_plan_0.attr,
121331 + &dev_attr_cls_plan_1.attr,
121332 + &dev_attr_cls_plan_2.attr,
121333 + &dev_attr_cls_plan_3.attr,
121334 + &dev_attr_cls_plan_4.attr,
121335 + &dev_attr_cls_plan_5.attr,
121336 + &dev_attr_cls_plan_6.attr,
121337 + &dev_attr_cls_plan_7.attr,
121338 + &dev_attr_cls_plan_8.attr,
121339 + &dev_attr_cls_plan_9.attr,
121340 + &dev_attr_cls_plan_10.attr,
121341 + &dev_attr_cls_plan_11.attr,
121342 + &dev_attr_cls_plan_12.attr,
121343 + &dev_attr_cls_plan_13.attr,
121344 + &dev_attr_cls_plan_14.attr,
121345 + &dev_attr_cls_plan_15.attr,
121346 + &dev_attr_cls_plan_16.attr,
121347 + &dev_attr_cls_plan_17.attr,
121348 + &dev_attr_cls_plan_18.attr,
121349 + &dev_attr_cls_plan_19.attr,
121350 + &dev_attr_cls_plan_20.attr,
121351 + &dev_attr_cls_plan_21.attr,
121352 + &dev_attr_cls_plan_22.attr,
121353 + &dev_attr_cls_plan_23.attr,
121354 + &dev_attr_cls_plan_24.attr,
121355 + &dev_attr_cls_plan_25.attr,
121356 + &dev_attr_cls_plan_26.attr,
121357 + &dev_attr_cls_plan_27.attr,
121358 + &dev_attr_cls_plan_28.attr,
121359 + &dev_attr_cls_plan_29.attr,
121360 + &dev_attr_cls_plan_30.attr,
121361 + &dev_attr_cls_plan_31.attr,
121362 + NULL
121363 +};
121364 +
121365 +static struct attribute *fm_dev_profiles_attributes[] = {
121366 + &dev_attr_profile_0.attr,
121367 + &dev_attr_profile_1.attr,
121368 + &dev_attr_profile_2.attr,
121369 + &dev_attr_profile_3.attr,
121370 + &dev_attr_profile_4.attr,
121371 + &dev_attr_profile_5.attr,
121372 + &dev_attr_profile_6.attr,
121373 + &dev_attr_profile_7.attr,
121374 + &dev_attr_profile_8.attr,
121375 + &dev_attr_profile_9.attr,
121376 + &dev_attr_profile_10.attr,
121377 + &dev_attr_profile_11.attr,
121378 + &dev_attr_profile_12.attr,
121379 + &dev_attr_profile_13.attr,
121380 + &dev_attr_profile_14.attr,
121381 + &dev_attr_profile_15.attr,
121382 + &dev_attr_profile_16.attr,
121383 + &dev_attr_profile_17.attr,
121384 + &dev_attr_profile_18.attr,
121385 + &dev_attr_profile_19.attr,
121386 + &dev_attr_profile_20.attr,
121387 + &dev_attr_profile_21.attr,
121388 + &dev_attr_profile_22.attr,
121389 + &dev_attr_profile_23.attr,
121390 + &dev_attr_profile_24.attr,
121391 + &dev_attr_profile_25.attr,
121392 + &dev_attr_profile_26.attr,
121393 + &dev_attr_profile_27.attr,
121394 + &dev_attr_profile_28.attr,
121395 + &dev_attr_profile_29.attr,
121396 + &dev_attr_profile_30.attr,
121397 + &dev_attr_profile_31.attr,
121398 + NULL
121399 +};
121400 +
121401 +static struct attribute *fm_dev_schemes_attributes[] = {
121402 + &dev_attr_scheme_0.attr,
121403 + &dev_attr_scheme_1.attr,
121404 + &dev_attr_scheme_2.attr,
121405 + &dev_attr_scheme_3.attr,
121406 + &dev_attr_scheme_4.attr,
121407 + &dev_attr_scheme_5.attr,
121408 + &dev_attr_scheme_6.attr,
121409 + &dev_attr_scheme_7.attr,
121410 + &dev_attr_scheme_8.attr,
121411 + &dev_attr_scheme_9.attr,
121412 + &dev_attr_scheme_10.attr,
121413 + &dev_attr_scheme_11.attr,
121414 + &dev_attr_scheme_12.attr,
121415 + &dev_attr_scheme_13.attr,
121416 + &dev_attr_scheme_14.attr,
121417 + &dev_attr_scheme_15.attr,
121418 + &dev_attr_scheme_16.attr,
121419 + &dev_attr_scheme_17.attr,
121420 + &dev_attr_scheme_18.attr,
121421 + &dev_attr_scheme_19.attr,
121422 + &dev_attr_scheme_20.attr,
121423 + &dev_attr_scheme_21.attr,
121424 + &dev_attr_scheme_22.attr,
121425 + &dev_attr_scheme_23.attr,
121426 + &dev_attr_scheme_24.attr,
121427 + &dev_attr_scheme_25.attr,
121428 + &dev_attr_scheme_26.attr,
121429 + &dev_attr_scheme_27.attr,
121430 + &dev_attr_scheme_28.attr,
121431 + &dev_attr_scheme_29.attr,
121432 + &dev_attr_scheme_30.attr,
121433 + &dev_attr_scheme_31.attr,
121434 + NULL
121435 +};
121436 +
121437 +static const struct attribute_group fm_dev_stats_attr_grp = {
121438 + .name = "statistics",
121439 + .attrs = fm_dev_stats_attributes
121440 +};
121441 +
121442 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
121443 + .name = "tnums_dbg",
121444 + .attrs = fm_dev_tnums_dbg_attributes
121445 +};
121446 +
121447 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
121448 + .name = "cls_plans",
121449 + .attrs = fm_dev_cls_plans_attributes
121450 +};
121451 +
121452 +static const struct attribute_group fm_dev_schemes_attr_grp = {
121453 + .name = "schemes",
121454 + .attrs = fm_dev_schemes_attributes
121455 +};
121456 +
121457 +static const struct attribute_group fm_dev_profiles_attr_grp = {
121458 + .name = "profiles",
121459 + .attrs = fm_dev_profiles_attributes
121460 +};
121461 +
121462 +static ssize_t show_fm_regs(struct device *dev,
121463 + struct device_attribute *attr,
121464 + char *buf)
121465 +{
121466 + unsigned long flags;
121467 + unsigned n = 0;
121468 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121469 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121470 +#endif
121471 + if (attr == NULL || buf == NULL || dev == NULL)
121472 + return -EINVAL;
121473 +
121474 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121475 +
121476 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121477 + if (WARN_ON(p_wrp_fm_dev == NULL))
121478 + return -EINVAL;
121479 +
121480 + local_irq_save(flags);
121481 +
121482 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
121483 +
121484 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121485 + return -EIO;
121486 + else
121487 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
121488 +
121489 + local_irq_restore(flags);
121490 +#else
121491 +
121492 + local_irq_save(flags);
121493 + n = snprintf(buf, PAGE_SIZE,
121494 + "Debug level is too low to dump registers!!!\n");
121495 + local_irq_restore(flags);
121496 +#endif /* (defined(DEBUG_ERRORS) && ... */
121497 +
121498 + return n;
121499 +}
121500 +
121501 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
121502 + struct device_attribute *attr,
121503 + char *buf)
121504 +{
121505 + unsigned long flags;
121506 + unsigned n = 0;
121507 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121508 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121509 +#endif
121510 +
121511 + if (attr == NULL || buf == NULL || dev == NULL)
121512 + return -EINVAL;
121513 +
121514 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121515 +
121516 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121517 + if (WARN_ON(p_wrp_fm_dev == NULL))
121518 + return -EINVAL;
121519 +
121520 + local_irq_save(flags);
121521 +
121522 + n = snprintf(buf, PAGE_SIZE,
121523 + "\n FM-KG Port Partition Config registers dump.\n");
121524 +
121525 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121526 + return -EIO;
121527 + else
121528 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
121529 +
121530 + local_irq_restore(flags);
121531 +#else
121532 +
121533 + local_irq_save(flags);
121534 + n = snprintf(buf, PAGE_SIZE,
121535 + "Debug level is too low to dump registers!!!\n");
121536 + local_irq_restore(flags);
121537 +#endif /* (defined(DEBUG_ERRORS) && ... */
121538 +
121539 + return n;
121540 +}
121541 +
121542 +static ssize_t show_fm_kg_regs(struct device *dev,
121543 + struct device_attribute *attr,
121544 + char *buf)
121545 +{
121546 + unsigned long flags;
121547 + unsigned n = 0;
121548 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121549 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121550 +#endif
121551 +
121552 + if (attr == NULL || buf == NULL || dev == NULL)
121553 + return -EINVAL;
121554 +
121555 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121556 +
121557 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121558 + if (WARN_ON(p_wrp_fm_dev == NULL))
121559 + return -EINVAL;
121560 +
121561 + local_irq_save(flags);
121562 +
121563 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
121564 +
121565 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121566 + return -EIO;
121567 + else
121568 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
121569 +
121570 + local_irq_restore(flags);
121571 +#else
121572 +
121573 + local_irq_save(flags);
121574 + n = snprintf(buf, PAGE_SIZE,
121575 + "Debug level is too low to dump registers!!!\n");
121576 + local_irq_restore(flags);
121577 +#endif /* (defined(DEBUG_ERRORS) && ... */
121578 +
121579 + return n;
121580 +}
121581 +
121582 +
121583 +static ssize_t show_fm_fpm_regs(struct device *dev,
121584 + struct device_attribute *attr,
121585 + char *buf)
121586 +{
121587 + unsigned long flags;
121588 + unsigned n = 0;
121589 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121590 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121591 +#endif
121592 +
121593 + if (attr == NULL || buf == NULL || dev == NULL)
121594 + return -EINVAL;
121595 +
121596 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121597 +
121598 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121599 + if (WARN_ON(p_wrp_fm_dev == NULL))
121600 + return -EINVAL;
121601 +
121602 + local_irq_save(flags);
121603 +
121604 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
121605 +
121606 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121607 + return -EIO;
121608 + else
121609 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
121610 +
121611 + local_irq_restore(flags);
121612 +#else
121613 +
121614 + local_irq_save(flags);
121615 + n = snprintf(buf, PAGE_SIZE,
121616 + "Debug level is too low to dump registers!!!\n");
121617 + local_irq_restore(flags);
121618 +#endif /* (defined(DEBUG_ERRORS) && ... */
121619 +
121620 + return n;
121621 +}
121622 +
121623 +static ssize_t show_prs_regs(struct device *dev,
121624 + struct device_attribute *attr, char *buf)
121625 +{
121626 + unsigned long flags;
121627 + unsigned n = 0;
121628 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121629 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121630 +#endif
121631 +
121632 + if (attr == NULL || buf == NULL || dev == NULL)
121633 + return -EINVAL;
121634 +
121635 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121636 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121637 + if (WARN_ON(p_wrp_fm_dev == NULL))
121638 + return -EINVAL;
121639 +
121640 + local_irq_save(flags);
121641 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
121642 +
121643 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121644 + return -EIO;
121645 + else
121646 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
121647 +
121648 + local_irq_restore(flags);
121649 +#else
121650 +
121651 + local_irq_save(flags);
121652 + n = snprintf(buf, PAGE_SIZE,
121653 + "Debug level is too low to dump registers!!!\n");
121654 + local_irq_restore(flags);
121655 +
121656 +#endif /* (defined(DEBUG_ERRORS) && ... */
121657 +
121658 + return n;
121659 +}
121660 +
121661 +static ssize_t show_plcr_regs(struct device *dev,
121662 + struct device_attribute *attr,
121663 + char *buf)
121664 +{
121665 + unsigned long flags;
121666 + unsigned n = 0;
121667 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121668 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121669 +#endif
121670 +
121671 + if (attr == NULL || buf == NULL || dev == NULL)
121672 + return -EINVAL;
121673 +
121674 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121675 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121676 + if (WARN_ON(p_wrp_fm_dev == NULL))
121677 + return -EINVAL;
121678 +
121679 + local_irq_save(flags);
121680 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
121681 +
121682 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121683 + return -EIO;
121684 + else
121685 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
121686 +
121687 + local_irq_restore(flags);
121688 +#else
121689 +
121690 + local_irq_save(flags);
121691 + n = snprintf(buf, PAGE_SIZE,
121692 + "Debug level is too low to dump registers!!!\n");
121693 + local_irq_restore(flags);
121694 +
121695 +#endif /* (defined(DEBUG_ERRORS) && ... */
121696 +
121697 + return n;
121698 +}
121699 +
121700 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
121701 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
121702 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
121703 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
121704 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
121705 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
121706 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
121707 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
121708 +
121709 +int fm_sysfs_create(struct device *dev)
121710 +{
121711 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121712 +
121713 + if (dev == NULL)
121714 + return -EIO;
121715 +
121716 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121717 +
121718 + /* store to remove them when module is disabled */
121719 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
121720 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
121721 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
121722 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
121723 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
121724 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
121725 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
121726 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
121727 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
121728 +
121729 + /* Create sysfs statistics group for FM module */
121730 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
121731 + return -EIO;
121732 +
121733 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
121734 + return -EIO;
121735 +
121736 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
121737 + return -EIO;
121738 +
121739 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
121740 + return -EIO;
121741 +
121742 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
121743 + return -EIO;
121744 +
121745 + /* Registers dump entry - in future will be moved to debugfs */
121746 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
121747 + return -EIO;
121748 +
121749 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
121750 + return -EIO;
121751 +
121752 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
121753 + return -EIO;
121754 +
121755 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
121756 + return -EIO;
121757 +
121758 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
121759 + return -EIO;
121760 +
121761 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
121762 + return -EIO;
121763 +
121764 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
121765 + return -EIO;
121766 +
121767 + /* muram free size */
121768 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
121769 + return -EIO;
121770 +
121771 + /* fm ctrl code version */
121772 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
121773 + return -EIO;
121774 +
121775 + return 0;
121776 +}
121777 +
121778 +void fm_sysfs_destroy(struct device *dev)
121779 +{
121780 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121781 +
121782 + if (WARN_ON(dev == NULL))
121783 + return;
121784 +
121785 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121786 + if (WARN_ON(p_wrp_fm_dev == NULL))
121787 + return;
121788 +
121789 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
121790 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
121791 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
121792 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
121793 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
121794 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
121795 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
121796 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
121797 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
121798 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
121799 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
121800 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
121801 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
121802 +}
121803 +
121804 +int fm_dump_regs(void *h_fm, char *buf, int nn)
121805 +{
121806 + t_Fm *p_Fm = (t_Fm *)h_fm;
121807 + uint8_t i = 0;
121808 + int n = nn;
121809 +
121810 + FM_DMP_SUBTITLE(buf, n, "\n");
121811 +
121812 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
121813 +
121814 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
121815 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
121816 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
121817 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
121818 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
121819 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
121820 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
121821 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
121822 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
121823 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
121824 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
121825 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
121826 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
121827 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
121828 +
121829 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
121830 +
121831 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
121832 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
121833 +
121834 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
121835 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
121836 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
121837 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
121838 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
121839 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
121840 +
121841 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
121842 + for (i = 0; i < 8 ; ++i)
121843 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
121844 +
121845 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
121846 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
121847 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
121848 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
121849 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
121850 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
121851 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
121852 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
121853 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
121854 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
121855 +
121856 + return n;
121857 +}
121858 +
121859 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
121860 +{
121861 + t_Fm *p_Fm = (t_Fm *)h_fm;
121862 + uint8_t i, j = 0;
121863 + int n = nn;
121864 +
121865 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
121866 + tn_s, tn_e);
121867 +
121868 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
121869 +
121870 + mb();
121871 +
121872 + for (j = tn_s; j <= tn_e; j++) {
121873 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
121874 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
121875 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
121876 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
121877 +
121878 + for (i = 0; i < 4 ; ++i)
121879 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
121880 +
121881 + FM_DMP_LN(buf, n, "\n");
121882 +
121883 + }
121884 +
121885 + return n;
121886 +}
121887 +
121888 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
121889 +{
121890 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121891 + int i = 0;
121892 + uint32_t tmp;
121893 + unsigned long i_flg;
121894 + int n = nn;
121895 + u_FmPcdKgIndirectAccessRegs *idac;
121896 + spinlock_t *p_lk;
121897 +
121898 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
121899 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
121900 +
121901 + spin_lock_irqsave(p_lk, i_flg);
121902 +
121903 + /* Read ClsPlan Block Action Regs */
121904 + tmp = (uint32_t)(FM_KG_KGAR_GO |
121905 + FM_KG_KGAR_READ |
121906 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
121907 + DUMMY_PORT_ID |
121908 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
121909 + FM_PCD_KG_KGAR_WSEL_MASK);
121910 +
121911 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
121912 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
121913 + spin_unlock_irqrestore(p_lk, i_flg);
121914 + return nn;
121915 + }
121916 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
121917 + "ClsPlan %d Indirect Access Regs", cpn);
121918 +
121919 + for (i = 0; i < 8; i++)
121920 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
121921 +
121922 + spin_unlock_irqrestore(p_lk, i_flg);
121923 +
121924 + return n;
121925 +}
121926 +
121927 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
121928 +{
121929 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121930 + t_FmPcdPlcrProfileRegs *p_prof_regs;
121931 + t_FmPcdPlcrRegs *p_plcr_regs;
121932 + t_FmPcdPlcr *p_plcr;
121933 + uint32_t tmp;
121934 + unsigned long i_flg;
121935 + int n = nn;
121936 + int toc = 10;
121937 + spinlock_t *p_lk;
121938 +
121939 + p_plcr = p_pcd->p_FmPcdPlcr;
121940 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
121941 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
121942 +
121943 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
121944 +
121945 + FM_DMP_SUBTITLE(buf, n, "\n");
121946 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
121947 +
121948 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
121949 + FM_PCD_PLCR_PAR_R |
121950 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
121951 + FM_PCD_PLCR_PAR_PWSEL_MASK);
121952 +
121953 + spin_lock_irqsave(p_lk, i_flg);
121954 +
121955 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
121956 +
121957 + mb();
121958 +
121959 + /* wait for the porfile regs to be present */
121960 + do {
121961 + --toc;
121962 + udelay(10);
121963 + if (!toc) {
121964 + /* looks like PLCR_PAR_GO refuses to clear */
121965 + spin_unlock_irqrestore(p_lk, i_flg);
121966 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
121967 + FM_DMP_LN(buf, n, " check profile init process\n");
121968 + return n;
121969 + }
121970 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
121971 +
121972 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
121973 +
121974 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
121975 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
121976 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
121977 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
121978 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
121979 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
121980 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
121981 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
121982 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
121983 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
121984 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
121985 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
121986 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
121987 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
121988 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
121989 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
121990 +
121991 + spin_unlock_irqrestore(p_lk, i_flg);
121992 +
121993 + return n;
121994 +}
121995 +
121996 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
121997 +{
121998 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
121999 + uint32_t tmp_ar;
122000 + unsigned long i_flg;
122001 + int i, n = nn;
122002 + spinlock_t *p_lk;
122003 + u_FmPcdKgIndirectAccessRegs *idac;
122004 +
122005 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
122006 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
122007 +
122008 + spin_lock_irqsave(p_lk, i_flg);
122009 +
122010 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
122011 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
122012 + FM_DMP_LN(buf, nn,
122013 + "Keygen scheme access violation or no such scheme");
122014 + spin_unlock_irqrestore(p_lk, i_flg);
122015 + return nn;
122016 + }
122017 +
122018 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
122019 + "Scheme %d Indirect Access Regs", scnum);
122020 +
122021 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
122022 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
122023 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
122024 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
122025 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
122026 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
122027 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
122028 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
122029 +
122030 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
122031 +
122032 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
122033 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
122034 +
122035 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
122036 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
122037 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
122038 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
122039 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
122040 +
122041 + FM_DMP_SUBTITLE(buf, n, "\n");
122042 +
122043 + spin_unlock_irqrestore(p_lk, i_flg);
122044 +
122045 + return n;
122046 +}
122047 +
122048 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
122049 +{
122050 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122051 + int i = 0;
122052 + uint8_t prt_id = 0;
122053 + uint32_t tmp_ar;
122054 + unsigned long i_flg;
122055 + int n = nn;
122056 + u_FmPcdKgIndirectAccessRegs *idac;
122057 + t_FmPcdKg *p_kg;
122058 + spinlock_t *p_lk;
122059 +
122060 + p_kg = p_pcd->p_FmPcdKg;
122061 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
122062 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
122063 +
122064 + spin_lock_irqsave(p_lk, i_flg);
122065 +
122066 + FM_DMP_SUBTITLE(buf, n, "\n");
122067 +
122068 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
122069 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
122070 +
122071 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
122072 +
122073 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
122074 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
122075 + spin_unlock_irqrestore(p_lk, i_flg);
122076 + return nn;
122077 + }
122078 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
122079 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
122080 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
122081 + }
122082 +
122083 + FM_DMP_SUBTITLE(buf, n, "\n");
122084 +
122085 + spin_unlock_irqrestore(p_lk, i_flg);
122086 +
122087 + return n;
122088 +}
122089 +
122090 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
122091 +{
122092 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122093 + int n = nn;
122094 +
122095 + FM_DMP_SUBTITLE(buf, n, "\n");
122096 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
122097 + "FmPcdKgRegs Regs");
122098 +
122099 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
122100 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
122101 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
122102 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
122103 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
122104 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
122105 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
122106 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
122107 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
122108 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
122109 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
122110 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
122111 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
122112 +
122113 + FM_DMP_SUBTITLE(buf, n, "\n");
122114 +
122115 + return n;
122116 +}
122117 +
122118 +
122119 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
122120 +{
122121 + t_Fm *p_fm = (t_Fm *)h_fm;
122122 + uint8_t i;
122123 + int n = nn;
122124 +
122125 + FM_DMP_SUBTITLE(buf, n, "\n");
122126 +
122127 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
122128 +
122129 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
122130 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
122131 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
122132 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
122133 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
122134 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
122135 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
122136 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
122137 +
122138 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
122139 + for (i = 0; i < 4; ++i)
122140 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
122141 +
122142 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
122143 + for (i = 0; i < 4; ++i)
122144 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
122145 +
122146 + FM_DMP_SUBTITLE(buf, n, "\n");
122147 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
122148 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
122149 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
122150 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
122151 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
122152 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
122153 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
122154 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
122155 +
122156 + FM_DMP_SUBTITLE(buf, n, "\n");
122157 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
122158 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
122159 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
122160 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
122161 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
122162 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
122163 +
122164 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
122165 + for (i = 0; i < 4; ++i)
122166 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
122167 +
122168 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
122169 + for (i = 0; i < 64; ++i)
122170 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
122171 +
122172 + return n;
122173 +}
122174 +
122175 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
122176 +{
122177 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122178 + int n = nn;
122179 +
122180 + FM_DMP_SUBTITLE(buf, n, "\n");
122181 +
122182 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
122183 + "FM-PCD parser regs");
122184 +
122185 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
122186 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
122187 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
122188 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
122189 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
122190 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
122191 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
122192 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
122193 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
122194 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
122195 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
122196 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
122197 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
122198 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
122199 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
122200 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
122201 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
122202 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
122203 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
122204 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
122205 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
122206 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
122207 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
122208 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
122209 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
122210 +
122211 + return n;
122212 +}
122213 +
122214 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
122215 +{
122216 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122217 + int i = 0;
122218 + int n = nn;
122219 +
122220 + FM_DMP_SUBTITLE(buf, n, "\n");
122221 +
122222 + FM_DMP_TITLE(buf, n,
122223 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
122224 + "FM policer regs");
122225 +
122226 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
122227 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
122228 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
122229 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
122230 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
122231 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
122232 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
122233 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
122234 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
122235 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
122236 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
122237 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
122238 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
122239 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
122240 +
122241 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
122242 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
122243 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
122244 +
122245 + FM_DMP_TITLE(buf, n,
122246 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
122247 + "fmpl_pmr");
122248 +
122249 + for (i = 0; i < 63; ++i)
122250 + FM_DMP_MEM_32(buf, n,
122251 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
122252 +
122253 + return n;
122254 +}
122255 +
122256 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
122257 +{
122258 + t_Fm *p_fm = (t_Fm *)h_fm;
122259 +
122260 + /* When applicable (when there is an "enable counters" bit),
122261 + check that counters are enabled */
122262 +
122263 + switch (cnt_e) {
122264 + case (e_FM_COUNTERS_DEQ_1):
122265 + case (e_FM_COUNTERS_DEQ_2):
122266 + case (e_FM_COUNTERS_DEQ_3):
122267 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
122268 + return -EINVAL; /* counter not available */
122269 +
122270 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
122271 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
122272 + case (e_FM_COUNTERS_DEQ_0):
122273 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
122274 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
122275 + case (e_FM_COUNTERS_DEQ_FROM_FD):
122276 + case (e_FM_COUNTERS_DEQ_CONFIRM):
122277 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
122278 + QMI_CFG_EN_COUNTERS))
122279 + return -EINVAL; /* Requested counter not available */
122280 + break;
122281 + default:
122282 + break;
122283 + }
122284 +
122285 + switch (cnt_e) {
122286 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
122287 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
122288 + return 0;
122289 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
122290 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
122291 + return 0;
122292 + case (e_FM_COUNTERS_DEQ_0):
122293 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
122294 + return 0;
122295 + case (e_FM_COUNTERS_DEQ_1):
122296 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
122297 + return 0;
122298 + case (e_FM_COUNTERS_DEQ_2):
122299 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
122300 + return 0;
122301 + case (e_FM_COUNTERS_DEQ_3):
122302 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
122303 + return 0;
122304 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
122305 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
122306 + return 0;
122307 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
122308 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
122309 + return 0;
122310 + case (e_FM_COUNTERS_DEQ_FROM_FD):
122311 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
122312 + return 0;
122313 + case (e_FM_COUNTERS_DEQ_CONFIRM):
122314 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
122315 + return 0;
122316 + }
122317 + /* should never get here */
122318 + return -EINVAL; /* counter not available */
122319 +}
122320 --- /dev/null
122321 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
122322 @@ -0,0 +1,136 @@
122323 +/*
122324 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122325 + *
122326 + * Redistribution and use in source and binary forms, with or without
122327 + * modification, are permitted provided that the following conditions are met:
122328 + * * Redistributions of source code must retain the above copyright
122329 + * notice, this list of conditions and the following disclaimer.
122330 + * * Redistributions in binary form must reproduce the above copyright
122331 + * notice, this list of conditions and the following disclaimer in the
122332 + * documentation and/or other materials provided with the distribution.
122333 + * * Neither the name of Freescale Semiconductor nor the
122334 + * names of its contributors may be used to endorse or promote products
122335 + * derived from this software without specific prior written permission.
122336 + *
122337 + *
122338 + * ALTERNATIVELY, this software may be distributed under the terms of the
122339 + * GNU General Public License ("GPL") as published by the Free Software
122340 + * Foundation, either version 2 of that License or (at your option) any
122341 + * later version.
122342 + *
122343 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122344 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122345 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122346 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122347 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122348 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122349 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122350 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122351 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122352 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122353 + */
122354 +
122355 +
122356 +#ifndef LNXWRP_SYSFS_FM_H_
122357 +#define LNXWRP_SYSFS_FM_H_
122358 +
122359 +#include "lnxwrp_sysfs.h"
122360 +
122361 +int fm_sysfs_create(struct device *dev);
122362 +void fm_sysfs_destroy(struct device *dev);
122363 +int fm_dump_regs(void *h_dev, char *buf, int nn);
122364 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
122365 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
122366 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
122367 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
122368 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
122369 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
122370 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
122371 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
122372 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
122373 +
122374 +#define FM_DMP_PGSZ_ERR { \
122375 + snprintf(&buf[PAGE_SIZE - 80], 70, \
122376 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
122377 + n = PAGE_SIZE - 2; \
122378 + }
122379 +
122380 +#define FM_DMP_LN(buf, n, ...) \
122381 + do { \
122382 + int k, m = n; \
122383 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
122384 + if (k < 0 || m > PAGE_SIZE - 90) \
122385 + FM_DMP_PGSZ_ERR \
122386 + n = m; \
122387 + } while (0)
122388 +
122389 +#define FM_DMP_TITLE(buf, n, addr, ...) \
122390 + do { \
122391 + int k, m = n; \
122392 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
122393 + if (k < 0 || m > PAGE_SIZE - 90) \
122394 + FM_DMP_PGSZ_ERR \
122395 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
122396 + if (k < 0 || m > PAGE_SIZE - 90) \
122397 + FM_DMP_PGSZ_ERR \
122398 + if (addr) { \
122399 + phys_addr_t pa; \
122400 + pa = virt_to_phys(addr); \
122401 + m += k = \
122402 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
122403 + (long unsigned int)(pa)); \
122404 + if (k < 0 || m > PAGE_SIZE - 90) \
122405 + FM_DMP_PGSZ_ERR \
122406 + } \
122407 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
122408 + "\n----------------------------------------\n\n"); \
122409 + if (k < 0 || m > PAGE_SIZE - 90) \
122410 + FM_DMP_PGSZ_ERR \
122411 + n = m; \
122412 + } while (0)
122413 +
122414 +#define FM_DMP_SUBTITLE(buf, n, ...) \
122415 + do { \
122416 + int k, m = n; \
122417 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
122418 + if (k < 0 || m > PAGE_SIZE - 90) \
122419 + FM_DMP_PGSZ_ERR \
122420 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
122421 + if (k < 0 || m > PAGE_SIZE - 90) \
122422 + FM_DMP_PGSZ_ERR \
122423 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
122424 + if (k < 0 || m > PAGE_SIZE - 90) \
122425 + FM_DMP_PGSZ_ERR \
122426 + n = m; \
122427 + } while (0)
122428 +
122429 +#define FM_DMP_MEM_32(buf, n, addr) \
122430 + { \
122431 + uint32_t val; \
122432 + phys_addr_t pa; \
122433 + int k, m = n; \
122434 + pa = virt_to_phys(addr); \
122435 + val = ioread32be((addr)); \
122436 + do { \
122437 + m += k = snprintf(&buf[m], \
122438 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
122439 + pa, val); \
122440 + if (k < 0 || m > PAGE_SIZE - 90) \
122441 + FM_DMP_PGSZ_ERR \
122442 + n += k; \
122443 + } while (0) ;\
122444 + }
122445 +
122446 +#define FM_DMP_V32(buf, n, st, phrase) \
122447 + do { \
122448 + int k, m = n; \
122449 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
122450 + k = snprintf(&buf[m], PAGE_SIZE - m, \
122451 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
122452 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
122453 + if (k < 0 || m > PAGE_SIZE - 90) \
122454 + FM_DMP_PGSZ_ERR \
122455 + n += k; \
122456 + } while (0)
122457 +
122458 +#endif /* LNXWRP_SYSFS_FM_H_ */
122459 --- /dev/null
122460 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
122461 @@ -0,0 +1,1268 @@
122462 +/*
122463 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122464 + *
122465 + * Redistribution and use in source and binary forms, with or without
122466 + * modification, are permitted provided that the following conditions are met:
122467 + * * Redistributions of source code must retain the above copyright
122468 + * notice, this list of conditions and the following disclaimer.
122469 + * * Redistributions in binary form must reproduce the above copyright
122470 + * notice, this list of conditions and the following disclaimer in the
122471 + * documentation and/or other materials provided with the distribution.
122472 + * * Neither the name of Freescale Semiconductor nor the
122473 + * names of its contributors may be used to endorse or promote products
122474 + * derived from this software without specific prior written permission.
122475 + *
122476 + *
122477 + * ALTERNATIVELY, this software may be distributed under the terms of the
122478 + * GNU General Public License ("GPL") as published by the Free Software
122479 + * Foundation, either version 2 of that License or (at your option) any
122480 + * later version.
122481 + *
122482 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122483 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122484 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122485 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122486 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122487 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122488 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122489 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122490 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122491 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122492 + */
122493 +
122494 +#include "lnxwrp_sysfs.h"
122495 +#include "lnxwrp_fm.h"
122496 +#include "debug_ext.h"
122497 +#include "lnxwrp_sysfs_fm_port.h"
122498 +#include "lnxwrp_sysfs_fm.h"
122499 +
122500 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
122501 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
122502 +
122503 +#if defined(__ERR_MODULE__)
122504 +#undef __ERR_MODULE__
122505 +#endif
122506 +
122507 +#include "../../sdk_fman/Peripherals/FM/fm.h"
122508 +
122509 +static const struct sysfs_stats_t portSysfsStats[] = {
122510 + /* RX/TX/OH common statistics */
122511 + {
122512 + .stat_name = "port_frame",
122513 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
122514 + },
122515 + {
122516 + .stat_name = "port_discard_frame",
122517 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
122518 + },
122519 + {
122520 + .stat_name = "port_dealloc_buf",
122521 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
122522 + },
122523 + {
122524 + .stat_name = "port_enq_total",
122525 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
122526 + },
122527 + /* TX/OH */
122528 + {
122529 + .stat_name = "port_length_err",
122530 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
122531 + },
122532 + {
122533 + .stat_name = "port_unsupprted_format",
122534 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
122535 + },
122536 + {
122537 + .stat_name = "port_deq_total",
122538 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
122539 + },
122540 + {
122541 + .stat_name = "port_deq_from_default",
122542 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
122543 + },
122544 + {
122545 + .stat_name = "port_deq_confirm",
122546 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
122547 + },
122548 + /* RX/OH */
122549 + {
122550 + .stat_name = "port_rx_bad_frame",
122551 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
122552 + },
122553 + {
122554 + .stat_name = "port_rx_large_frame",
122555 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
122556 + },
122557 + {
122558 + .stat_name = "port_rx_out_of_buffers_discard",
122559 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
122560 + },
122561 + {
122562 + .stat_name = "port_rx_filter_frame",
122563 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
122564 + },
122565 + /* TODO: Particular statistics for OH ports */
122566 + {}
122567 +};
122568 +
122569 +static ssize_t show_fm_port_stats(struct device *dev,
122570 + struct device_attribute *attr, char *buf)
122571 +{
122572 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122573 + t_LnxWrpFmDev *p_LnxWrpFmDev;
122574 + unsigned long flags;
122575 + int n = 0;
122576 + uint8_t counter = 0;
122577 +
122578 + if (attr == NULL || buf == NULL || dev == NULL)
122579 + return -EINVAL;
122580 +
122581 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122582 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122583 + return -EINVAL;
122584 +
122585 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
122586 + if (WARN_ON(p_LnxWrpFmDev == NULL))
122587 + return -EINVAL;
122588 +
122589 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
122590 + return -EIO;
122591 +
122592 + if (!p_LnxWrpFmPortDev->h_Dev) {
122593 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122594 + return n;
122595 + }
122596 +
122597 + counter = fm_find_statistic_counter_by_name(
122598 + attr->attr.name,
122599 + portSysfsStats, NULL);
122600 +
122601 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
122602 + uint32_t fmRev = 0;
122603 + fmRev = 0xffff &
122604 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
122605 + 0x000c30c4));
122606 +
122607 + if (fmRev == 0x0100) {
122608 + local_irq_save(flags);
122609 + n = snprintf(buf, PAGE_SIZE,
122610 + "counter not available for revision 1\n");
122611 + local_irq_restore(flags);
122612 + }
122613 + return n;
122614 + }
122615 +
122616 + local_irq_save(flags);
122617 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
122618 + p_LnxWrpFmPortDev->name,
122619 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
122620 + (e_FmPortCounters) counter));
122621 + local_irq_restore(flags);
122622 +
122623 + return n;
122624 +}
122625 +
122626 +/* FM PORT RX/TX/OH statistics */
122627 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
122628 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
122629 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
122630 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
122631 +/* FM PORT TX/OH statistics */
122632 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
122633 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
122634 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
122635 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
122636 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
122637 +/* FM PORT RX/OH statistics */
122638 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
122639 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
122640 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
122641 + show_fm_port_stats, NULL);
122642 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
122643 +
122644 +/* FM PORT TX statistics */
122645 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
122646 + &dev_attr_port_frame.attr,
122647 + &dev_attr_port_discard_frame.attr,
122648 + &dev_attr_port_dealloc_buf.attr,
122649 + &dev_attr_port_enq_total.attr,
122650 + &dev_attr_port_length_err.attr,
122651 + &dev_attr_port_unsupprted_format.attr,
122652 + &dev_attr_port_deq_total.attr,
122653 + &dev_attr_port_deq_from_default.attr,
122654 + &dev_attr_port_deq_confirm.attr,
122655 + NULL
122656 +};
122657 +
122658 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
122659 + .name = "statistics",
122660 + .attrs = fm_tx_port_dev_stats_attributes
122661 +};
122662 +
122663 +/* FM PORT RX statistics */
122664 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
122665 + &dev_attr_port_frame.attr,
122666 + &dev_attr_port_discard_frame.attr,
122667 + &dev_attr_port_dealloc_buf.attr,
122668 + &dev_attr_port_enq_total.attr,
122669 + &dev_attr_port_rx_bad_frame.attr,
122670 + &dev_attr_port_rx_large_frame.attr,
122671 + &dev_attr_port_rx_out_of_buffers_discard.attr,
122672 + &dev_attr_port_rx_filter_frame.attr,
122673 + NULL
122674 +};
122675 +
122676 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
122677 + .name = "statistics",
122678 + .attrs = fm_rx_port_dev_stats_attributes
122679 +};
122680 +
122681 +/* TODO: add particular OH ports statistics */
122682 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
122683 + &dev_attr_port_frame.attr,
122684 + &dev_attr_port_discard_frame.attr,
122685 + &dev_attr_port_dealloc_buf.attr,
122686 + &dev_attr_port_enq_total.attr,
122687 + /*TX*/ &dev_attr_port_length_err.attr,
122688 + &dev_attr_port_unsupprted_format.attr,
122689 + &dev_attr_port_deq_total.attr,
122690 + &dev_attr_port_deq_from_default.attr,
122691 + &dev_attr_port_deq_confirm.attr,
122692 + /* &dev_attr_port_rx_bad_frame.attr, */
122693 + /* &dev_attr_port_rx_large_frame.attr, */
122694 + &dev_attr_port_rx_out_of_buffers_discard.attr,
122695 + /*&dev_attr_port_rx_filter_frame.attr, */
122696 + NULL
122697 +};
122698 +
122699 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
122700 + .name = "statistics",
122701 + .attrs = fm_oh_port_dev_stats_attributes
122702 +};
122703 +
122704 +static ssize_t show_fm_port_regs(struct device *dev,
122705 + struct device_attribute *attr, char *buf)
122706 +{
122707 + unsigned long flags;
122708 + unsigned n = 0;
122709 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122710 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122711 +#endif
122712 + if (attr == NULL || buf == NULL || dev == NULL)
122713 + return -EINVAL;
122714 +
122715 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122716 + p_LnxWrpFmPortDev =
122717 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122718 +
122719 +
122720 + local_irq_save(flags);
122721 +
122722 + if (!p_LnxWrpFmPortDev->h_Dev) {
122723 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122724 + return n;
122725 + } else {
122726 + n = snprintf(buf, PAGE_SIZE,
122727 + "FM port driver registers dump.\n");
122728 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
122729 + }
122730 +
122731 + local_irq_restore(flags);
122732 +
122733 + return n;
122734 +#else
122735 +
122736 + local_irq_save(flags);
122737 + n = snprintf(buf, PAGE_SIZE,
122738 + "Debug level is too low to dump registers!!!\n");
122739 + local_irq_restore(flags);
122740 +
122741 + return n;
122742 +#endif
122743 +}
122744 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
122745 +{
122746 + t_FmPort *p_FmPort;
122747 + t_Fm *p_Fm;
122748 + uint8_t hardwarePortId;
122749 + uint32_t *param_page;
122750 + t_ArCommonDesc *ArCommonDescPtr;
122751 + uint32_t *mem;
122752 + int i, n = nn;
122753 +
122754 + p_FmPort = (t_FmPort *)h_dev;
122755 + hardwarePortId = p_FmPort->hardwarePortId;
122756 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
122757 +
122758 + if (!FM_PORT_IsInDsar(p_FmPort))
122759 + {
122760 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
122761 + hardwarePortId);
122762 + return n;
122763 + }
122764 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
122765 + FM_DMP_LN(buf, n, "========================\n");
122766 +
122767 + /* do I need request_mem_region here? */
122768 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
122769 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
122770 + mem = (uint32_t*)ArCommonDescPtr;
122771 + for (i = 0; i < 300; i+=4)
122772 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
122773 + iounmap(ArCommonDescPtr);
122774 + iounmap(param_page);
122775 + return n;
122776 +}
122777 +
122778 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
122779 +{
122780 + t_FmPort *p_FmPort;
122781 + t_Fm *p_Fm;
122782 + uint8_t hardwarePortId;
122783 + uint32_t *param_page;
122784 + t_ArCommonDesc *ArCommonDescPtr;
122785 + int i, n = nn;
122786 +
122787 + p_FmPort = (t_FmPort *)h_dev;
122788 + hardwarePortId = p_FmPort->hardwarePortId;
122789 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
122790 +
122791 + if (!FM_PORT_IsInDsar(p_FmPort))
122792 + {
122793 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
122794 + hardwarePortId);
122795 + return n;
122796 + }
122797 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
122798 + FM_DMP_LN(buf, n, "========================\n");
122799 +
122800 + /* do I need request_mem_region here? */
122801 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
122802 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
122803 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
122804 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
122805 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
122806 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
122807 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
122808 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
122809 + ArCommonDescPtr->macStationAddr[5]);
122810 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
122811 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
122812 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
122813 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
122814 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
122815 + if (ArCommonDescPtr->p_ArStats)
122816 + {
122817 + t_ArStatistics *arStatistics = (t_ArStatistics*)
122818 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
122819 + p_FmPort->fmMuramPhysBaseAddr,
122820 + sizeof (t_ArStatistics));
122821 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
122822 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
122823 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
122824 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
122825 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
122826 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
122827 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
122828 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
122829 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
122830 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
122831 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
122832 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
122833 +
122834 + iounmap(arStatistics);
122835 + }
122836 + if (ArCommonDescPtr->p_ArpDescriptor)
122837 + {
122838 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
122839 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
122840 + p_FmPort->fmMuramPhysBaseAddr,
122841 + sizeof (t_DsarArpDescriptor));
122842 + FM_DMP_LN(buf, n, "\nARP\n");
122843 + FM_DMP_LN(buf, n, "===\n");
122844 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
122845 + if (ArpDescriptor->numOfBindings)
122846 + {
122847 + char ip_str[100];
122848 + t_DsarArpBindingEntry* bindings = ioremap(
122849 + ioread32be(&ArpDescriptor->p_Bindings) +
122850 + p_FmPort->fmMuramPhysBaseAddr,
122851 + ArpDescriptor->numOfBindings *
122852 + sizeof(t_DsarArpBindingEntry));
122853 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
122854 + FM_DMP_LN(buf, n, " ip vlan id\n");
122855 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
122856 + {
122857 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
122858 + ip_addr[0], ip_addr[1],
122859 + ip_addr[2], ip_addr[3]);
122860 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
122861 + ip_str, bindings->vlanId);
122862 + }
122863 + iounmap(bindings);
122864 + }
122865 + if (ArpDescriptor->p_Statistics)
122866 + {
122867 + t_DsarArpStatistics* arpStats = ioremap(
122868 + ioread32be(&ArpDescriptor->p_Statistics) +
122869 + p_FmPort->fmMuramPhysBaseAddr,
122870 + sizeof(t_DsarArpStatistics));
122871 + FM_DMP_LN(buf, n, "statistics\n");
122872 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
122873 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
122874 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
122875 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
122876 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
122877 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
122878 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
122879 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
122880 + iounmap(arpStats);
122881 + }
122882 +
122883 + iounmap(ArpDescriptor);
122884 + }
122885 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
122886 + {
122887 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
122888 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
122889 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
122890 + p_FmPort->fmMuramPhysBaseAddr,
122891 + sizeof (t_DsarIcmpV4Descriptor));
122892 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
122893 + FM_DMP_LN(buf, n, "===========\n");
122894 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
122895 + if (ICMPV4Descriptor->numOfBindings)
122896 + {
122897 + char ip_str[100];
122898 + t_DsarArpBindingEntry* bindings = ioremap(
122899 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
122900 + p_FmPort->fmMuramPhysBaseAddr,
122901 + ICMPV4Descriptor->numOfBindings *
122902 + sizeof(t_DsarArpBindingEntry));
122903 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
122904 + FM_DMP_LN(buf, n, " ip vlan id\n");
122905 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
122906 + {
122907 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
122908 + ip_addr[0], ip_addr[1],
122909 + ip_addr[2], ip_addr[3]);
122910 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
122911 + ip_str, bindings->vlanId);
122912 + }
122913 + iounmap(bindings);
122914 + }
122915 + if (ICMPV4Descriptor->p_Statistics)
122916 + {
122917 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
122918 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
122919 + p_FmPort->fmMuramPhysBaseAddr,
122920 + sizeof(t_DsarIcmpV4Statistics));
122921 + FM_DMP_LN(buf, n, "statistics\n");
122922 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
122923 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
122924 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
122925 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
122926 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
122927 + iounmap(icmpv4Stats);
122928 + }
122929 + iounmap(ICMPV4Descriptor);
122930 + }
122931 + if (ArCommonDescPtr->p_NdDescriptor)
122932 + {
122933 + t_DsarNdDescriptor *NDDescriptor =
122934 + (t_DsarNdDescriptor*)ioremap(ioread32be(
122935 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
122936 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
122937 + FM_DMP_LN(buf, n, "\nNDP\n");
122938 + FM_DMP_LN(buf, n, "===\n");
122939 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
122940 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
122941 + if (NDDescriptor->numOfBindings)
122942 + {
122943 + char ip_str[100];
122944 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
122945 + ioread32be(&NDDescriptor->p_Bindings) +
122946 + p_FmPort->fmMuramPhysBaseAddr,
122947 + NDDescriptor->numOfBindings *
122948 + sizeof(t_DsarIcmpV6BindingEntry));
122949 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
122950 + FM_DMP_LN(buf, n, " ip vlan id\n");
122951 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
122952 + {
122953 + n += snprintf(ip_str, 100,
122954 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
122955 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
122956 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
122957 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
122958 + }
122959 + iounmap(bindings);
122960 + }
122961 + if (NDDescriptor->p_Statistics)
122962 + {
122963 + t_NdStatistics* ndStats = ioremap(
122964 + ioread32be(&NDDescriptor->p_Statistics) +
122965 + p_FmPort->fmMuramPhysBaseAddr,
122966 + sizeof(t_NdStatistics));
122967 + FM_DMP_LN(buf, n, "statistics\n");
122968 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
122969 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
122970 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
122971 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
122972 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
122973 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
122974 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
122975 + iounmap(ndStats);
122976 + }
122977 + iounmap(NDDescriptor);
122978 + }
122979 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
122980 + {
122981 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
122982 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
122983 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
122984 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
122985 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
122986 + FM_DMP_LN(buf, n, "===========\n");
122987 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
122988 + if (ICMPV6Descriptor->numOfBindings)
122989 + {
122990 + char ip_str[100];
122991 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
122992 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
122993 + p_FmPort->fmMuramPhysBaseAddr,
122994 + ICMPV6Descriptor->numOfBindings *
122995 + sizeof(t_DsarIcmpV6BindingEntry));
122996 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
122997 + FM_DMP_LN(buf, n, " ip vlan id\n");
122998 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
122999 + {
123000 + n += snprintf(ip_str, 100,
123001 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
123002 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
123003 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
123004 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
123005 + }
123006 + iounmap(bindings);
123007 + }
123008 + if (ICMPV6Descriptor->p_Statistics)
123009 + {
123010 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
123011 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
123012 + p_FmPort->fmMuramPhysBaseAddr,
123013 + sizeof(t_DsarIcmpV6Statistics));
123014 + FM_DMP_LN(buf, n, "statistics\n");
123015 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
123016 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
123017 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
123018 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
123019 + iounmap(icmpv6Stats);
123020 + }
123021 + iounmap(ICMPV6Descriptor);
123022 + }
123023 + if (ArCommonDescPtr->p_SnmpDescriptor)
123024 + {
123025 + t_DsarSnmpDescriptor *SnmpDescriptor =
123026 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
123027 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
123028 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
123029 + FM_DMP_LN(buf, n, "\nSNMP\n");
123030 + FM_DMP_LN(buf, n, "===========\n");
123031 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
123032 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
123033 + if (SnmpDescriptor->numOfIpv4Addresses)
123034 + {
123035 + char ip_str[100];
123036 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
123037 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
123038 + p_FmPort->fmMuramPhysBaseAddr,
123039 + SnmpDescriptor->numOfIpv4Addresses *
123040 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
123041 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
123042 + FM_DMP_LN(buf, n, " ip vlan id\n");
123043 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
123044 + {
123045 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
123046 + ip_addr[0], ip_addr[1],
123047 + ip_addr[2], ip_addr[3]);
123048 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
123049 + }
123050 + iounmap(addrs);
123051 + }
123052 + if (SnmpDescriptor->p_Statistics)
123053 + {
123054 + t_DsarSnmpStatistics* snmpStats = ioremap(
123055 + ioread32be(&SnmpDescriptor->p_Statistics) +
123056 + p_FmPort->fmMuramPhysBaseAddr,
123057 + sizeof(t_DsarSnmpStatistics));
123058 + FM_DMP_LN(buf, n, "statistics\n");
123059 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
123060 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
123061 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
123062 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
123063 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
123064 + iounmap(snmpStats);
123065 + }
123066 + iounmap(SnmpDescriptor);
123067 + }
123068 + iounmap(ArCommonDescPtr);
123069 + iounmap(param_page);
123070 + return n;
123071 +}
123072 +
123073 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
123074 + struct device_attribute *attr, char *buf)
123075 +{
123076 + unsigned long flags;
123077 + unsigned n = 0;
123078 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123079 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123080 +#endif
123081 + if (attr == NULL || buf == NULL || dev == NULL)
123082 + return -EINVAL;
123083 +
123084 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123085 + p_LnxWrpFmPortDev =
123086 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123087 +
123088 + local_irq_save(flags);
123089 +
123090 + if (!p_LnxWrpFmPortDev->h_Dev) {
123091 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123092 + return n;
123093 + } else {
123094 + n = snprintf(buf, PAGE_SIZE,
123095 + "FM port driver registers dump.\n");
123096 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
123097 + }
123098 +
123099 + local_irq_restore(flags);
123100 +
123101 + return n;
123102 +#else
123103 +
123104 + local_irq_save(flags);
123105 + n = snprintf(buf, PAGE_SIZE,
123106 + "Debug level is too low to dump registers!!!\n");
123107 + local_irq_restore(flags);
123108 +
123109 + return n;
123110 +#endif
123111 +}
123112 +
123113 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
123114 + struct device_attribute *attr, char *buf)
123115 +{
123116 + unsigned long flags;
123117 + unsigned n = 0;
123118 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123119 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123120 +#endif
123121 + if (attr == NULL || buf == NULL || dev == NULL)
123122 + return -EINVAL;
123123 +
123124 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123125 + p_LnxWrpFmPortDev =
123126 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123127 +
123128 + local_irq_save(flags);
123129 +
123130 + if (!p_LnxWrpFmPortDev->h_Dev) {
123131 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123132 + return n;
123133 + } else {
123134 + n = snprintf(buf, PAGE_SIZE,
123135 + "FM port driver registers dump.\n");
123136 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
123137 + }
123138 +
123139 + local_irq_restore(flags);
123140 +
123141 + return n;
123142 +#else
123143 +
123144 + local_irq_save(flags);
123145 + n = snprintf(buf, PAGE_SIZE,
123146 + "Debug level is too low to dump registers!!!\n");
123147 + local_irq_restore(flags);
123148 +
123149 + return n;
123150 +#endif
123151 +}
123152 +
123153 +#if (DPAA_VERSION >= 11)
123154 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
123155 + struct device_attribute *attr, char *buf)
123156 +{
123157 + unsigned long flags;
123158 + unsigned n = 0;
123159 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123160 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123161 +#endif
123162 +
123163 + if (attr == NULL || buf == NULL || dev == NULL)
123164 + return -EINVAL;
123165 +
123166 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123167 + p_LnxWrpFmPortDev =
123168 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123169 +
123170 + local_irq_save(flags);
123171 +
123172 + if (!p_LnxWrpFmPortDev->h_Dev) {
123173 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123174 + return n;
123175 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
123176 + == NULL) {
123177 + n = snprintf(buf, PAGE_SIZE,
123178 + "\tPort: FMan-controller params page not set\n");
123179 + return n;
123180 + } else {
123181 + n = snprintf(buf, PAGE_SIZE,
123182 + "Counter for fragmented pkt with IP header options\n");
123183 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
123184 + }
123185 +
123186 + local_irq_restore(flags);
123187 +
123188 + return n;
123189 +#else
123190 +
123191 + local_irq_save(flags);
123192 + n = snprintf(buf, PAGE_SIZE,
123193 + "Debug level is too low to dump registers!!!\n");
123194 + local_irq_restore(flags);
123195 +
123196 + return n;
123197 +#endif
123198 +}
123199 +
123200 +#endif
123201 +
123202 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
123203 + struct device_attribute *attr, char *buf)
123204 +{
123205 + unsigned long flags;
123206 + unsigned n = 0;
123207 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123208 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123209 +#endif
123210 +
123211 + if (attr == NULL || buf == NULL || dev == NULL)
123212 + return -EINVAL;
123213 +
123214 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123215 + p_LnxWrpFmPortDev =
123216 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123217 +
123218 + local_irq_save(flags);
123219 +
123220 + if (!p_LnxWrpFmPortDev->h_Dev) {
123221 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123222 + return n;
123223 + } else {
123224 + n = snprintf(buf, PAGE_SIZE,
123225 + "FM port driver registers dump.\n");
123226 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
123227 + }
123228 +
123229 + local_irq_restore(flags);
123230 +
123231 + return n;
123232 +#else
123233 +
123234 + local_irq_save(flags);
123235 + n = snprintf(buf, PAGE_SIZE,
123236 + "Debug level is too low to dump registers!!!\n");
123237 + local_irq_restore(flags);
123238 +
123239 + return n;
123240 +#endif
123241 +}
123242 +
123243 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
123244 + struct device_attribute *attr, char *buf)
123245 +{
123246 + unsigned long flags;
123247 + unsigned n = 0;
123248 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123249 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123250 +#endif
123251 +
123252 + if (attr == NULL || buf == NULL || dev == NULL)
123253 + return -EINVAL;
123254 +
123255 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123256 + p_LnxWrpFmPortDev =
123257 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123258 +
123259 + local_irq_save(flags);
123260 +
123261 + if (!p_LnxWrpFmPortDev->h_Dev) {
123262 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123263 + return n;
123264 + } else {
123265 + n = snprintf(buf, PAGE_SIZE,
123266 + "FM port driver registers dump.\n");
123267 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
123268 + }
123269 +
123270 + local_irq_restore(flags);
123271 +
123272 + return n;
123273 +#else
123274 +
123275 + local_irq_save(flags);
123276 + n = snprintf(buf, PAGE_SIZE,
123277 + "Debug level is too low to dump registers!!!\n");
123278 + local_irq_restore(flags);
123279 +
123280 + return n;
123281 +#endif
123282 +}
123283 +
123284 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
123285 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
123286 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
123287 +#if (DPAA_VERSION >= 11)
123288 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
123289 +#endif
123290 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
123291 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
123292 +
123293 +int fm_port_sysfs_create(struct device *dev)
123294 +{
123295 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123296 +
123297 + if (dev == NULL)
123298 + return -EINVAL;
123299 +
123300 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123301 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
123302 + return -EINVAL;
123303 +
123304 + /* store to remove them when module is disabled */
123305 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
123306 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
123307 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
123308 +#if (DPAA_VERSION >= 11)
123309 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
123310 +#endif
123311 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
123312 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
123313 + /* Registers dump entry - in future will be moved to debugfs */
123314 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
123315 + return -EIO;
123316 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
123317 + return -EIO;
123318 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
123319 + return -EIO;
123320 +#if (DPAA_VERSION >= 11)
123321 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
123322 + return -EIO;
123323 +#endif
123324 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
123325 + return -EIO;
123326 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
123327 + return -EIO;
123328 +
123329 + /* FM Ports statistics */
123330 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
123331 + case e_FM_PORT_TYPE_TX:
123332 + case e_FM_PORT_TYPE_TX_10G:
123333 + if (sysfs_create_group
123334 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
123335 + return -EIO;
123336 + break;
123337 + case e_FM_PORT_TYPE_RX:
123338 + case e_FM_PORT_TYPE_RX_10G:
123339 + if (sysfs_create_group
123340 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
123341 + return -EIO;
123342 + break;
123343 + case e_FM_PORT_TYPE_DUMMY:
123344 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
123345 + if (sysfs_create_group
123346 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
123347 + return -EIO;
123348 + break;
123349 + default:
123350 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
123351 + __func__);
123352 + return -EINVAL;
123353 + break;
123354 + };
123355 +
123356 + return 0;
123357 +}
123358 +
123359 +void fm_port_sysfs_destroy(struct device *dev)
123360 +{
123361 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
123362 +
123363 + /* this function has never been tested !!! */
123364 +
123365 + if (WARN_ON(dev == NULL))
123366 + return;
123367 +
123368 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123369 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
123370 + return;
123371 +
123372 + /* The name attribute will be freed also by these 2 functions? */
123373 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
123374 + case e_FM_PORT_TYPE_TX:
123375 + case e_FM_PORT_TYPE_TX_10G:
123376 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
123377 + break;
123378 + case e_FM_PORT_TYPE_RX:
123379 + case e_FM_PORT_TYPE_RX_10G:
123380 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
123381 + break;
123382 + case e_FM_PORT_TYPE_DUMMY:
123383 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
123384 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
123385 + break;
123386 + default:
123387 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
123388 + __func__);
123389 + break;
123390 + };
123391 +
123392 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
123393 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
123394 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
123395 +#if (DPAA_VERSION >= 11)
123396 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
123397 +#endif
123398 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
123399 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
123400 +}
123401 +
123402 +
123403 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
123404 +{
123405 + t_FmPort *p_FmPort;
123406 + t_Fm *p_Fm;
123407 + uint8_t hardwarePortId;
123408 + int n = nn;
123409 +
123410 + p_FmPort = (t_FmPort *)h_dev;
123411 + hardwarePortId = p_FmPort->hardwarePortId;
123412 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
123413 +
123414 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
123415 + "fmbm_pp for port %u", hardwarePortId);
123416 + FM_DMP_MEM_32(buf, n,
123417 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
123418 +
123419 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
123420 + "fmbm_pfs for port %u", hardwarePortId);
123421 + FM_DMP_MEM_32(buf, n,
123422 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
123423 +
123424 + FM_DMP_TITLE(buf, n,
123425 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
123426 + "fmbm_spliodn for port %u", hardwarePortId);
123427 + FM_DMP_MEM_32(buf, n,
123428 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
123429 +
123430 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
123431 + "fmfp_psfor port %u", hardwarePortId);
123432 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
123433 +
123434 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
123435 + "fmdmplrfor port %u", hardwarePortId);
123436 + FM_DMP_MEM_32(buf, n,
123437 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
123438 + return n;
123439 +}
123440 +
123441 +#if (DPAA_VERSION >= 11)
123442 +
123443 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
123444 +{
123445 + t_FmPort *p_FmPort;
123446 + int n = nn;
123447 +
123448 + p_FmPort = (t_FmPort *)h_dev;
123449 +
123450 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
123451 +
123452 + FM_DMP_SUBTITLE(buf, n, "\n");
123453 +
123454 + return n;
123455 +}
123456 +#endif
123457 +
123458 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
123459 +{
123460 + t_FmPort *p_FmPort;
123461 + u_FmPortBmiRegs *p_bmi;
123462 +
123463 + char arr[20];
123464 + uint8_t flag;
123465 + int i = 0;
123466 + int n = nn;
123467 +
123468 + p_FmPort = (t_FmPort *)h_dev;
123469 + p_bmi = p_FmPort->p_FmPortBmiRegs;
123470 +
123471 + memset(arr, 0, sizeof(arr));
123472 + switch (p_FmPort->portType) {
123473 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
123474 + strcpy(arr, "OFFLINE-PARSING");
123475 + flag = 0;
123476 + break;
123477 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
123478 + strcpy(arr, "HOST-COMMAND");
123479 + flag = 0;
123480 + break;
123481 + case (e_FM_PORT_TYPE_RX):
123482 + strcpy(arr, "RX");
123483 + flag = 1;
123484 + break;
123485 + case (e_FM_PORT_TYPE_RX_10G):
123486 + strcpy(arr, "RX-10G");
123487 + flag = 1;
123488 + break;
123489 + case (e_FM_PORT_TYPE_TX):
123490 + strcpy(arr, "TX");
123491 + flag = 2;
123492 + break;
123493 + case (e_FM_PORT_TYPE_TX_10G):
123494 + strcpy(arr, "TX-10G");
123495 + flag = 2;
123496 + break;
123497 + default:
123498 + return -EINVAL;
123499 + }
123500 +
123501 + FM_DMP_TITLE(buf, n, NULL,
123502 + "FMan-Port (%s #%d) registers:",
123503 + arr, p_FmPort->portId);
123504 +
123505 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
123506 +
123507 + switch (flag) {
123508 + case (0):
123509 + FM_DMP_SUBTITLE(buf, n, "\n");
123510 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
123511 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
123512 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
123513 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
123514 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
123515 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
123516 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
123517 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
123518 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
123519 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
123520 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
123521 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
123522 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
123523 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
123524 +
123525 + FM_DMP_TITLE(buf, n,
123526 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
123527 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
123528 + FM_DMP_MEM_32(buf, n,
123529 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
123530 + }
123531 + FM_DMP_SUBTITLE(buf, n, "\n");
123532 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
123533 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
123534 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
123535 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
123536 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
123537 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
123538 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
123539 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
123540 + {
123541 +#ifndef FM_NO_OP_OBSERVED_POOLS
123542 + if (p_FmPort->fmRevInfo.majorRev == 4) {
123543 + FM_DMP_TITLE(buf, n,
123544 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
123545 + "fmbm_oebmpi");
123546 +
123547 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
123548 + FM_DMP_MEM_32(buf, n,
123549 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
123550 + }
123551 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
123552 + }
123553 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
123554 + }
123555 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
123556 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
123557 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
123558 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
123559 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
123560 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
123561 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
123562 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
123563 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
123564 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
123565 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
123566 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
123567 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
123568 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
123569 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
123570 + "fmbm_odcfg");
123571 + for (i = 0; i < 3; ++i) {
123572 + FM_DMP_MEM_32(buf, n,
123573 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
123574 + }
123575 + FM_DMP_SUBTITLE(buf, n, "\n");
123576 +
123577 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
123578 + break;
123579 + case (1):
123580 + FM_DMP_SUBTITLE(buf, n, "\n");
123581 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
123582 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
123583 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
123584 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
123585 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
123586 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
123587 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
123588 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
123589 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
123590 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
123591 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
123592 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
123593 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
123594 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
123595 + "fmbm_rprai");
123596 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
123597 + FM_DMP_MEM_32(buf, n,
123598 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
123599 + }
123600 + FM_DMP_SUBTITLE(buf, n, "\n");
123601 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
123602 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
123603 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
123604 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
123605 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
123606 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
123607 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
123608 + "fmbm_ebmpi");
123609 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
123610 + FM_DMP_MEM_32(buf, n,
123611 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
123612 + }
123613 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
123614 + "fmbm_acnt");
123615 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
123616 + FM_DMP_MEM_32(buf, n,
123617 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
123618 + }
123619 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
123620 + "fmbm_rcgm");
123621 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
123622 + FM_DMP_MEM_32(buf, n,
123623 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
123624 + }
123625 +
123626 + FM_DMP_SUBTITLE(buf, n, "\n");
123627 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
123628 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
123629 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
123630 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
123631 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
123632 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
123633 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
123634 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
123635 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
123636 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
123637 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
123638 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
123639 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
123640 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
123641 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
123642 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
123643 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
123644 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
123645 + "fmbm_rdcfg");
123646 + for (i = 0; i < 3; ++i) {
123647 + FM_DMP_MEM_32(buf, n,
123648 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
123649 + }
123650 + FM_DMP_SUBTITLE(buf, n, "\n");
123651 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
123652 + break;
123653 + case (2):
123654 + FM_DMP_SUBTITLE(buf, n, "\n");
123655 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
123656 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
123657 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
123658 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
123659 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
123660 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
123661 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
123662 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
123663 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
123664 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
123665 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
123666 +#if (DPAA_VERSION >= 11)
123667 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
123668 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
123669 +#endif /* (DPAA_VERSION >= 11) */
123670 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
123671 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
123672 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
123673 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
123674 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
123675 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
123676 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
123677 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
123678 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
123679 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
123680 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
123681 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
123682 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
123683 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
123684 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
123685 + "fmbm_tdcfg");
123686 + for (i = 0; i < 3 ; ++i) {
123687 + FM_DMP_MEM_32(buf, n,
123688 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
123689 + }
123690 + FM_DMP_SUBTITLE(buf, n, "\n");
123691 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
123692 + break;
123693 + }
123694 +
123695 + FM_DMP_SUBTITLE(buf, n, "\n");
123696 +
123697 + return n;
123698 +}
123699 +
123700 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
123701 +{
123702 + t_FmPort *p_FmPort;
123703 + int n = nn;
123704 +
123705 + p_FmPort = (t_FmPort *)h_dev;
123706 +
123707 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
123708 +
123709 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
123710 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
123711 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
123712 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
123713 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
123714 + FM_DMP_V32(buf, n,
123715 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
123716 + FM_DMP_V32(buf, n,
123717 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
123718 + FM_DMP_V32(buf, n,
123719 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
123720 + FM_DMP_V32(buf, n,
123721 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
123722 + FM_DMP_V32(buf, n,
123723 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
123724 +
123725 + FM_DMP_SUBTITLE(buf, n, "\n");
123726 +
123727 + return n;
123728 +}
123729 +
123730 --- /dev/null
123731 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
123732 @@ -0,0 +1,56 @@
123733 +/*
123734 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123735 + *
123736 + * Redistribution and use in source and binary forms, with or without
123737 + * modification, are permitted provided that the following conditions are met:
123738 + * * Redistributions of source code must retain the above copyright
123739 + * notice, this list of conditions and the following disclaimer.
123740 + * * Redistributions in binary form must reproduce the above copyright
123741 + * notice, this list of conditions and the following disclaimer in the
123742 + * documentation and/or other materials provided with the distribution.
123743 + * * Neither the name of Freescale Semiconductor nor the
123744 + * names of its contributors may be used to endorse or promote products
123745 + * derived from this software without specific prior written permission.
123746 + *
123747 + *
123748 + * ALTERNATIVELY, this software may be distributed under the terms of the
123749 + * GNU General Public License ("GPL") as published by the Free Software
123750 + * Foundation, either version 2 of that License or (at your option) any
123751 + * later version.
123752 + *
123753 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123754 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123755 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123756 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123757 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123758 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123759 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123760 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123761 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123762 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123763 + */
123764 +
123765 +/*
123766 + @File lnxwrp_sysfs_fm_port.h
123767 +
123768 + @Description FM port sysfs functions.
123769 +
123770 +*/
123771 +
123772 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
123773 +#define LNXWRP_SYSFS_FM_PORT_H_
123774 +
123775 +#include "lnxwrp_sysfs.h"
123776 +
123777 +int fm_port_sysfs_create(struct device *dev);
123778 +void fm_port_sysfs_destroy(struct device *dev);
123779 +
123780 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
123781 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
123782 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
123783 +
123784 +#if (DPAA_VERSION >= 11)
123785 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
123786 +#endif
123787 +
123788 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
123789 --- /dev/null
123790 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
123791 @@ -0,0 +1,18 @@
123792 +#
123793 +# Makefile for the Freescale Ethernet controllers
123794 +#
123795 +ccflags-y += -DVERSION=\"\"
123796 +#
123797 +#Include netcomm SW specific definitions
123798 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
123799 +
123800 +obj-y += fsl-ncsw-xx.o
123801 +
123802 +ifneq ($(CONFIG_FMAN_ARM),y)
123803 +fsl-ncsw-xx-objs := xx_linux.o \
123804 + module_strings.o
123805 +else
123806 +fsl-ncsw-xx-objs := xx_arm_linux.o \
123807 + module_strings.o
123808 +endif
123809 +
123810 --- /dev/null
123811 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
123812 @@ -0,0 +1,46 @@
123813 +/*
123814 + * Copyright 2012 Freescale Semiconductor Inc.
123815 + *
123816 + * Redistribution and use in source and binary forms, with or without
123817 + * modification, are permitted provided that the following conditions are met:
123818 + * * Redistributions of source code must retain the above copyright
123819 + * notice, this list of conditions and the following disclaimer.
123820 + * * Redistributions in binary form must reproduce the above copyright
123821 + * notice, this list of conditions and the following disclaimer in the
123822 + * documentation and/or other materials provided with the distribution.
123823 + * * Neither the name of Freescale Semiconductor nor the
123824 + * names of its contributors may be used to endorse or promote products
123825 + * derived from this software without specific prior written permission.
123826 + *
123827 + *
123828 + * ALTERNATIVELY, this software may be distributed under the terms of the
123829 + * GNU General Public License ("GPL") as published by the Free Software
123830 + * Foundation, either version 2 of that License or (at your option) any
123831 + * later version.
123832 + *
123833 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123834 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123835 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123836 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123837 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123838 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123839 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123840 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123841 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123842 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123843 + */
123844 +
123845 +/* Module names for debug messages */
123846 +const char *moduleStrings[] =
123847 +{
123848 + "", /* MODULE_UNKNOWN */
123849 + "FM", /* MODULE_FM */
123850 + "FM-MURAM", /* MODULE_FM_MURAM */
123851 + "FM-PCD", /* MODULE_FM_PCD */
123852 + "FM-RTC", /* MODULE_FM_RTC */
123853 + "FM-MAC", /* MODULE_FM_MAC */
123854 + "FM-Port", /* MODULE_FM_PORT */
123855 + "MM", /* MODULE_MM */
123856 + "FM-SP", /* MODULE_FM_SP */
123857 + "FM-MACSEC" /* MODULE_FM_MACSEC */
123858 +};
123859 --- /dev/null
123860 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
123861 @@ -0,0 +1,905 @@
123862 +/*
123863 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123864 + *
123865 + * Redistribution and use in source and binary forms, with or without
123866 + * modification, are permitted provided that the following conditions are met:
123867 + * * Redistributions of source code must retain the above copyright
123868 + * notice, this list of conditions and the following disclaimer.
123869 + * * Redistributions in binary form must reproduce the above copyright
123870 + * notice, this list of conditions and the following disclaimer in the
123871 + * documentation and/or other materials provided with the distribution.
123872 + * * Neither the name of Freescale Semiconductor nor the
123873 + * names of its contributors may be used to endorse or promote products
123874 + * derived from this software without specific prior written permission.
123875 + *
123876 + *
123877 + * ALTERNATIVELY, this software may be distributed under the terms of the
123878 + * GNU General Public License ("GPL") as published by the Free Software
123879 + * Foundation, either version 2 of that License or (at your option) any
123880 + * later version.
123881 + *
123882 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123883 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123884 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123885 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123886 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123887 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123888 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123889 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123890 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123891 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123892 + */
123893 +
123894 +/**************************************************************************//**
123895 + @File xx_arm_linux.c
123896 +
123897 + @Description XX routines implementation for Linux.
123898 +*//***************************************************************************/
123899 +#include <linux/version.h>
123900 +
123901 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123902 +#define MODVERSIONS
123903 +#endif
123904 +#ifdef MODVERSIONS
123905 +#include <config/modversions.h>
123906 +#endif /* MODVERSIONS */
123907 +
123908 +#include <linux/module.h>
123909 +#include <linux/kernel.h>
123910 +#include <linux/sched.h>
123911 +#include <linux/string.h>
123912 +#include <linux/ptrace.h>
123913 +#include <linux/errno.h>
123914 +#include <linux/ioport.h>
123915 +#include <linux/slab.h>
123916 +#include <linux/interrupt.h>
123917 +#include <linux/fs.h>
123918 +#include <linux/vmalloc.h>
123919 +#include <linux/init.h>
123920 +#include <linux/timer.h>
123921 +#include <linux/spinlock.h>
123922 +#include <linux/delay.h>
123923 +#include <linux/proc_fs.h>
123924 +#include <linux/smp.h>
123925 +#include <linux/of.h>
123926 +#include <linux/irqdomain.h>
123927 +
123928 +#include <linux/workqueue.h>
123929 +
123930 +#ifdef BIGPHYSAREA_ENABLE
123931 +#include <linux/bigphysarea.h>
123932 +#endif /* BIGPHYSAREA_ENABLE */
123933 +
123934 +//#include <sysdev/fsl_soc.h>
123935 +#include <asm/pgtable.h>
123936 +#include <asm/irq.h>
123937 +#include <asm/bitops.h>
123938 +#include <asm/uaccess.h>
123939 +#include <asm/io.h>
123940 +#include <asm/atomic.h>
123941 +#include <asm/string.h>
123942 +#include <asm/byteorder.h>
123943 +#include <asm/page.h>
123944 +
123945 +#include "error_ext.h"
123946 +#include "std_ext.h"
123947 +#include "list_ext.h"
123948 +#include "mm_ext.h"
123949 +#include "sys_io_ext.h"
123950 +#include "xx.h"
123951 +
123952 +
123953 +#define __ERR_MODULE__ MODULE_UNKNOWN
123954 +
123955 +#ifdef BIGPHYSAREA_ENABLE
123956 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123957 +
123958 +
123959 +/* TODO: large allocations => use big phys area */
123960 +/******************************************************************************
123961 + * routine: get_nr_pages
123962 + *
123963 + * description:
123964 + * calculates the number of memory pages for a given size (in bytes)
123965 + *
123966 + * arguments:
123967 + * size - the number of bytes
123968 + *
123969 + * return code:
123970 + * The number of pages
123971 + *
123972 + *****************************************************************************/
123973 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123974 +{
123975 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123976 +}
123977 +
123978 +static bool in_big_phys_area (uint32_t addr)
123979 +{
123980 + uint32_t base, size;
123981 +
123982 + bigphysarea_get_details (&base, &size);
123983 + return ((addr >= base) && (addr < base + size));
123984 +}
123985 +#endif /* BIGPHYSAREA_ENABLE */
123986 +
123987 +void * xx_Malloc(uint32_t n)
123988 +{
123989 + void *a;
123990 + uint32_t flags;
123991 +
123992 + flags = XX_DisableAllIntr();
123993 +#ifdef BIGPHYSAREA_ENABLE
123994 + if (n >= MAX_ALLOCATION_SIZE)
123995 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123996 + else
123997 +#endif /* BIGPHYSAREA_ENABLE */
123998 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123999 + if (!a)
124000 + XX_Print("No memory for XX_Malloc\n");
124001 + XX_RestoreAllIntr(flags);
124002 +
124003 + return a;
124004 +}
124005 +
124006 +void xx_Free(void *p)
124007 +{
124008 +#ifdef BIGPHYSAREA_ENABLE
124009 + if (in_big_phys_area ((uint32_t)p))
124010 + bigphysarea_free_pages(p);
124011 + else
124012 +#endif /* BIGPHYSAREA_ENABLE */
124013 + kfree(p);
124014 +}
124015 +
124016 +void XX_Exit(int status)
124017 +{
124018 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
124019 +}
124020 +
124021 +#define BUF_SIZE 512
124022 +void XX_Print(char *str, ...)
124023 +{
124024 + va_list args;
124025 +#ifdef CONFIG_SMP
124026 + char buf[BUF_SIZE];
124027 +#endif /* CONFIG_SMP */
124028 +
124029 + va_start(args, str);
124030 +#ifdef CONFIG_SMP
124031 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124032 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124033 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
124034 +#else
124035 + vprintk(str, args);
124036 +#endif /* CONFIG_SMP */
124037 + va_end(args);
124038 +}
124039 +
124040 +void XX_Fprint(void *file, char *str, ...)
124041 +{
124042 + va_list args;
124043 +#ifdef CONFIG_SMP
124044 + char buf[BUF_SIZE];
124045 +#endif /* CONFIG_SMP */
124046 +
124047 + va_start(args, str);
124048 +#ifdef CONFIG_SMP
124049 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124050 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124051 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
124052 +
124053 +#else
124054 + vprintk(str, args);
124055 +#endif /* CONFIG_SMP */
124056 + va_end(args);
124057 +}
124058 +
124059 +#ifdef DEBUG_XX_MALLOC
124060 +typedef void (*t_ffn)(void *);
124061 +typedef struct {
124062 + t_ffn f_free;
124063 + void *mem;
124064 + char *fname;
124065 + int fline;
124066 + uint32_t size;
124067 + t_List node;
124068 +} t_MemDebug;
124069 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
124070 +
124071 +LIST(memDbgLst);
124072 +
124073 +
124074 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
124075 +{
124076 + void *mem;
124077 + t_MemDebug *p_MemDbg;
124078 +
124079 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
124080 + if (p_MemDbg == NULL)
124081 + return NULL;
124082 +
124083 + mem = xx_Malloc(size);
124084 + if (mem == NULL)
124085 + {
124086 + XX_Free(p_MemDbg);
124087 + return NULL;
124088 + }
124089 +
124090 + INIT_LIST(&p_MemDbg->node);
124091 + p_MemDbg->f_free = xx_Free;
124092 + p_MemDbg->mem = mem;
124093 + p_MemDbg->fname = fname;
124094 + p_MemDbg->fline = line;
124095 + p_MemDbg->size = size+sizeof(t_MemDebug);
124096 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
124097 +
124098 + return mem;
124099 +}
124100 +
124101 +void * XX_MallocSmartDebug(uint32_t size,
124102 + int memPartitionId,
124103 + uint32_t align,
124104 + char *fname,
124105 + int line)
124106 +{
124107 + void *mem;
124108 + t_MemDebug *p_MemDbg;
124109 +
124110 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
124111 + if (p_MemDbg == NULL)
124112 + return NULL;
124113 +
124114 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
124115 + if (mem == NULL)
124116 + {
124117 + XX_Free(p_MemDbg);
124118 + return NULL;
124119 + }
124120 +
124121 + INIT_LIST(&p_MemDbg->node);
124122 + p_MemDbg->f_free = xx_FreeSmart;
124123 + p_MemDbg->mem = mem;
124124 + p_MemDbg->fname = fname;
124125 + p_MemDbg->fline = line;
124126 + p_MemDbg->size = size+sizeof(t_MemDebug);
124127 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
124128 +
124129 + return mem;
124130 +}
124131 +
124132 +static void debug_free(void *mem)
124133 +{
124134 + t_List *p_MemDbgLh = NULL;
124135 + t_MemDebug *p_MemDbg;
124136 + bool found = FALSE;
124137 +
124138 + if (LIST_IsEmpty(&memDbgLst))
124139 + {
124140 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
124141 + return;
124142 + }
124143 +
124144 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
124145 + {
124146 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
124147 + if (p_MemDbg->mem == mem)
124148 + {
124149 + found = TRUE;
124150 + break;
124151 + }
124152 + }
124153 +
124154 + if (!found)
124155 + {
124156 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
124157 + ("Attempt to free unallocated address (0x%08x)",mem));
124158 + dump_stack();
124159 + return;
124160 + }
124161 +
124162 + LIST_Del(p_MemDbgLh);
124163 + p_MemDbg->f_free(mem);
124164 + p_MemDbg->f_free(p_MemDbg);
124165 +}
124166 +
124167 +void XX_FreeSmart(void *p)
124168 +{
124169 + debug_free(p);
124170 +}
124171 +
124172 +
124173 +void XX_Free(void *p)
124174 +{
124175 + debug_free(p);
124176 +}
124177 +
124178 +#else /* not DEBUG_XX_MALLOC */
124179 +void * XX_Malloc(uint32_t size)
124180 +{
124181 + return xx_Malloc(size);
124182 +}
124183 +
124184 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124185 +{
124186 + return xx_MallocSmart(size,memPartitionId, alignment);
124187 +}
124188 +
124189 +void XX_FreeSmart(void *p)
124190 +{
124191 + xx_FreeSmart(p);
124192 +}
124193 +
124194 +
124195 +void XX_Free(void *p)
124196 +{
124197 + xx_Free(p);
124198 +}
124199 +#endif /* not DEBUG_XX_MALLOC */
124200 +
124201 +
124202 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
124203 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
124204 +{
124205 + e_Event eventCode = (e_Event)event;
124206 +
124207 + UNUSED(eventCode);
124208 + UNUSED(appId);
124209 + UNUSED(flags);
124210 + UNUSED(msg);
124211 +}
124212 +#endif /* (defined(REPORT_EVENTS) && ... */
124213 +
124214 +
124215 +uint32_t XX_DisableAllIntr(void)
124216 +{
124217 + unsigned long flags;
124218 +
124219 +#ifdef local_irq_save_nort
124220 + local_irq_save_nort(flags);
124221 +#else
124222 + local_irq_save(flags);
124223 +#endif
124224 +
124225 + return (uint32_t)flags;
124226 +}
124227 +
124228 +void XX_RestoreAllIntr(uint32_t flags)
124229 +{
124230 +#ifdef local_irq_restore_nort
124231 + local_irq_restore_nort((unsigned long)flags);
124232 +#else
124233 + local_irq_restore((unsigned long)flags);
124234 +#endif
124235 +}
124236 +
124237 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
124238 +{
124239 + UNUSED(qid);
124240 + UNUSED(appId);
124241 + UNUSED(flags);
124242 +
124243 + return f(id);
124244 +}
124245 +
124246 +int XX_IsICacheEnable(void)
124247 +{
124248 + return TRUE;
124249 +}
124250 +
124251 +int XX_IsDCacheEnable(void)
124252 +{
124253 + return TRUE;
124254 +}
124255 +
124256 +
124257 +typedef struct {
124258 + t_Isr *f_Isr;
124259 + t_Handle handle;
124260 +} t_InterruptHandler;
124261 +
124262 +
124263 +t_Handle interruptHandlers[0x00010000];
124264 +
124265 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
124266 +{
124267 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
124268 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
124269 + return IRQ_HANDLED;
124270 +}
124271 +
124272 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
124273 +{
124274 + const char *device;
124275 + t_InterruptHandler *p_IntrHndl;
124276 +
124277 + device = GetDeviceName(irq);
124278 + if (device == NULL)
124279 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
124280 +
124281 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
124282 + if (p_IntrHndl == NULL)
124283 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
124284 + p_IntrHndl->f_Isr = f_Isr;
124285 + p_IntrHndl->handle = handle;
124286 + interruptHandlers[irq] = p_IntrHndl;
124287 +
124288 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
124289 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
124290 + disable_irq(GetDeviceIrqNum(irq));
124291 +
124292 + return E_OK;
124293 +}
124294 +
124295 +t_Error XX_FreeIntr(int irq)
124296 +{
124297 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
124298 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
124299 + XX_Free(p_IntrHndl);
124300 + interruptHandlers[irq] = 0;
124301 + return E_OK;
124302 +}
124303 +
124304 +t_Error XX_EnableIntr(int irq)
124305 +{
124306 + enable_irq(GetDeviceIrqNum(irq));
124307 + return E_OK;
124308 +}
124309 +
124310 +t_Error XX_DisableIntr(int irq)
124311 +{
124312 + disable_irq(GetDeviceIrqNum(irq));
124313 + return E_OK;
124314 +}
124315 +
124316 +
124317 +/*****************************************************************************/
124318 +/* Tasklet Service Routines */
124319 +/*****************************************************************************/
124320 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
124321 +typedef struct
124322 +{
124323 + t_Handle h_Data;
124324 + void (*f_Callback) (void *);
124325 + struct delayed_work dwork;
124326 +} t_Tasklet;
124327 +
124328 +static void GenericTaskletCallback(struct work_struct *p_Work)
124329 +{
124330 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
124331 +
124332 + p_Task->f_Callback(p_Task->h_Data);
124333 +}
124334 +#endif /* LINUX_VERSION_CODE */
124335 +
124336 +
124337 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
124338 +{
124339 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124340 + struct work_struct *p_Task;
124341 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
124342 + INIT_WORK(p_Task, routine, data);
124343 +#else
124344 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
124345 + p_Task->h_Data = data;
124346 + p_Task->f_Callback = routine;
124347 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
124348 +#endif /* LINUX_VERSION_CODE */
124349 +
124350 + return (t_TaskletHandle)p_Task;
124351 +}
124352 +
124353 +
124354 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
124355 +{
124356 + if (h_Tasklet)
124357 + XX_Free(h_Tasklet);
124358 +}
124359 +
124360 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
124361 +{
124362 + int ans;
124363 +
124364 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124365 + if (immediate)
124366 + ans = schedule_work(h_Tasklet);
124367 + else
124368 + ans = schedule_delayed_work(h_Tasklet, 1);
124369 +#else
124370 + if (immediate)
124371 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
124372 + else
124373 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
124374 +#endif /* LINUX_VERSION_CODE */
124375 +
124376 + return ans;
124377 +}
124378 +
124379 +void XX_FlushScheduledTasks(void)
124380 +{
124381 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124382 + flush_scheduled_tasks();
124383 +#else
124384 + flush_scheduled_work();
124385 +#endif /* LINUX_VERSION_CODE */
124386 +}
124387 +
124388 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
124389 +{
124390 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124391 + return (int)(((struct work_struct *)h_Tasklet)->pending);
124392 +#else
124393 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
124394 +#endif /* LINUX_VERSION_CODE */
124395 +}
124396 +
124397 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
124398 +{
124399 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124400 + ((struct tq_struct *)h_Tasklet)->data = data;
124401 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124402 + ((struct work_struct *)h_Tasklet)->data = data;
124403 +#else
124404 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
124405 +#endif /* LINUX_VERSION_CODE */
124406 +}
124407 +
124408 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
124409 +{
124410 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124411 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
124412 +#else
124413 + return ((t_Tasklet *)h_Tasklet)->h_Data;
124414 +#endif /* LINUX_VERSION_CODE */
124415 +}
124416 +
124417 +
124418 +/*****************************************************************************/
124419 +/* Spinlock Service Routines */
124420 +/*****************************************************************************/
124421 +
124422 +t_Handle XX_InitSpinlock(void)
124423 +{
124424 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
124425 + if (!p_Spinlock)
124426 + return NULL;
124427 +
124428 + spin_lock_init(p_Spinlock);
124429 +
124430 + return (t_Handle)p_Spinlock;
124431 +}
124432 +
124433 +void XX_FreeSpinlock(t_Handle h_Spinlock)
124434 +{
124435 + if (h_Spinlock)
124436 + XX_Free(h_Spinlock);
124437 +}
124438 +
124439 +void XX_LockSpinlock(t_Handle h_Spinlock)
124440 +{
124441 + spin_lock((spinlock_t *)h_Spinlock);
124442 +}
124443 +
124444 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
124445 +{
124446 + spin_unlock((spinlock_t *)h_Spinlock);
124447 +}
124448 +
124449 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
124450 +{
124451 + unsigned long intrFlags;
124452 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
124453 + return intrFlags;
124454 +}
124455 +
124456 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
124457 +{
124458 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
124459 +}
124460 +
124461 +
124462 +/*****************************************************************************/
124463 +/* Timers Service Routines */
124464 +/*****************************************************************************/
124465 +/* The time now is in mili sec. resolution */
124466 +uint32_t XX_CurrentTime(void)
124467 +{
124468 + return (jiffies*1000)/HZ;
124469 +}
124470 +
124471 +
124472 +t_Handle XX_CreateTimer(void)
124473 +{
124474 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
124475 + if (p_Timer)
124476 + {
124477 + memset(p_Timer, 0, sizeof(struct timer_list));
124478 + init_timer(p_Timer);
124479 + }
124480 + return (t_Handle)p_Timer;
124481 +}
124482 +
124483 +void XX_FreeTimer(t_Handle h_Timer)
124484 +{
124485 + if (h_Timer)
124486 + XX_Free(h_Timer);
124487 +}
124488 +
124489 +void XX_StartTimer(t_Handle h_Timer,
124490 + uint32_t msecs,
124491 + bool periodic,
124492 + void (*f_TimerExpired)(t_Handle),
124493 + t_Handle h_Arg)
124494 +{
124495 + int tmp_jiffies = (msecs*HZ)/1000;
124496 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124497 +
124498 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
124499 +
124500 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
124501 + p_Timer->data = (unsigned long)h_Arg;
124502 + if ((msecs*HZ)%1000)
124503 + tmp_jiffies++;
124504 + p_Timer->expires = (jiffies + tmp_jiffies);
124505 +
124506 + add_timer((struct timer_list *)h_Timer);
124507 +}
124508 +
124509 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
124510 +{
124511 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124512 +
124513 + p_Timer->data = (unsigned long)data;
124514 +}
124515 +
124516 +t_Handle XX_GetTimerData(t_Handle h_Timer)
124517 +{
124518 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124519 +
124520 + return (t_Handle)p_Timer->data;
124521 +}
124522 +
124523 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
124524 +{
124525 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124526 +
124527 + return (uint32_t)p_Timer->expires;
124528 +}
124529 +
124530 +void XX_StopTimer(t_Handle h_Timer)
124531 +{
124532 + del_timer((struct timer_list *)h_Timer);
124533 +}
124534 +
124535 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
124536 +{
124537 + int tmp_jiffies = (msecs*HZ)/1000;
124538 +
124539 + if ((msecs*HZ)%1000)
124540 + tmp_jiffies++;
124541 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
124542 +}
124543 +
124544 +int XX_TimerIsActive(t_Handle h_Timer)
124545 +{
124546 + return timer_pending((struct timer_list *)h_Timer);
124547 +}
124548 +
124549 +uint32_t XX_Sleep(uint32_t msecs)
124550 +{
124551 + int tmp_jiffies = (msecs*HZ)/1000;
124552 +
124553 + if ((msecs*HZ)%1000)
124554 + tmp_jiffies++;
124555 + return schedule_timeout(tmp_jiffies);
124556 +}
124557 +
124558 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
124559 +void XX_UDelay(uint32_t usecs)
124560 +{
124561 + udelay(usecs);
124562 +}
124563 +
124564 +/* TODO: verify that these are correct */
124565 +#define MSG_BODY_SIZE 512
124566 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
124567 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
124568 +t_Error XX_SendMessage(char *p_DestAddr,
124569 + uint32_t msgId,
124570 + uint8_t msgBody[MSG_BODY_SIZE],
124571 + t_MsgCompletionCB *f_CompletionCB,
124572 + t_Handle h_CBArg);
124573 +
124574 +typedef struct {
124575 + char *p_Addr;
124576 + t_MsgHandler *f_MsgHandlerCB;
124577 + t_Handle h_Mod;
124578 + t_List node;
124579 +} t_MsgHndlr;
124580 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
124581 +
124582 +LIST(msgHndlrList);
124583 +
124584 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
124585 +{
124586 + uint32_t intFlags;
124587 +
124588 + intFlags = XX_DisableAllIntr();
124589 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
124590 + XX_RestoreAllIntr(intFlags);
124591 +}
124592 +/* TODO: add this for multi-platform support
124593 +static t_MsgHndlr * DequeueMsgHndlr(void)
124594 +{
124595 + t_MsgHndlr *p_MsgHndlr = NULL;
124596 + uint32_t intFlags;
124597 +
124598 + intFlags = XX_DisableAllIntr();
124599 + if (!LIST_IsEmpty(&msgHndlrList))
124600 + {
124601 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
124602 + LIST_DelAndInit(&p_MsgHndlr->node);
124603 + }
124604 + XX_RestoreAllIntr(intFlags);
124605 +
124606 + return p_MsgHndlr;
124607 +}
124608 +*/
124609 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
124610 +{
124611 + t_MsgHndlr *p_MsgHndlr;
124612 + t_List *p_Pos;
124613 +
124614 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
124615 + {
124616 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
124617 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
124618 + return p_MsgHndlr;
124619 + }
124620 +
124621 + return NULL;
124622 +}
124623 +
124624 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
124625 +{
124626 + t_MsgHndlr *p_MsgHndlr;
124627 + uint32_t len;
124628 +
124629 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
124630 + if (!p_MsgHndlr)
124631 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
124632 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
124633 +
124634 + len = strlen(p_Addr);
124635 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
124636 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
124637 +
124638 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
124639 + p_MsgHndlr->h_Mod = h_Mod;
124640 + INIT_LIST(&p_MsgHndlr->node);
124641 + EnqueueMsgHndlr(p_MsgHndlr);
124642 +
124643 + return E_OK;
124644 +}
124645 +
124646 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
124647 +{
124648 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
124649 + if (!p_MsgHndlr)
124650 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124651 +
124652 + LIST_Del(&p_MsgHndlr->node);
124653 + XX_Free(p_MsgHndlr->p_Addr);
124654 + XX_Free(p_MsgHndlr);
124655 +
124656 + return E_OK;
124657 +}
124658 +
124659 +t_Error XX_SendMessage(char *p_DestAddr,
124660 + uint32_t msgId,
124661 + uint8_t msgBody[MSG_BODY_SIZE],
124662 + t_MsgCompletionCB *f_CompletionCB,
124663 + t_Handle h_CBArg)
124664 +{
124665 + t_Error ans;
124666 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
124667 + if (!p_MsgHndlr)
124668 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124669 +
124670 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
124671 +
124672 + if (f_CompletionCB)
124673 + f_CompletionCB(h_CBArg, msgBody);
124674 +
124675 + return ans;
124676 +}
124677 +
124678 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124679 + t_IpcMsgHandler *f_MsgHandler,
124680 + t_Handle h_Module,
124681 + uint32_t replyLength)
124682 +{
124683 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
124684 + return E_OK;
124685 +}
124686 +
124687 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124688 +{
124689 + UNUSED(addr);
124690 + return E_OK;
124691 +}
124692 +
124693 +
124694 +t_Error XX_IpcSendMessage(t_Handle h_Session,
124695 + uint8_t *p_Msg,
124696 + uint32_t msgLength,
124697 + uint8_t *p_Reply,
124698 + uint32_t *p_ReplyLength,
124699 + t_IpcMsgCompletion *f_Completion,
124700 + t_Handle h_Arg)
124701 +{
124702 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
124703 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
124704 + return E_OK;
124705 +}
124706 +
124707 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124708 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124709 +{
124710 + UNUSED(destAddr); UNUSED(srcAddr);
124711 + return E_OK;
124712 +}
124713 +
124714 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
124715 +int GetDeviceIrqNum(int irq)
124716 +{
124717 + struct device_node *iPar;
124718 + struct irq_domain *irqHost;
124719 + uint32_t hwIrq;
124720 +
124721 + /* Get the interrupt controller */
124722 + iPar = of_find_node_by_name(NULL, "mpic");
124723 + hwIrq = 0;
124724 +
124725 + ASSERT_COND(iPar != NULL);
124726 + /* Get the irq host */
124727 + irqHost = irq_find_host(iPar);
124728 + of_node_put(iPar);
124729 +
124730 + /* Create irq mapping */
124731 + return irq_create_mapping(irqHost, hwIrq);
124732 +}
124733 +#else
124734 +#error "kernel not supported!!!"
124735 +#endif /* LINUX_VERSION_CODE */
124736 +
124737 +void * XX_PhysToVirt(physAddress_t addr)
124738 +{
124739 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
124740 +}
124741 +
124742 +physAddress_t XX_VirtToPhys(void * addr)
124743 +{
124744 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
124745 +}
124746 +
124747 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124748 +{
124749 + uintptr_t *returnCode, tmp;
124750 +
124751 + if (alignment < sizeof(uintptr_t))
124752 + alignment = sizeof(uintptr_t);
124753 + size += alignment + sizeof(returnCode);
124754 + tmp = (uintptr_t)xx_Malloc(size);
124755 + if (tmp == 0)
124756 + return NULL;
124757 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
124758 + *(returnCode - 1) = tmp;
124759 +
124760 + return (void*)returnCode;
124761 +}
124762 +
124763 +void xx_FreeSmart(void *p)
124764 +{
124765 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
124766 +}
124767 --- /dev/null
124768 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
124769 @@ -0,0 +1,918 @@
124770 +/*
124771 + * Copyright 2008-2012 Freescale Semiconductor Inc.
124772 + *
124773 + * Redistribution and use in source and binary forms, with or without
124774 + * modification, are permitted provided that the following conditions are met:
124775 + * * Redistributions of source code must retain the above copyright
124776 + * notice, this list of conditions and the following disclaimer.
124777 + * * Redistributions in binary form must reproduce the above copyright
124778 + * notice, this list of conditions and the following disclaimer in the
124779 + * documentation and/or other materials provided with the distribution.
124780 + * * Neither the name of Freescale Semiconductor nor the
124781 + * names of its contributors may be used to endorse or promote products
124782 + * derived from this software without specific prior written permission.
124783 + *
124784 + *
124785 + * ALTERNATIVELY, this software may be distributed under the terms of the
124786 + * GNU General Public License ("GPL") as published by the Free Software
124787 + * Foundation, either version 2 of that License or (at your option) any
124788 + * later version.
124789 + *
124790 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124791 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124792 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124793 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124794 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124795 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124796 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124797 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124798 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124799 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124800 + */
124801 +
124802 +/**************************************************************************//**
124803 + @File xx_linux.c
124804 +
124805 + @Description XX routines implementation for Linux.
124806 +*//***************************************************************************/
124807 +#include <linux/version.h>
124808 +
124809 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
124810 +#define MODVERSIONS
124811 +#endif
124812 +#ifdef MODVERSIONS
124813 +#include <config/modversions.h>
124814 +#endif /* MODVERSIONS */
124815 +
124816 +#include <linux/module.h>
124817 +#include <linux/kernel.h>
124818 +#include <linux/sched.h>
124819 +#include <linux/string.h>
124820 +#include <linux/ptrace.h>
124821 +#include <linux/errno.h>
124822 +#include <linux/ioport.h>
124823 +#include <linux/slab.h>
124824 +#include <linux/interrupt.h>
124825 +#include <linux/fs.h>
124826 +#include <linux/vmalloc.h>
124827 +#include <linux/init.h>
124828 +#include <linux/timer.h>
124829 +#include <linux/spinlock.h>
124830 +#include <linux/delay.h>
124831 +#include <linux/proc_fs.h>
124832 +#include <linux/smp.h>
124833 +#include <linux/of.h>
124834 +#ifdef CONFIG_FMAN_ARM
124835 +#include <linux/irqdomain.h>
124836 +#endif
124837 +
124838 +#include <linux/workqueue.h>
124839 +
124840 +#ifdef BIGPHYSAREA_ENABLE
124841 +#include <linux/bigphysarea.h>
124842 +#endif /* BIGPHYSAREA_ENABLE */
124843 +
124844 +#ifndef CONFIG_FMAN_ARM
124845 +#include <sysdev/fsl_soc.h>
124846 +#endif
124847 +#include <asm/pgtable.h>
124848 +#include <asm/irq.h>
124849 +#include <asm/bitops.h>
124850 +#include <asm/uaccess.h>
124851 +#include <asm/io.h>
124852 +#include <asm/atomic.h>
124853 +#include <asm/string.h>
124854 +#include <asm/byteorder.h>
124855 +#include <asm/page.h>
124856 +
124857 +#include "error_ext.h"
124858 +#include "std_ext.h"
124859 +#include "list_ext.h"
124860 +#include "mm_ext.h"
124861 +#include "sys_io_ext.h"
124862 +#include "xx.h"
124863 +
124864 +
124865 +#define __ERR_MODULE__ MODULE_UNKNOWN
124866 +
124867 +#ifdef BIGPHYSAREA_ENABLE
124868 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
124869 +
124870 +
124871 +/* TODO: large allocations => use big phys area */
124872 +/******************************************************************************
124873 + * routine: get_nr_pages
124874 + *
124875 + * description:
124876 + * calculates the number of memory pages for a given size (in bytes)
124877 + *
124878 + * arguments:
124879 + * size - the number of bytes
124880 + *
124881 + * return code:
124882 + * The number of pages
124883 + *
124884 + *****************************************************************************/
124885 +static __inline__ uint32_t get_nr_pages (uint32_t size)
124886 +{
124887 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
124888 +}
124889 +
124890 +static bool in_big_phys_area (uint32_t addr)
124891 +{
124892 + uint32_t base, size;
124893 +
124894 + bigphysarea_get_details (&base, &size);
124895 + return ((addr >= base) && (addr < base + size));
124896 +}
124897 +#endif /* BIGPHYSAREA_ENABLE */
124898 +
124899 +void * xx_Malloc(uint32_t n)
124900 +{
124901 + void *a;
124902 + uint32_t flags;
124903 +
124904 + flags = XX_DisableAllIntr();
124905 +#ifdef BIGPHYSAREA_ENABLE
124906 + if (n >= MAX_ALLOCATION_SIZE)
124907 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
124908 + else
124909 +#endif /* BIGPHYSAREA_ENABLE */
124910 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
124911 + if (!a)
124912 + XX_Print("No memory for XX_Malloc\n");
124913 + XX_RestoreAllIntr(flags);
124914 +
124915 + return a;
124916 +}
124917 +
124918 +void xx_Free(void *p)
124919 +{
124920 +#ifdef BIGPHYSAREA_ENABLE
124921 + if (in_big_phys_area ((uint32_t)p))
124922 + bigphysarea_free_pages(p);
124923 + else
124924 +#endif /* BIGPHYSAREA_ENABLE */
124925 + kfree(p);
124926 +}
124927 +
124928 +void XX_Exit(int status)
124929 +{
124930 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
124931 +}
124932 +
124933 +#define BUF_SIZE 512
124934 +void XX_Print(char *str, ...)
124935 +{
124936 + va_list args;
124937 +#ifdef CONFIG_SMP
124938 + char buf[BUF_SIZE];
124939 +#endif /* CONFIG_SMP */
124940 +
124941 + va_start(args, str);
124942 +#ifdef CONFIG_SMP
124943 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124944 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124945 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
124946 +#else
124947 + vprintk(str, args);
124948 +#endif /* CONFIG_SMP */
124949 + va_end(args);
124950 +}
124951 +
124952 +void XX_Fprint(void *file, char *str, ...)
124953 +{
124954 + va_list args;
124955 +#ifdef CONFIG_SMP
124956 + char buf[BUF_SIZE];
124957 +#endif /* CONFIG_SMP */
124958 +
124959 + va_start(args, str);
124960 +#ifdef CONFIG_SMP
124961 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124962 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124963 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
124964 +
124965 +#else
124966 + vprintk(str, args);
124967 +#endif /* CONFIG_SMP */
124968 + va_end(args);
124969 +}
124970 +
124971 +#ifdef DEBUG_XX_MALLOC
124972 +typedef void (*t_ffn)(void *);
124973 +typedef struct {
124974 + t_ffn f_free;
124975 + void *mem;
124976 + char *fname;
124977 + int fline;
124978 + uint32_t size;
124979 + t_List node;
124980 +} t_MemDebug;
124981 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
124982 +
124983 +LIST(memDbgLst);
124984 +
124985 +
124986 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
124987 +{
124988 + void *mem;
124989 + t_MemDebug *p_MemDbg;
124990 +
124991 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
124992 + if (p_MemDbg == NULL)
124993 + return NULL;
124994 +
124995 + mem = xx_Malloc(size);
124996 + if (mem == NULL)
124997 + {
124998 + XX_Free(p_MemDbg);
124999 + return NULL;
125000 + }
125001 +
125002 + INIT_LIST(&p_MemDbg->node);
125003 + p_MemDbg->f_free = xx_Free;
125004 + p_MemDbg->mem = mem;
125005 + p_MemDbg->fname = fname;
125006 + p_MemDbg->fline = line;
125007 + p_MemDbg->size = size+sizeof(t_MemDebug);
125008 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
125009 +
125010 + return mem;
125011 +}
125012 +
125013 +void * XX_MallocSmartDebug(uint32_t size,
125014 + int memPartitionId,
125015 + uint32_t align,
125016 + char *fname,
125017 + int line)
125018 +{
125019 + void *mem;
125020 + t_MemDebug *p_MemDbg;
125021 +
125022 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
125023 + if (p_MemDbg == NULL)
125024 + return NULL;
125025 +
125026 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
125027 + if (mem == NULL)
125028 + {
125029 + XX_Free(p_MemDbg);
125030 + return NULL;
125031 + }
125032 +
125033 + INIT_LIST(&p_MemDbg->node);
125034 + p_MemDbg->f_free = xx_FreeSmart;
125035 + p_MemDbg->mem = mem;
125036 + p_MemDbg->fname = fname;
125037 + p_MemDbg->fline = line;
125038 + p_MemDbg->size = size+sizeof(t_MemDebug);
125039 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
125040 +
125041 + return mem;
125042 +}
125043 +
125044 +static void debug_free(void *mem)
125045 +{
125046 + t_List *p_MemDbgLh = NULL;
125047 + t_MemDebug *p_MemDbg;
125048 + bool found = FALSE;
125049 +
125050 + if (LIST_IsEmpty(&memDbgLst))
125051 + {
125052 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
125053 + return;
125054 + }
125055 +
125056 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
125057 + {
125058 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
125059 + if (p_MemDbg->mem == mem)
125060 + {
125061 + found = TRUE;
125062 + break;
125063 + }
125064 + }
125065 +
125066 + if (!found)
125067 + {
125068 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
125069 + ("Attempt to free unallocated address (0x%08x)",mem));
125070 + dump_stack();
125071 + return;
125072 + }
125073 +
125074 + LIST_Del(p_MemDbgLh);
125075 + p_MemDbg->f_free(mem);
125076 + p_MemDbg->f_free(p_MemDbg);
125077 +}
125078 +
125079 +void XX_FreeSmart(void *p)
125080 +{
125081 + debug_free(p);
125082 +}
125083 +
125084 +
125085 +void XX_Free(void *p)
125086 +{
125087 + debug_free(p);
125088 +}
125089 +
125090 +#else /* not DEBUG_XX_MALLOC */
125091 +void * XX_Malloc(uint32_t size)
125092 +{
125093 + return xx_Malloc(size);
125094 +}
125095 +
125096 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
125097 +{
125098 + return xx_MallocSmart(size,memPartitionId, alignment);
125099 +}
125100 +
125101 +void XX_FreeSmart(void *p)
125102 +{
125103 + xx_FreeSmart(p);
125104 +}
125105 +
125106 +
125107 +void XX_Free(void *p)
125108 +{
125109 + xx_Free(p);
125110 +}
125111 +#endif /* not DEBUG_XX_MALLOC */
125112 +
125113 +
125114 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
125115 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
125116 +{
125117 + e_Event eventCode = (e_Event)event;
125118 +
125119 + UNUSED(eventCode);
125120 + UNUSED(appId);
125121 + UNUSED(flags);
125122 + UNUSED(msg);
125123 +}
125124 +#endif /* (defined(REPORT_EVENTS) && ... */
125125 +
125126 +
125127 +uint32_t XX_DisableAllIntr(void)
125128 +{
125129 + unsigned long flags;
125130 +
125131 +#ifdef local_irq_save_nort
125132 + local_irq_save_nort(flags);
125133 +#else
125134 + local_irq_save(flags);
125135 +#endif
125136 +
125137 + return (uint32_t)flags;
125138 +}
125139 +
125140 +void XX_RestoreAllIntr(uint32_t flags)
125141 +{
125142 +#ifdef local_irq_restore_nort
125143 + local_irq_restore_nort((unsigned long)flags);
125144 +#else
125145 + local_irq_restore((unsigned long)flags);
125146 +#endif
125147 +}
125148 +
125149 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
125150 +{
125151 + UNUSED(qid);
125152 + UNUSED(appId);
125153 + UNUSED(flags);
125154 +
125155 + return f(id);
125156 +}
125157 +
125158 +int XX_IsICacheEnable(void)
125159 +{
125160 + return TRUE;
125161 +}
125162 +
125163 +int XX_IsDCacheEnable(void)
125164 +{
125165 + return TRUE;
125166 +}
125167 +
125168 +
125169 +typedef struct {
125170 + t_Isr *f_Isr;
125171 + t_Handle handle;
125172 +} t_InterruptHandler;
125173 +
125174 +
125175 +t_Handle interruptHandlers[0x00010000];
125176 +
125177 +#ifdef CONFIG_FMAN_ARM
125178 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
125179 +{
125180 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
125181 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
125182 + return IRQ_HANDLED;
125183 +}
125184 +#endif
125185 +
125186 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
125187 +{
125188 +#ifdef CONFIG_FMAN_ARM
125189 + const char *device;
125190 + t_InterruptHandler *p_IntrHndl;
125191 +
125192 + device = GetDeviceName(irq);
125193 + if (device == NULL)
125194 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
125195 +
125196 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
125197 + if (p_IntrHndl == NULL)
125198 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
125199 + p_IntrHndl->f_Isr = f_Isr;
125200 + p_IntrHndl->handle = handle;
125201 + interruptHandlers[irq] = p_IntrHndl;
125202 +
125203 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
125204 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
125205 + disable_irq(GetDeviceIrqNum(irq));
125206 +#endif
125207 + return E_OK;
125208 +}
125209 +
125210 +t_Error XX_FreeIntr(int irq)
125211 +{
125212 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
125213 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
125214 + XX_Free(p_IntrHndl);
125215 + interruptHandlers[irq] = 0;
125216 + return E_OK;
125217 +}
125218 +
125219 +t_Error XX_EnableIntr(int irq)
125220 +{
125221 + enable_irq(GetDeviceIrqNum(irq));
125222 + return E_OK;
125223 +}
125224 +
125225 +t_Error XX_DisableIntr(int irq)
125226 +{
125227 + disable_irq(GetDeviceIrqNum(irq));
125228 + return E_OK;
125229 +}
125230 +
125231 +
125232 +/*****************************************************************************/
125233 +/* Tasklet Service Routines */
125234 +/*****************************************************************************/
125235 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
125236 +typedef struct
125237 +{
125238 + t_Handle h_Data;
125239 + void (*f_Callback) (void *);
125240 + struct delayed_work dwork;
125241 +} t_Tasklet;
125242 +
125243 +static void GenericTaskletCallback(struct work_struct *p_Work)
125244 +{
125245 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
125246 +
125247 + p_Task->f_Callback(p_Task->h_Data);
125248 +}
125249 +#endif /* LINUX_VERSION_CODE */
125250 +
125251 +
125252 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
125253 +{
125254 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125255 + struct work_struct *p_Task;
125256 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
125257 + INIT_WORK(p_Task, routine, data);
125258 +#else
125259 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
125260 + p_Task->h_Data = data;
125261 + p_Task->f_Callback = routine;
125262 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
125263 +#endif /* LINUX_VERSION_CODE */
125264 +
125265 + return (t_TaskletHandle)p_Task;
125266 +}
125267 +
125268 +
125269 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
125270 +{
125271 + if (h_Tasklet)
125272 + XX_Free(h_Tasklet);
125273 +}
125274 +
125275 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
125276 +{
125277 + int ans;
125278 +
125279 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125280 + if (immediate)
125281 + ans = schedule_work(h_Tasklet);
125282 + else
125283 + ans = schedule_delayed_work(h_Tasklet, 1);
125284 +#else
125285 + if (immediate)
125286 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
125287 + else
125288 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
125289 +#endif /* LINUX_VERSION_CODE */
125290 +
125291 + return ans;
125292 +}
125293 +
125294 +void XX_FlushScheduledTasks(void)
125295 +{
125296 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
125297 + flush_scheduled_tasks();
125298 +#else
125299 + flush_scheduled_work();
125300 +#endif /* LINUX_VERSION_CODE */
125301 +}
125302 +
125303 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
125304 +{
125305 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125306 + return (int)(((struct work_struct *)h_Tasklet)->pending);
125307 +#else
125308 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
125309 +#endif /* LINUX_VERSION_CODE */
125310 +}
125311 +
125312 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
125313 +{
125314 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
125315 + ((struct tq_struct *)h_Tasklet)->data = data;
125316 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125317 + ((struct work_struct *)h_Tasklet)->data = data;
125318 +#else
125319 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
125320 +#endif /* LINUX_VERSION_CODE */
125321 +}
125322 +
125323 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
125324 +{
125325 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125326 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
125327 +#else
125328 + return ((t_Tasklet *)h_Tasklet)->h_Data;
125329 +#endif /* LINUX_VERSION_CODE */
125330 +}
125331 +
125332 +
125333 +/*****************************************************************************/
125334 +/* Spinlock Service Routines */
125335 +/*****************************************************************************/
125336 +
125337 +t_Handle XX_InitSpinlock(void)
125338 +{
125339 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
125340 + if (!p_Spinlock)
125341 + return NULL;
125342 +
125343 + spin_lock_init(p_Spinlock);
125344 +
125345 + return (t_Handle)p_Spinlock;
125346 +}
125347 +
125348 +void XX_FreeSpinlock(t_Handle h_Spinlock)
125349 +{
125350 + if (h_Spinlock)
125351 + XX_Free(h_Spinlock);
125352 +}
125353 +
125354 +void XX_LockSpinlock(t_Handle h_Spinlock)
125355 +{
125356 + spin_lock((spinlock_t *)h_Spinlock);
125357 +}
125358 +
125359 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
125360 +{
125361 + spin_unlock((spinlock_t *)h_Spinlock);
125362 +}
125363 +
125364 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
125365 +{
125366 + unsigned long intrFlags;
125367 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
125368 + return intrFlags;
125369 +}
125370 +
125371 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
125372 +{
125373 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
125374 +}
125375 +
125376 +
125377 +/*****************************************************************************/
125378 +/* Timers Service Routines */
125379 +/*****************************************************************************/
125380 +/* The time now is in mili sec. resolution */
125381 +uint32_t XX_CurrentTime(void)
125382 +{
125383 + return (jiffies*1000)/HZ;
125384 +}
125385 +
125386 +
125387 +t_Handle XX_CreateTimer(void)
125388 +{
125389 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
125390 + if (p_Timer)
125391 + {
125392 + memset(p_Timer, 0, sizeof(struct timer_list));
125393 + init_timer(p_Timer);
125394 + }
125395 + return (t_Handle)p_Timer;
125396 +}
125397 +
125398 +void XX_FreeTimer(t_Handle h_Timer)
125399 +{
125400 + if (h_Timer)
125401 + XX_Free(h_Timer);
125402 +}
125403 +
125404 +void XX_StartTimer(t_Handle h_Timer,
125405 + uint32_t msecs,
125406 + bool periodic,
125407 + void (*f_TimerExpired)(t_Handle),
125408 + t_Handle h_Arg)
125409 +{
125410 + int tmp_jiffies = (msecs*HZ)/1000;
125411 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125412 +
125413 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
125414 +
125415 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
125416 + p_Timer->data = (unsigned long)h_Arg;
125417 + if ((msecs*HZ)%1000)
125418 + tmp_jiffies++;
125419 + p_Timer->expires = (jiffies + tmp_jiffies);
125420 +
125421 + add_timer((struct timer_list *)h_Timer);
125422 +}
125423 +
125424 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
125425 +{
125426 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125427 +
125428 + p_Timer->data = (unsigned long)data;
125429 +}
125430 +
125431 +t_Handle XX_GetTimerData(t_Handle h_Timer)
125432 +{
125433 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125434 +
125435 + return (t_Handle)p_Timer->data;
125436 +}
125437 +
125438 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
125439 +{
125440 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125441 +
125442 + return (uint32_t)p_Timer->expires;
125443 +}
125444 +
125445 +void XX_StopTimer(t_Handle h_Timer)
125446 +{
125447 + del_timer((struct timer_list *)h_Timer);
125448 +}
125449 +
125450 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
125451 +{
125452 + int tmp_jiffies = (msecs*HZ)/1000;
125453 +
125454 + if ((msecs*HZ)%1000)
125455 + tmp_jiffies++;
125456 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
125457 +}
125458 +
125459 +int XX_TimerIsActive(t_Handle h_Timer)
125460 +{
125461 + return timer_pending((struct timer_list *)h_Timer);
125462 +}
125463 +
125464 +uint32_t XX_Sleep(uint32_t msecs)
125465 +{
125466 + int tmp_jiffies = (msecs*HZ)/1000;
125467 +
125468 + if ((msecs*HZ)%1000)
125469 + tmp_jiffies++;
125470 + return schedule_timeout(tmp_jiffies);
125471 +}
125472 +
125473 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
125474 +void XX_UDelay(uint32_t usecs)
125475 +{
125476 + udelay(usecs);
125477 +}
125478 +
125479 +/* TODO: verify that these are correct */
125480 +#define MSG_BODY_SIZE 512
125481 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
125482 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
125483 +t_Error XX_SendMessage(char *p_DestAddr,
125484 + uint32_t msgId,
125485 + uint8_t msgBody[MSG_BODY_SIZE],
125486 + t_MsgCompletionCB *f_CompletionCB,
125487 + t_Handle h_CBArg);
125488 +
125489 +typedef struct {
125490 + char *p_Addr;
125491 + t_MsgHandler *f_MsgHandlerCB;
125492 + t_Handle h_Mod;
125493 + t_List node;
125494 +} t_MsgHndlr;
125495 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
125496 +
125497 +LIST(msgHndlrList);
125498 +
125499 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
125500 +{
125501 + uint32_t intFlags;
125502 +
125503 + intFlags = XX_DisableAllIntr();
125504 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
125505 + XX_RestoreAllIntr(intFlags);
125506 +}
125507 +/* TODO: add this for multi-platform support
125508 +static t_MsgHndlr * DequeueMsgHndlr(void)
125509 +{
125510 + t_MsgHndlr *p_MsgHndlr = NULL;
125511 + uint32_t intFlags;
125512 +
125513 + intFlags = XX_DisableAllIntr();
125514 + if (!LIST_IsEmpty(&msgHndlrList))
125515 + {
125516 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
125517 + LIST_DelAndInit(&p_MsgHndlr->node);
125518 + }
125519 + XX_RestoreAllIntr(intFlags);
125520 +
125521 + return p_MsgHndlr;
125522 +}
125523 +*/
125524 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
125525 +{
125526 + t_MsgHndlr *p_MsgHndlr;
125527 + t_List *p_Pos;
125528 +
125529 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
125530 + {
125531 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
125532 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
125533 + return p_MsgHndlr;
125534 + }
125535 +
125536 + return NULL;
125537 +}
125538 +
125539 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
125540 +{
125541 + t_MsgHndlr *p_MsgHndlr;
125542 + uint32_t len;
125543 +
125544 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
125545 + if (!p_MsgHndlr)
125546 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
125547 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
125548 +
125549 + len = strlen(p_Addr);
125550 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
125551 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
125552 +
125553 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
125554 + p_MsgHndlr->h_Mod = h_Mod;
125555 + INIT_LIST(&p_MsgHndlr->node);
125556 + EnqueueMsgHndlr(p_MsgHndlr);
125557 +
125558 + return E_OK;
125559 +}
125560 +
125561 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
125562 +{
125563 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
125564 + if (!p_MsgHndlr)
125565 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
125566 +
125567 + LIST_Del(&p_MsgHndlr->node);
125568 + XX_Free(p_MsgHndlr->p_Addr);
125569 + XX_Free(p_MsgHndlr);
125570 +
125571 + return E_OK;
125572 +}
125573 +
125574 +t_Error XX_SendMessage(char *p_DestAddr,
125575 + uint32_t msgId,
125576 + uint8_t msgBody[MSG_BODY_SIZE],
125577 + t_MsgCompletionCB *f_CompletionCB,
125578 + t_Handle h_CBArg)
125579 +{
125580 + t_Error ans;
125581 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
125582 + if (!p_MsgHndlr)
125583 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
125584 +
125585 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
125586 +
125587 + if (f_CompletionCB)
125588 + f_CompletionCB(h_CBArg, msgBody);
125589 +
125590 + return ans;
125591 +}
125592 +
125593 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
125594 + t_IpcMsgHandler *f_MsgHandler,
125595 + t_Handle h_Module,
125596 + uint32_t replyLength)
125597 +{
125598 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
125599 + return E_OK;
125600 +}
125601 +
125602 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
125603 +{
125604 + UNUSED(addr);
125605 + return E_OK;
125606 +}
125607 +
125608 +
125609 +t_Error XX_IpcSendMessage(t_Handle h_Session,
125610 + uint8_t *p_Msg,
125611 + uint32_t msgLength,
125612 + uint8_t *p_Reply,
125613 + uint32_t *p_ReplyLength,
125614 + t_IpcMsgCompletion *f_Completion,
125615 + t_Handle h_Arg)
125616 +{
125617 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
125618 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
125619 + return E_OK;
125620 +}
125621 +
125622 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
125623 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
125624 +{
125625 + UNUSED(destAddr); UNUSED(srcAddr);
125626 + return E_OK;
125627 +}
125628 +
125629 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
125630 +uint32_t E500_GetId(void)
125631 +{
125632 + return raw_smp_processor_id();
125633 +}
125634 +
125635 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
125636 +int GetDeviceIrqNum(int irq)
125637 +{
125638 + struct device_node *iPar;
125639 + struct irq_domain *irqHost;
125640 + uint32_t hwIrq;
125641 +
125642 + /* Get the interrupt controller */
125643 + iPar = of_find_node_by_name(NULL, "mpic");
125644 + hwIrq = 0;
125645 +
125646 + ASSERT_COND(iPar != NULL);
125647 + /* Get the irq host */
125648 + irqHost = irq_find_host(iPar);
125649 + of_node_put(iPar);
125650 +
125651 + /* Create irq mapping */
125652 + return irq_create_mapping(irqHost, hwIrq);
125653 +}
125654 +#else
125655 +#error "kernel not supported!!!"
125656 +#endif /* LINUX_VERSION_CODE */
125657 +
125658 +void * XX_PhysToVirt(physAddress_t addr)
125659 +{
125660 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
125661 +}
125662 +
125663 +physAddress_t XX_VirtToPhys(void * addr)
125664 +{
125665 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
125666 +}
125667 +
125668 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
125669 +{
125670 + uintptr_t *returnCode, tmp;
125671 +
125672 + if (alignment < sizeof(uintptr_t))
125673 + alignment = sizeof(uintptr_t);
125674 + size += alignment + sizeof(returnCode);
125675 + tmp = (uintptr_t)xx_Malloc(size);
125676 + if (tmp == 0)
125677 + return NULL;
125678 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
125679 + *(returnCode - 1) = tmp;
125680 +
125681 + return (void*)returnCode;
125682 +}
125683 +
125684 +void xx_FreeSmart(void *p)
125685 +{
125686 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
125687 +}
125688 --- /dev/null
125689 +++ b/drivers/staging/fsl_qbman/Kconfig
125690 @@ -0,0 +1,228 @@
125691 +config FSL_SDK_DPA
125692 + bool "Freescale Datapath Queue and Buffer management"
125693 + depends on !FSL_DPAA
125694 + select FSL_QMAN_FQ_LOOKUP if PPC64
125695 + select FSL_QMAN_FQ_LOOKUP if ARM64
125696 +
125697 +
125698 +menu "Freescale Datapath QMan/BMan options"
125699 + depends on FSL_SDK_DPA
125700 +
125701 +config FSL_DPA_CHECKING
125702 + bool "additional driver checking"
125703 + default n
125704 + ---help---
125705 + Compiles in additional checks to sanity-check the drivers and any
125706 + use of it by other code. Not recommended for performance.
125707 +
125708 +config FSL_DPA_CAN_WAIT
125709 + bool
125710 + default y
125711 +
125712 +config FSL_DPA_CAN_WAIT_SYNC
125713 + bool
125714 + default y
125715 +
125716 +config FSL_DPA_PIRQ_FAST
125717 + bool
125718 + default y
125719 +
125720 +config FSL_DPA_PIRQ_SLOW
125721 + bool
125722 + default y
125723 +
125724 +config FSL_DPA_PORTAL_SHARE
125725 + bool
125726 + default y
125727 +
125728 +config FSL_SDK_BMAN
125729 + bool "Freescale Buffer Manager (BMan) support"
125730 + default y
125731 +
125732 +if FSL_SDK_BMAN
125733 +
125734 +config FSL_BMAN_CONFIG
125735 + bool "BMan device management"
125736 + default y
125737 + ---help---
125738 + If this linux image is running natively, you need this option. If this
125739 + linux image is running as a guest OS under the hypervisor, only one
125740 + guest OS ("the control plane") needs this option.
125741 +
125742 +config FSL_BMAN_TEST
125743 + tristate "BMan self-tests"
125744 + default n
125745 + ---help---
125746 + This option compiles self-test code for BMan.
125747 +
125748 +config FSL_BMAN_TEST_HIGH
125749 + bool "BMan high-level self-test"
125750 + depends on FSL_BMAN_TEST
125751 + default y
125752 + ---help---
125753 + This requires the presence of cpu-affine portals, and performs
125754 + high-level API testing with them (whichever portal(s) are affine to
125755 + the cpu(s) the test executes on).
125756 +
125757 +config FSL_BMAN_TEST_THRESH
125758 + bool "BMan threshold test"
125759 + depends on FSL_BMAN_TEST
125760 + default y
125761 + ---help---
125762 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
125763 + before multiple threads (one per cpu) create pool objects to track
125764 + depletion state changes. The pool is then drained to empty by a
125765 + "drainer" thread, and the other threads that they observe exactly
125766 + the depletion state changes that are expected.
125767 +
125768 +config FSL_BMAN_DEBUGFS
125769 + tristate "BMan debugfs interface"
125770 + depends on DEBUG_FS
125771 + default y
125772 + ---help---
125773 + This option compiles debugfs code for BMan.
125774 +
125775 +endif # FSL_SDK_BMAN
125776 +
125777 +config FSL_SDK_QMAN
125778 + bool "Freescale Queue Manager (QMan) support"
125779 + default y
125780 +
125781 +if FSL_SDK_QMAN
125782 +
125783 +config FSL_QMAN_POLL_LIMIT
125784 + int
125785 + default 32
125786 +
125787 +config FSL_QMAN_CONFIG
125788 + bool "QMan device management"
125789 + default y
125790 + ---help---
125791 + If this linux image is running natively, you need this option. If this
125792 + linux image is running as a guest OS under the hypervisor, only one
125793 + guest OS ("the control plane") needs this option.
125794 +
125795 +config FSL_QMAN_TEST
125796 + tristate "QMan self-tests"
125797 + default n
125798 + ---help---
125799 + This option compiles self-test code for QMan.
125800 +
125801 +config FSL_QMAN_TEST_STASH_POTATO
125802 + bool "QMan 'hot potato' data-stashing self-test"
125803 + depends on FSL_QMAN_TEST
125804 + default y
125805 + ---help---
125806 + This performs a "hot potato" style test enqueuing/dequeuing a frame
125807 + across a series of FQs scheduled to different portals (and cpus), with
125808 + DQRR, data and context stashing always on.
125809 +
125810 +config FSL_QMAN_TEST_HIGH
125811 + bool "QMan high-level self-test"
125812 + depends on FSL_QMAN_TEST
125813 + default y
125814 + ---help---
125815 + This requires the presence of cpu-affine portals, and performs
125816 + high-level API testing with them (whichever portal(s) are affine to
125817 + the cpu(s) the test executes on).
125818 +
125819 +config FSL_QMAN_DEBUGFS
125820 + tristate "QMan debugfs interface"
125821 + depends on DEBUG_FS
125822 + default y
125823 + ---help---
125824 + This option compiles debugfs code for QMan.
125825 +
125826 +# H/w settings that can be hard-coded for now.
125827 +config FSL_QMAN_FQD_SZ
125828 + int "size of Frame Queue Descriptor region"
125829 + default 10
125830 + ---help---
125831 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
125832 + ex: 10 => PAGE_SIZE * (2^10)
125833 + Note: Default device-trees now require minimum Kconfig setting of 10.
125834 +
125835 +config FSL_QMAN_PFDR_SZ
125836 + int "size of the PFDR pool"
125837 + default 13
125838 + ---help---
125839 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
125840 + ex: 13 => PAGE_SIZE * (2^13)
125841 +
125842 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
125843 +# ability to snart. Stash priority is 3, other priorities are 2.
125844 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
125845 + int
125846 + depends on FSL_QMAN_CONFIG
125847 + default 4
125848 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
125849 + int
125850 + depends on FSL_QMAN_CONFIG
125851 + default 3
125852 +config FSL_QMAN_CI_SCHED_CFG_RW_W
125853 + int
125854 + depends on FSL_QMAN_CONFIG
125855 + default 2
125856 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
125857 + int
125858 + depends on FSL_QMAN_CONFIG
125859 + default 2
125860 +
125861 +# portal interrupt settings
125862 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
125863 + int
125864 + default 12
125865 +config FSL_QMAN_PIRQ_MR_ITHRESH
125866 + int
125867 + default 4
125868 +config FSL_QMAN_PIRQ_IPERIOD
125869 + int
125870 + default 100
125871 +
125872 +# 64 bit kernel support
125873 +config FSL_QMAN_FQ_LOOKUP
125874 + bool
125875 + default n
125876 +
125877 +config QMAN_CEETM_UPDATE_PERIOD
125878 + int "Token update period for shaping, in nanoseconds"
125879 + default 1000
125880 + ---help---
125881 + Traffic shaping works by performing token calculations (using
125882 + credits) on shaper instances periodically. This update period
125883 + sets the granularity for how often those token rate credit
125884 + updates are performed, and thus determines the accuracy and
125885 + range of traffic rates that can be configured by users. The
125886 + reference manual recommends a 1 microsecond period as providing
125887 + a good balance between granularity and range.
125888 +
125889 + Unless you know what you are doing, leave this value at its default.
125890 +
125891 +config FSL_QMAN_INIT_TIMEOUT
125892 + int "timeout for qman init stage, in seconds"
125893 + default 10
125894 + ---help---
125895 + The timeout setting to quit the initialization loop for non-control
125896 + partition in case the control partition fails to boot-up.
125897 +
125898 +endif # FSL_SDK_QMAN
125899 +
125900 +config FSL_USDPAA
125901 + bool "Freescale USDPAA process driver"
125902 + depends on FSL_SDK_DPA
125903 + default y
125904 + ---help---
125905 + This driver provides user-space access to kernel-managed
125906 + resource interfaces for USDPAA applications, on the assumption
125907 + that each process will open this device once. Specifically, this
125908 + device exposes functionality that would be awkward if exposed
125909 + via the portal devices - ie. this device exposes functionality
125910 + that is inherently process-wide rather than portal-specific.
125911 + This device is necessary for obtaining access to DMA memory and
125912 + for allocation of Qman and Bman resources. In short, if you wish
125913 + to use USDPAA applications, you need this.
125914 +
125915 + If unsure, say Y.
125916 +
125917 +
125918 +endmenu
125919 --- /dev/null
125920 +++ b/drivers/staging/fsl_qbman/Makefile
125921 @@ -0,0 +1,28 @@
125922 +subdir-ccflags-y := -Werror
125923 +
125924 +# Common
125925 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
125926 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
125927 +
125928 +# Bman
125929 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
125930 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
125931 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
125932 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
125933 +bman_tester-y = bman_test.o
125934 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
125935 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
125936 +bman_debugfs_interface-y = bman_debugfs.o
125937 +
125938 +# Qman
125939 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
125940 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
125941 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
125942 +qman_tester-y = qman_test.o
125943 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
125944 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
125945 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
125946 +qman_debugfs_interface-y = qman_debugfs.o
125947 +
125948 +# USDPAA
125949 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
125950 --- /dev/null
125951 +++ b/drivers/staging/fsl_qbman/bman_config.c
125952 @@ -0,0 +1,720 @@
125953 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
125954 + *
125955 + * Redistribution and use in source and binary forms, with or without
125956 + * modification, are permitted provided that the following conditions are met:
125957 + * * Redistributions of source code must retain the above copyright
125958 + * notice, this list of conditions and the following disclaimer.
125959 + * * Redistributions in binary form must reproduce the above copyright
125960 + * notice, this list of conditions and the following disclaimer in the
125961 + * documentation and/or other materials provided with the distribution.
125962 + * * Neither the name of Freescale Semiconductor nor the
125963 + * names of its contributors may be used to endorse or promote products
125964 + * derived from this software without specific prior written permission.
125965 + *
125966 + *
125967 + * ALTERNATIVELY, this software may be distributed under the terms of the
125968 + * GNU General Public License ("GPL") as published by the Free Software
125969 + * Foundation, either version 2 of that License or (at your option) any
125970 + * later version.
125971 + *
125972 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125973 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125974 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125975 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125976 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125977 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125978 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125979 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125980 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125981 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125982 + */
125983 +
125984 +#include <asm/cacheflush.h>
125985 +#include "bman_private.h"
125986 +#include <linux/of_reserved_mem.h>
125987 +
125988 +/* Last updated for v00.79 of the BG */
125989 +
125990 +struct bman;
125991 +
125992 +/* Register offsets */
125993 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
125994 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
125995 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
125996 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
125997 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
125998 +#define REG_FBPR_FPC 0x0800
125999 +#define REG_STATE_IDLE 0x960
126000 +#define REG_STATE_STOP 0x964
126001 +#define REG_ECSR 0x0a00
126002 +#define REG_ECIR 0x0a04
126003 +#define REG_EADR 0x0a08
126004 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
126005 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
126006 +#define REG_IP_REV_1 0x0bf8
126007 +#define REG_IP_REV_2 0x0bfc
126008 +#define REG_FBPR_BARE 0x0c00
126009 +#define REG_FBPR_BAR 0x0c04
126010 +#define REG_FBPR_AR 0x0c10
126011 +#define REG_SRCIDR 0x0d04
126012 +#define REG_LIODNR 0x0d08
126013 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
126014 +
126015 +/* Used by all error interrupt registers except 'inhibit' */
126016 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
126017 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
126018 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
126019 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
126020 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
126021 +
126022 +/* BMAN_ECIR valid error bit */
126023 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
126024 +
126025 +union bman_ecir {
126026 + u32 ecir_raw;
126027 + struct {
126028 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
126029 + u32 __reserved1:4;
126030 + u32 portal_num:4;
126031 + u32 __reserved2:12;
126032 + u32 numb:4;
126033 + u32 __reserved3:2;
126034 + u32 pid:6;
126035 +#else
126036 + u32 pid:6;
126037 + u32 __reserved3:2;
126038 + u32 numb:4;
126039 + u32 __reserved2:12;
126040 + u32 portal_num:4;
126041 + u32 __reserved1:4;
126042 +#endif
126043 + } __packed info;
126044 +};
126045 +
126046 +union bman_eadr {
126047 + u32 eadr_raw;
126048 + struct {
126049 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
126050 + u32 __reserved1:5;
126051 + u32 memid:3;
126052 + u32 __reserved2:14;
126053 + u32 eadr:10;
126054 +#else
126055 + u32 eadr:10;
126056 + u32 __reserved2:14;
126057 + u32 memid:3;
126058 + u32 __reserved1:5;
126059 +#endif
126060 + } __packed info;
126061 +};
126062 +
126063 +struct bman_hwerr_txt {
126064 + u32 mask;
126065 + const char *txt;
126066 +};
126067 +
126068 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
126069 +
126070 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
126071 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
126072 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
126073 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
126074 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
126075 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
126076 +};
126077 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
126078 +
126079 +struct bman_error_info_mdata {
126080 + u16 addr_mask;
126081 + u16 bits;
126082 + const char *txt;
126083 +};
126084 +
126085 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
126086 +static const struct bman_error_info_mdata error_mdata[] = {
126087 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
126088 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
126089 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
126090 +};
126091 +#define BMAN_ERR_MDATA_COUNT \
126092 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
126093 +
126094 +/* Add this in Kconfig */
126095 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
126096 +
126097 +/**
126098 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
126099 + * @v: for accessors that write values, this is the 32-bit value
126100 + *
126101 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
126102 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
126103 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
126104 + * "write the enable register" rather than "enable the write register"!
126105 + */
126106 +#define bm_err_isr_status_read(bm) \
126107 + __bm_err_isr_read(bm, bm_isr_status)
126108 +#define bm_err_isr_status_clear(bm, m) \
126109 + __bm_err_isr_write(bm, bm_isr_status, m)
126110 +#define bm_err_isr_enable_read(bm) \
126111 + __bm_err_isr_read(bm, bm_isr_enable)
126112 +#define bm_err_isr_enable_write(bm, v) \
126113 + __bm_err_isr_write(bm, bm_isr_enable, v)
126114 +#define bm_err_isr_disable_read(bm) \
126115 + __bm_err_isr_read(bm, bm_isr_disable)
126116 +#define bm_err_isr_disable_write(bm, v) \
126117 + __bm_err_isr_write(bm, bm_isr_disable, v)
126118 +#define bm_err_isr_inhibit(bm) \
126119 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
126120 +#define bm_err_isr_uninhibit(bm) \
126121 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
126122 +
126123 +/*
126124 + * TODO: unimplemented registers
126125 + *
126126 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
126127 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
126128 + */
126129 +
126130 +/* Encapsulate "struct bman *" as a cast of the register space address. */
126131 +
126132 +static struct bman *bm_create(void *regs)
126133 +{
126134 + return (struct bman *)regs;
126135 +}
126136 +
126137 +static inline u32 __bm_in(struct bman *bm, u32 offset)
126138 +{
126139 + return in_be32((void *)bm + offset);
126140 +}
126141 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
126142 +{
126143 + out_be32((void *)bm + offset, val);
126144 +}
126145 +#define bm_in(reg) __bm_in(bm, REG_##reg)
126146 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
126147 +
126148 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
126149 +{
126150 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
126151 +}
126152 +
126153 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
126154 +{
126155 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
126156 +}
126157 +
126158 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
126159 +{
126160 + u32 v = bm_in(IP_REV_1);
126161 + *id = (v >> 16);
126162 + *major = (v >> 8) & 0xff;
126163 + *minor = v & 0xff;
126164 +}
126165 +
126166 +static u32 __generate_thresh(u32 val, int roundup)
126167 +{
126168 + u32 e = 0; /* co-efficient, exponent */
126169 + int oddbit = 0;
126170 + while (val > 0xff) {
126171 + oddbit = val & 1;
126172 + val >>= 1;
126173 + e++;
126174 + if (roundup && oddbit)
126175 + val++;
126176 + }
126177 + DPA_ASSERT(e < 0x10);
126178 + return val | (e << 8);
126179 +}
126180 +
126181 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
126182 + u32 hwdet, u32 hwdxt)
126183 +{
126184 + DPA_ASSERT(pool < bman_pool_max);
126185 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
126186 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
126187 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
126188 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
126189 +}
126190 +
126191 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
126192 +{
126193 + u32 exp = ilog2(size);
126194 + /* choke if size isn't within range */
126195 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
126196 + is_power_of_2(size));
126197 + /* choke if '[e]ba' has lower-alignment than 'size' */
126198 + DPA_ASSERT(!(ba & (size - 1)));
126199 + bm_out(FBPR_BARE, upper_32_bits(ba));
126200 + bm_out(FBPR_BAR, lower_32_bits(ba));
126201 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
126202 +}
126203 +
126204 +/*****************/
126205 +/* Config driver */
126206 +/*****************/
126207 +
126208 +/* TODO: Kconfig these? */
126209 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
126210 +
126211 +/* We support only one of these. */
126212 +static struct bman *bm;
126213 +static struct device_node *bm_node;
126214 +
126215 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
126216 + * during bman_init_ccsr(). */
126217 +static dma_addr_t fbpr_a;
126218 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
126219 +
126220 +static int bman_fbpr(struct reserved_mem *rmem)
126221 +{
126222 + fbpr_a = rmem->base;
126223 + fbpr_sz = rmem->size;
126224 +
126225 + WARN_ON(!(fbpr_a && fbpr_sz));
126226 +
126227 + return 0;
126228 +}
126229 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
126230 +
126231 +static int __init fsl_bman_init(struct device_node *node)
126232 +{
126233 + struct resource res;
126234 + u32 __iomem *regs;
126235 + const char *s;
126236 + int ret, standby = 0;
126237 + u16 id;
126238 + u8 major, minor;
126239 +
126240 + ret = of_address_to_resource(node, 0, &res);
126241 + if (ret) {
126242 + pr_err("Can't get %s property 'reg'\n",
126243 + node->full_name);
126244 + return ret;
126245 + }
126246 + s = of_get_property(node, "fsl,hv-claimable", &ret);
126247 + if (s && !strcmp(s, "standby"))
126248 + standby = 1;
126249 + /* Global configuration */
126250 + regs = ioremap(res.start, res.end - res.start + 1);
126251 + bm = bm_create(regs);
126252 + BUG_ON(!bm);
126253 + bm_node = node;
126254 + bm_get_version(bm, &id, &major, &minor);
126255 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
126256 + if ((major == 1) && (minor == 0)) {
126257 + bman_ip_rev = BMAN_REV10;
126258 + bman_pool_max = 64;
126259 + } else if ((major == 2) && (minor == 0)) {
126260 + bman_ip_rev = BMAN_REV20;
126261 + bman_pool_max = 8;
126262 + } else if ((major == 2) && (minor == 1)) {
126263 + bman_ip_rev = BMAN_REV21;
126264 + bman_pool_max = 64;
126265 + } else {
126266 + pr_warn("unknown Bman version, default to rev1.0\n");
126267 + }
126268 +
126269 + if (standby) {
126270 + pr_info(" -> in standby mode\n");
126271 + return 0;
126272 + }
126273 + return 0;
126274 +}
126275 +
126276 +int bman_have_ccsr(void)
126277 +{
126278 + return bm ? 1 : 0;
126279 +}
126280 +
126281 +int bm_pool_set(u32 bpid, const u32 *thresholds)
126282 +{
126283 + if (!bm)
126284 + return -ENODEV;
126285 + bm_set_pool(bm, bpid, thresholds[0],
126286 + thresholds[1], thresholds[2],
126287 + thresholds[3]);
126288 + return 0;
126289 +}
126290 +EXPORT_SYMBOL(bm_pool_set);
126291 +
126292 +__init int bman_init_early(void)
126293 +{
126294 + struct device_node *dn;
126295 + int ret;
126296 +
126297 + for_each_compatible_node(dn, NULL, "fsl,bman") {
126298 + if (bm)
126299 + pr_err("%s: only one 'fsl,bman' allowed\n",
126300 + dn->full_name);
126301 + else {
126302 + if (!of_device_is_available(dn))
126303 + continue;
126304 +
126305 + ret = fsl_bman_init(dn);
126306 + BUG_ON(ret);
126307 + }
126308 + }
126309 + return 0;
126310 +}
126311 +postcore_initcall_sync(bman_init_early);
126312 +
126313 +
126314 +static void log_edata_bits(u32 bit_count)
126315 +{
126316 + u32 i, j, mask = 0xffffffff;
126317 +
126318 + pr_warn("Bman ErrInt, EDATA:\n");
126319 + i = bit_count/32;
126320 + if (bit_count%32) {
126321 + i++;
126322 + mask = ~(mask << bit_count%32);
126323 + }
126324 + j = 16-i;
126325 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
126326 + j++;
126327 + for (; j < 16; j++)
126328 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
126329 +}
126330 +
126331 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
126332 +{
126333 + union bman_ecir ecir_val;
126334 + union bman_eadr eadr_val;
126335 +
126336 + ecir_val.ecir_raw = bm_in(ECIR);
126337 + /* Is portal info valid */
126338 + if (ecsr_val & PORTAL_ECSR_ERR) {
126339 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
126340 + ecir_val.info.portal_num, ecir_val.info.numb,
126341 + ecir_val.info.pid);
126342 + }
126343 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
126344 + eadr_val.eadr_raw = bm_in(EADR);
126345 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
126346 + error_mdata[eadr_val.info.memid].txt,
126347 + error_mdata[eadr_val.info.memid].addr_mask
126348 + & eadr_val.info.eadr);
126349 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
126350 + }
126351 +}
126352 +
126353 +/* Bman interrupt handler */
126354 +static irqreturn_t bman_isr(int irq, void *ptr)
126355 +{
126356 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
126357 +
126358 + ier_val = bm_err_isr_enable_read(bm);
126359 + isr_val = bm_err_isr_status_read(bm);
126360 + ecsr_val = bm_in(ECSR);
126361 + isr_mask = isr_val & ier_val;
126362 +
126363 + if (!isr_mask)
126364 + return IRQ_NONE;
126365 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
126366 + if (bman_hwerr_txts[i].mask & isr_mask) {
126367 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
126368 + if (bman_hwerr_txts[i].mask & ecsr_val) {
126369 + log_additional_error_info(isr_mask, ecsr_val);
126370 + /* Re-arm error capture registers */
126371 + bm_out(ECSR, ecsr_val);
126372 + }
126373 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
126374 + pr_devel("Bman un-enabling error 0x%x\n",
126375 + bman_hwerr_txts[i].mask);
126376 + ier_val &= ~bman_hwerr_txts[i].mask;
126377 + bm_err_isr_enable_write(bm, ier_val);
126378 + }
126379 + }
126380 + }
126381 + bm_err_isr_status_clear(bm, isr_val);
126382 + return IRQ_HANDLED;
126383 +}
126384 +
126385 +static int __bind_irq(void)
126386 +{
126387 + int ret, err_irq;
126388 +
126389 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
126390 + if (err_irq == 0) {
126391 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
126392 + "interrupts");
126393 + return -ENODEV;
126394 + }
126395 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
126396 + if (ret) {
126397 + pr_err("request_irq() failed %d for '%s'\n", ret,
126398 + bm_node->full_name);
126399 + return -ENODEV;
126400 + }
126401 + /* Disable Buffer Pool State Change */
126402 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
126403 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
126404 + * to resource allocation during driver init). */
126405 + bm_err_isr_status_clear(bm, 0xffffffff);
126406 + /* Enable Error Interrupts */
126407 + bm_err_isr_enable_write(bm, 0xffffffff);
126408 + return 0;
126409 +}
126410 +
126411 +int bman_init_ccsr(struct device_node *node)
126412 +{
126413 + int ret;
126414 + if (!bman_have_ccsr())
126415 + return 0;
126416 + if (node != bm_node)
126417 + return -EINVAL;
126418 + /* FBPR memory */
126419 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
126420 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
126421 +
126422 + ret = __bind_irq();
126423 + if (ret)
126424 + return ret;
126425 + return 0;
126426 +}
126427 +
126428 +u32 bm_pool_free_buffers(u32 bpid)
126429 +{
126430 + return bm_in(POOL_CONTENT(bpid));
126431 +}
126432 +
126433 +#ifdef CONFIG_SYSFS
126434 +
126435 +#define DRV_NAME "fsl-bman"
126436 +#define SBEC_MAX_ID 1
126437 +#define SBEC_MIN_ID 0
126438 +
126439 +static ssize_t show_fbpr_fpc(struct device *dev,
126440 + struct device_attribute *dev_attr, char *buf)
126441 +{
126442 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
126443 +};
126444 +
126445 +static ssize_t show_pool_count(struct device *dev,
126446 + struct device_attribute *dev_attr, char *buf)
126447 +{
126448 + u32 data;
126449 + int i;
126450 +
126451 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
126452 + return -EINVAL;
126453 + data = bm_in(POOL_CONTENT(i));
126454 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
126455 +};
126456 +
126457 +static ssize_t show_err_isr(struct device *dev,
126458 + struct device_attribute *dev_attr, char *buf)
126459 +{
126460 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
126461 +};
126462 +
126463 +static ssize_t show_sbec(struct device *dev,
126464 + struct device_attribute *dev_attr, char *buf)
126465 +{
126466 + int i;
126467 +
126468 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
126469 + return -EINVAL;
126470 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
126471 + return -EINVAL;
126472 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
126473 +};
126474 +
126475 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
126476 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
126477 +
126478 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
126479 + * Initialize them when needed. */
126480 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
126481 +static struct device_attribute *dev_attr_buffer_pool_count;
126482 +
126483 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
126484 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
126485 +
126486 +static struct attribute *bman_dev_attributes[] = {
126487 + &dev_attr_fbpr_fpc.attr,
126488 + &dev_attr_err_isr.attr,
126489 + NULL
126490 +};
126491 +
126492 +static struct attribute *bman_dev_ecr_attributes[] = {
126493 + &dev_attr_sbec_0.attr,
126494 + &dev_attr_sbec_1.attr,
126495 + NULL
126496 +};
126497 +
126498 +static struct attribute **bman_dev_pool_count_attributes;
126499 +
126500 +
126501 +/* root level */
126502 +static const struct attribute_group bman_dev_attr_grp = {
126503 + .name = NULL,
126504 + .attrs = bman_dev_attributes
126505 +};
126506 +static const struct attribute_group bman_dev_ecr_grp = {
126507 + .name = "error_capture",
126508 + .attrs = bman_dev_ecr_attributes
126509 +};
126510 +static struct attribute_group bman_dev_pool_countent_grp = {
126511 + .name = "pool_count",
126512 +};
126513 +
126514 +static int of_fsl_bman_remove(struct platform_device *ofdev)
126515 +{
126516 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
126517 + return 0;
126518 +};
126519 +
126520 +static int of_fsl_bman_probe(struct platform_device *ofdev)
126521 +{
126522 + int ret, i;
126523 +
126524 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
126525 + if (ret)
126526 + goto done;
126527 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
126528 + if (ret)
126529 + goto del_group_0;
126530 +
126531 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
126532 + GFP_KERNEL);
126533 + if (!name_attrs_pool_count) {
126534 + pr_err("Can't alloc name_attrs_pool_count\n");
126535 + goto del_group_1;
126536 + }
126537 +
126538 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
126539 + bman_pool_max, GFP_KERNEL);
126540 + if (!dev_attr_buffer_pool_count) {
126541 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
126542 + goto del_group_2;
126543 + }
126544 +
126545 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
126546 + (bman_pool_max + 1), GFP_KERNEL);
126547 + if (!bman_dev_pool_count_attributes) {
126548 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
126549 + goto del_group_3;
126550 + }
126551 +
126552 + for (i = 0; i < bman_pool_max; i++) {
126553 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
126554 + if (!ret)
126555 + goto del_group_4;
126556 + dev_attr_buffer_pool_count[i].attr.name =
126557 + (name_attrs_pool_count + i * 3);
126558 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
126559 + dev_attr_buffer_pool_count[i].show = show_pool_count;
126560 + bman_dev_pool_count_attributes[i] =
126561 + &dev_attr_buffer_pool_count[i].attr;
126562 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
126563 + }
126564 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
126565 +
126566 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
126567 +
126568 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
126569 + if (ret)
126570 + goto del_group_4;
126571 +
126572 + goto done;
126573 +
126574 +del_group_4:
126575 + kfree(bman_dev_pool_count_attributes);
126576 +del_group_3:
126577 + kfree(dev_attr_buffer_pool_count);
126578 +del_group_2:
126579 + kfree(name_attrs_pool_count);
126580 +del_group_1:
126581 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
126582 +del_group_0:
126583 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
126584 +done:
126585 + if (ret)
126586 + dev_err(&ofdev->dev,
126587 + "Cannot create dev attributes ret=%d\n", ret);
126588 + return ret;
126589 +};
126590 +
126591 +static struct of_device_id of_fsl_bman_ids[] = {
126592 + {
126593 + .compatible = "fsl,bman",
126594 + },
126595 + {}
126596 +};
126597 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
126598 +
126599 +#ifdef CONFIG_SUSPEND
126600 +static u32 saved_isdr;
126601 +
126602 +static int bman_pm_suspend_noirq(struct device *dev)
126603 +{
126604 + uint32_t idle_state;
126605 +
126606 + suspend_unused_bportal();
126607 + /* save isdr, disable all, clear isr */
126608 + saved_isdr = bm_err_isr_disable_read(bm);
126609 + bm_err_isr_disable_write(bm, 0xffffffff);
126610 + bm_err_isr_status_clear(bm, 0xffffffff);
126611 +
126612 + if (bman_ip_rev < BMAN_REV21) {
126613 +#ifdef CONFIG_PM_DEBUG
126614 + pr_info("Bman version doesn't have STATE_IDLE\n");
126615 +#endif
126616 + return 0;
126617 + }
126618 + idle_state = bm_in(STATE_IDLE);
126619 + if (!(idle_state & 0x1)) {
126620 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
126621 + bm_err_isr_disable_write(bm, saved_isdr);
126622 + resume_unused_bportal();
126623 + return -EBUSY;
126624 + }
126625 +#ifdef CONFIG_PM_DEBUG
126626 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
126627 +#endif
126628 + return 0;
126629 +}
126630 +
126631 +static int bman_pm_resume_noirq(struct device *dev)
126632 +{
126633 + /* restore isdr */
126634 + bm_err_isr_disable_write(bm, saved_isdr);
126635 + resume_unused_bportal();
126636 + return 0;
126637 +}
126638 +#else
126639 +#define bman_pm_suspend_noirq NULL
126640 +#define bman_pm_resume_noirq NULL
126641 +#endif
126642 +
126643 +static const struct dev_pm_ops bman_pm_ops = {
126644 + .suspend_noirq = bman_pm_suspend_noirq,
126645 + .resume_noirq = bman_pm_resume_noirq,
126646 +};
126647 +
126648 +static struct platform_driver of_fsl_bman_driver = {
126649 + .driver = {
126650 + .owner = THIS_MODULE,
126651 + .name = DRV_NAME,
126652 + .of_match_table = of_fsl_bman_ids,
126653 + .pm = &bman_pm_ops,
126654 + },
126655 + .probe = of_fsl_bman_probe,
126656 + .remove = of_fsl_bman_remove,
126657 +};
126658 +
126659 +static int bman_ctrl_init(void)
126660 +{
126661 + return platform_driver_register(&of_fsl_bman_driver);
126662 +}
126663 +
126664 +static void bman_ctrl_exit(void)
126665 +{
126666 + platform_driver_unregister(&of_fsl_bman_driver);
126667 +}
126668 +
126669 +module_init(bman_ctrl_init);
126670 +module_exit(bman_ctrl_exit);
126671 +
126672 +#endif /* CONFIG_SYSFS */
126673 --- /dev/null
126674 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
126675 @@ -0,0 +1,119 @@
126676 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
126677 + *
126678 + * Redistribution and use in source and binary forms, with or without
126679 + * modification, are permitted provided that the following conditions are met:
126680 + * * Redistributions of source code must retain the above copyright
126681 + * notice, this list of conditions and the following disclaimer.
126682 + * * Redistributions in binary form must reproduce the above copyright
126683 + * notice, this list of conditions and the following disclaimer in the
126684 + * documentation and/or other materials provided with the distribution.
126685 + * * Neither the name of Freescale Semiconductor nor the
126686 + * names of its contributors may be used to endorse or promote products
126687 + * derived from this software without specific prior written permission.
126688 + *
126689 + *
126690 + * ALTERNATIVELY, this software may be distributed under the terms of the
126691 + * GNU General Public License ("GPL") as published by the Free Software
126692 + * Foundation, either version 2 of that License or (at your option) any
126693 + * later version.
126694 + *
126695 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126696 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126697 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126698 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126699 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126700 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126701 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126702 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126703 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126704 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126705 + */
126706 +#include <linux/module.h>
126707 +#include <linux/fsl_bman.h>
126708 +#include <linux/debugfs.h>
126709 +#include <linux/seq_file.h>
126710 +#include <linux/uaccess.h>
126711 +
126712 +static struct dentry *dfs_root; /* debugfs root directory */
126713 +
126714 +/*******************************************************************************
126715 + * Query Buffer Pool State
126716 + ******************************************************************************/
126717 +static int query_bp_state_show(struct seq_file *file, void *offset)
126718 +{
126719 + int ret;
126720 + struct bm_pool_state state;
126721 + int i, j;
126722 + u32 mask;
126723 +
126724 + memset(&state, 0, sizeof(struct bm_pool_state));
126725 + ret = bman_query_pools(&state);
126726 + if (ret) {
126727 + seq_printf(file, "Error %d\n", ret);
126728 + return 0;
126729 + }
126730 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
126731 + for (i = 0; i < 2; i++) {
126732 + mask = 0x80000000;
126733 + for (j = 0; j < 32; j++) {
126734 + seq_printf(file,
126735 + " %-2u %-3s %-3s\n",
126736 + (i*32)+j,
126737 + (state.as.state.__state[i] & mask) ? "no" : "yes",
126738 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
126739 + mask >>= 1;
126740 + }
126741 + }
126742 + return 0;
126743 +}
126744 +
126745 +static int query_bp_state_open(struct inode *inode, struct file *file)
126746 +{
126747 + return single_open(file, query_bp_state_show, NULL);
126748 +}
126749 +
126750 +static const struct file_operations query_bp_state_fops = {
126751 + .owner = THIS_MODULE,
126752 + .open = query_bp_state_open,
126753 + .read = seq_read,
126754 + .release = single_release,
126755 +};
126756 +
126757 +static int __init bman_debugfs_module_init(void)
126758 +{
126759 + int ret = 0;
126760 + struct dentry *d;
126761 +
126762 + dfs_root = debugfs_create_dir("bman", NULL);
126763 +
126764 + if (dfs_root == NULL) {
126765 + ret = -ENOMEM;
126766 + pr_err("Cannot create bman debugfs dir\n");
126767 + goto _return;
126768 + }
126769 + d = debugfs_create_file("query_bp_state",
126770 + S_IRUGO,
126771 + dfs_root,
126772 + NULL,
126773 + &query_bp_state_fops);
126774 + if (d == NULL) {
126775 + ret = -ENOMEM;
126776 + pr_err("Cannot create query_bp_state\n");
126777 + goto _return;
126778 + }
126779 + return 0;
126780 +
126781 +_return:
126782 + debugfs_remove_recursive(dfs_root);
126783 + return ret;
126784 +}
126785 +
126786 +static void __exit bman_debugfs_module_exit(void)
126787 +{
126788 + debugfs_remove_recursive(dfs_root);
126789 +}
126790 +
126791 +
126792 +module_init(bman_debugfs_module_init);
126793 +module_exit(bman_debugfs_module_exit);
126794 +MODULE_LICENSE("Dual BSD/GPL");
126795 --- /dev/null
126796 +++ b/drivers/staging/fsl_qbman/bman_driver.c
126797 @@ -0,0 +1,559 @@
126798 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
126799 + *
126800 + * Redistribution and use in source and binary forms, with or without
126801 + * modification, are permitted provided that the following conditions are met:
126802 + * * Redistributions of source code must retain the above copyright
126803 + * notice, this list of conditions and the following disclaimer.
126804 + * * Redistributions in binary form must reproduce the above copyright
126805 + * notice, this list of conditions and the following disclaimer in the
126806 + * documentation and/or other materials provided with the distribution.
126807 + * * Neither the name of Freescale Semiconductor nor the
126808 + * names of its contributors may be used to endorse or promote products
126809 + * derived from this software without specific prior written permission.
126810 + *
126811 + *
126812 + * ALTERNATIVELY, this software may be distributed under the terms of the
126813 + * GNU General Public License ("GPL") as published by the Free Software
126814 + * Foundation, either version 2 of that License or (at your option) any
126815 + * later version.
126816 + *
126817 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126818 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126819 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126820 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126821 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126822 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126823 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126824 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126825 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126826 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126827 + */
126828 +#include "bman_low.h"
126829 +#ifdef CONFIG_HOTPLUG_CPU
126830 +#include <linux/cpu.h>
126831 +#endif
126832 +/*
126833 + * Global variables of the max portal/pool number this bman version supported
126834 + */
126835 +u16 bman_ip_rev;
126836 +EXPORT_SYMBOL(bman_ip_rev);
126837 +u16 bman_pool_max;
126838 +EXPORT_SYMBOL(bman_pool_max);
126839 +static u16 bman_portal_max;
126840 +
126841 +/* After initialising cpus that own shared portal configs, we cache the
126842 + * resulting portals (ie. not just the configs) in this array. Then we
126843 + * initialise slave cpus that don't have their own portals, redirecting them to
126844 + * portals from this cache in a round-robin assignment. */
126845 +static struct bman_portal *shared_portals[NR_CPUS];
126846 +static int num_shared_portals;
126847 +static int shared_portals_idx;
126848 +static LIST_HEAD(unused_pcfgs);
126849 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
126850 +static void *affine_bportals[NR_CPUS];
126851 +
126852 +static int __init fsl_bpool_init(struct device_node *node)
126853 +{
126854 + int ret;
126855 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
126856 + if (!bpid || (ret != 4)) {
126857 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
126858 + return -ENODEV;
126859 + }
126860 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
126861 + if (thresh) {
126862 + if (ret != 16) {
126863 + pr_err("Invalid %s property '%s'\n",
126864 + node->full_name, "fsl,bpool-thresholds");
126865 + return -ENODEV;
126866 + }
126867 + }
126868 + if (thresh) {
126869 +#ifdef CONFIG_FSL_BMAN_CONFIG
126870 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
126871 + if (ret)
126872 + pr_err("No CCSR node for %s property '%s'\n",
126873 + node->full_name, "fsl,bpool-thresholds");
126874 + return ret;
126875 +#else
126876 + pr_err("Ignoring %s property '%s', no CCSR support\n",
126877 + node->full_name, "fsl,bpool-thresholds");
126878 +#endif
126879 + }
126880 + return 0;
126881 +}
126882 +
126883 +static int __init fsl_bpid_range_init(struct device_node *node)
126884 +{
126885 + int ret;
126886 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
126887 + if (!range) {
126888 + pr_err("No 'fsl,bpid-range' property in node %s\n",
126889 + node->full_name);
126890 + return -EINVAL;
126891 + }
126892 + if (ret != 8) {
126893 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
126894 + node->full_name);
126895 + return -EINVAL;
126896 + }
126897 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
126898 + pr_info("Bman: BPID allocator includes range %d:%d\n",
126899 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
126900 + return 0;
126901 +}
126902 +
126903 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
126904 +{
126905 + struct bm_portal_config *pcfg;
126906 + const u32 *index;
126907 + int irq, ret;
126908 + resource_size_t len;
126909 +
126910 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
126911 + if (!pcfg) {
126912 + pr_err("can't allocate portal config");
126913 + return NULL;
126914 + }
126915 +
126916 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
126917 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
126918 + bman_ip_rev = BMAN_REV10;
126919 + bman_pool_max = 64;
126920 + bman_portal_max = 10;
126921 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
126922 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
126923 + bman_ip_rev = BMAN_REV20;
126924 + bman_pool_max = 8;
126925 + bman_portal_max = 3;
126926 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
126927 + bman_ip_rev = BMAN_REV21;
126928 + bman_pool_max = 64;
126929 + bman_portal_max = 50;
126930 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
126931 + bman_ip_rev = BMAN_REV21;
126932 + bman_pool_max = 64;
126933 + bman_portal_max = 25;
126934 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
126935 + bman_ip_rev = BMAN_REV21;
126936 + bman_pool_max = 64;
126937 + bman_portal_max = 18;
126938 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
126939 + bman_ip_rev = BMAN_REV21;
126940 + bman_pool_max = 64;
126941 + bman_portal_max = 10;
126942 + } else {
126943 + pr_warn("unknown BMan version in portal node,"
126944 + "default to rev1.0\n");
126945 + bman_ip_rev = BMAN_REV10;
126946 + bman_pool_max = 64;
126947 + bman_portal_max = 10;
126948 + }
126949 +
126950 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
126951 + &pcfg->addr_phys[DPA_PORTAL_CE]);
126952 + if (ret) {
126953 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
126954 + goto err;
126955 + }
126956 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
126957 + &pcfg->addr_phys[DPA_PORTAL_CI]);
126958 + if (ret) {
126959 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
126960 + goto err;
126961 + }
126962 +
126963 + index = of_get_property(node, "cell-index", &ret);
126964 + if (!index || (ret != 4)) {
126965 + pr_err("Can't get %s property '%s'\n", node->full_name,
126966 + "cell-index");
126967 + goto err;
126968 + }
126969 + if (be32_to_cpu(*index) >= bman_portal_max) {
126970 + pr_err("BMan portal cell index %d out of range, max %d\n",
126971 + be32_to_cpu(*index), bman_portal_max);
126972 + goto err;
126973 + }
126974 +
126975 + pcfg->public_cfg.cpu = -1;
126976 +
126977 + irq = irq_of_parse_and_map(node, 0);
126978 + if (irq == 0) {
126979 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
126980 + goto err;
126981 + }
126982 + pcfg->public_cfg.irq = irq;
126983 + pcfg->public_cfg.index = be32_to_cpu(*index);
126984 + bman_depletion_fill(&pcfg->public_cfg.mask);
126985 +
126986 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
126987 + if (len != (unsigned long)len)
126988 + goto err;
126989 +
126990 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
126991 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
126992 + pcfg->addr_phys[DPA_PORTAL_CE].start,
126993 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
126994 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
126995 + pcfg->addr_phys[DPA_PORTAL_CI].start,
126996 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
126997 +
126998 +#else
126999 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
127000 + pcfg->addr_phys[DPA_PORTAL_CE].start,
127001 + (unsigned long)len,
127002 + 0);
127003 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
127004 + pcfg->addr_phys[DPA_PORTAL_CI].start,
127005 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
127006 + _PAGE_GUARDED | _PAGE_NO_CACHE);
127007 +#endif
127008 + /* disable bp depletion */
127009 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
127010 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
127011 + return pcfg;
127012 +err:
127013 + kfree(pcfg);
127014 + return NULL;
127015 +}
127016 +
127017 +static struct bm_portal_config *get_pcfg(struct list_head *list)
127018 +{
127019 + struct bm_portal_config *pcfg;
127020 + if (list_empty(list))
127021 + return NULL;
127022 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
127023 + list_del(&pcfg->list);
127024 + return pcfg;
127025 +}
127026 +
127027 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
127028 + uint32_t idx)
127029 +{
127030 + struct bm_portal_config *pcfg;
127031 + if (list_empty(list))
127032 + return NULL;
127033 + list_for_each_entry(pcfg, list, list) {
127034 + if (pcfg->public_cfg.index == idx) {
127035 + list_del(&pcfg->list);
127036 + return pcfg;
127037 + }
127038 + }
127039 + return NULL;
127040 +}
127041 +
127042 +struct bm_portal_config *bm_get_unused_portal(void)
127043 +{
127044 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
127045 +}
127046 +
127047 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
127048 +{
127049 + struct bm_portal_config *ret;
127050 + spin_lock(&unused_pcfgs_lock);
127051 + if (idx == QBMAN_ANY_PORTAL_IDX)
127052 + ret = get_pcfg(&unused_pcfgs);
127053 + else
127054 + ret = get_pcfg_idx(&unused_pcfgs, idx);
127055 + spin_unlock(&unused_pcfgs_lock);
127056 + return ret;
127057 +}
127058 +
127059 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
127060 +{
127061 + spin_lock(&unused_pcfgs_lock);
127062 + list_add(&pcfg->list, &unused_pcfgs);
127063 + spin_unlock(&unused_pcfgs_lock);
127064 +}
127065 +
127066 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
127067 +{
127068 + struct bman_portal *p;
127069 + p = bman_create_affine_portal(pcfg);
127070 + if (p) {
127071 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
127072 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
127073 +#endif
127074 + pr_info("Bman portal %sinitialised, cpu %d\n",
127075 + pcfg->public_cfg.is_shared ? "(shared) " : "",
127076 + pcfg->public_cfg.cpu);
127077 + affine_bportals[pcfg->public_cfg.cpu] = p;
127078 + } else
127079 + pr_crit("Bman portal failure on cpu %d\n",
127080 + pcfg->public_cfg.cpu);
127081 + return p;
127082 +}
127083 +
127084 +static void init_slave(int cpu)
127085 +{
127086 + struct bman_portal *p;
127087 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
127088 + if (!p)
127089 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
127090 + else
127091 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
127092 + if (shared_portals_idx >= num_shared_portals)
127093 + shared_portals_idx = 0;
127094 + affine_bportals[cpu] = p;
127095 +}
127096 +
127097 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
127098 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
127099 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
127100 + * explicitly mark it or them for sharing.
127101 + * Eg;
127102 + * bportals=s0,1-3,s4
127103 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
127104 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
127105 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
127106 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
127107 + * 0's portal.) */
127108 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
127109 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
127110 +
127111 +static int __init parse_bportals(char *str)
127112 +{
127113 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
127114 + "bportals");
127115 +}
127116 +__setup("bportals=", parse_bportals);
127117 +
127118 +static int bman_offline_cpu(unsigned int cpu)
127119 +{
127120 + struct bman_portal *p;
127121 + const struct bm_portal_config *pcfg;
127122 + p = (struct bman_portal *)affine_bportals[cpu];
127123 + if (p) {
127124 + pcfg = bman_get_bm_portal_config(p);
127125 + if (pcfg)
127126 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
127127 + }
127128 + return 0;
127129 +}
127130 +
127131 +#ifdef CONFIG_HOTPLUG_CPU
127132 +static int bman_online_cpu(unsigned int cpu)
127133 +{
127134 + struct bman_portal *p;
127135 + const struct bm_portal_config *pcfg;
127136 + p = (struct bman_portal *)affine_bportals[cpu];
127137 + if (p) {
127138 + pcfg = bman_get_bm_portal_config(p);
127139 + if (pcfg)
127140 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
127141 + }
127142 + return 0;
127143 +}
127144 +#endif /* CONFIG_HOTPLUG_CPU */
127145 +
127146 +/* Initialise the Bman driver. The meat of this function deals with portals. The
127147 + * following describes the flow of portal-handling, the code "steps" refer to
127148 + * this description;
127149 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
127150 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
127151 + * bound).
127152 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
127153 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
127154 + * them to cpus, placing them in the relevant list and setting ::cpu as
127155 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
127156 + * assign portals to all online cpus at the time of driver initialisation.
127157 + * Any failure to allocate portals (when parsing the "want" lists or when
127158 + * using default behaviour) will be silently tolerated (the "fixup" logic in
127159 + * step 3 will determine what happens in this case).
127160 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
127161 + * sharing and sharing is required (because not all cpus have been assigned
127162 + * portals), then one portal will marked for sharing. Conversely if no
127163 + * sharing is required, any portals marked for sharing will not be shared. It
127164 + * may be that sharing occurs when it wasn't expected, if portal allocation
127165 + * failed to honour all the requested assignments (including the default
127166 + * assignments if no bootarg is present).
127167 + * 4. Unshared portals are initialised on their respective cpus.
127168 + * 5. Shared portals are initialised on their respective cpus.
127169 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
127170 + * which are selected in a round-robin fashion.
127171 + * Any portal configs left unused are available for USDPAA allocation.
127172 + */
127173 +__init int bman_init(void)
127174 +{
127175 + struct cpumask slave_cpus;
127176 + struct cpumask unshared_cpus = *cpu_none_mask;
127177 + struct cpumask shared_cpus = *cpu_none_mask;
127178 + LIST_HEAD(unshared_pcfgs);
127179 + LIST_HEAD(shared_pcfgs);
127180 + struct device_node *dn;
127181 + struct bm_portal_config *pcfg;
127182 + struct bman_portal *p;
127183 + int cpu, ret;
127184 + struct cpumask offline_cpus;
127185 +
127186 + /* Initialise the Bman (CCSR) device */
127187 + for_each_compatible_node(dn, NULL, "fsl,bman") {
127188 + if (!bman_init_ccsr(dn))
127189 + pr_info("Bman err interrupt handler present\n");
127190 + else
127191 + pr_err("Bman CCSR setup failed\n");
127192 + }
127193 + /* Initialise any declared buffer pools */
127194 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
127195 + ret = fsl_bpool_init(dn);
127196 + if (ret)
127197 + return ret;
127198 + }
127199 + /* Step 1. See comments at the beginning of the file. */
127200 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
127201 + if (!of_device_is_available(dn))
127202 + continue;
127203 + pcfg = parse_pcfg(dn);
127204 + if (pcfg)
127205 + list_add_tail(&pcfg->list, &unused_pcfgs);
127206 + }
127207 + /* Step 2. */
127208 + for_each_possible_cpu(cpu) {
127209 + if (cpumask_test_cpu(cpu, &want_shared)) {
127210 + pcfg = get_pcfg(&unused_pcfgs);
127211 + if (!pcfg)
127212 + break;
127213 + pcfg->public_cfg.cpu = cpu;
127214 + list_add_tail(&pcfg->list, &shared_pcfgs);
127215 + cpumask_set_cpu(cpu, &shared_cpus);
127216 + }
127217 + if (cpumask_test_cpu(cpu, &want_unshared)) {
127218 + if (cpumask_test_cpu(cpu, &shared_cpus))
127219 + continue;
127220 + pcfg = get_pcfg(&unused_pcfgs);
127221 + if (!pcfg)
127222 + break;
127223 + pcfg->public_cfg.cpu = cpu;
127224 + list_add_tail(&pcfg->list, &unshared_pcfgs);
127225 + cpumask_set_cpu(cpu, &unshared_cpus);
127226 + }
127227 + }
127228 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
127229 + /* Default, give an unshared portal to each online cpu */
127230 + for_each_online_cpu(cpu) {
127231 + pcfg = get_pcfg(&unused_pcfgs);
127232 + if (!pcfg)
127233 + break;
127234 + pcfg->public_cfg.cpu = cpu;
127235 + list_add_tail(&pcfg->list, &unshared_pcfgs);
127236 + cpumask_set_cpu(cpu, &unshared_cpus);
127237 + }
127238 + }
127239 + /* Step 3. */
127240 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
127241 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
127242 + if (cpumask_empty(&slave_cpus)) {
127243 + /* No sharing required */
127244 + if (!list_empty(&shared_pcfgs)) {
127245 + /* Migrate "shared" to "unshared" */
127246 + cpumask_or(&unshared_cpus, &unshared_cpus,
127247 + &shared_cpus);
127248 + cpumask_clear(&shared_cpus);
127249 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
127250 + INIT_LIST_HEAD(&shared_pcfgs);
127251 + }
127252 + } else {
127253 + /* Sharing required */
127254 + if (list_empty(&shared_pcfgs)) {
127255 + /* Migrate one "unshared" to "shared" */
127256 + pcfg = get_pcfg(&unshared_pcfgs);
127257 + if (!pcfg) {
127258 + pr_crit("No BMan portals available!\n");
127259 + return 0;
127260 + }
127261 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
127262 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
127263 + list_add_tail(&pcfg->list, &shared_pcfgs);
127264 + }
127265 + }
127266 + /* Step 4. */
127267 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
127268 + pcfg->public_cfg.is_shared = 0;
127269 + p = init_pcfg(pcfg);
127270 + if (!p) {
127271 + pr_crit("Unable to initialize bman portal\n");
127272 + return 0;
127273 + }
127274 + }
127275 + /* Step 5. */
127276 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
127277 + pcfg->public_cfg.is_shared = 1;
127278 + p = init_pcfg(pcfg);
127279 + if (p)
127280 + shared_portals[num_shared_portals++] = p;
127281 + }
127282 + /* Step 6. */
127283 + if (!cpumask_empty(&slave_cpus))
127284 + for_each_cpu(cpu, &slave_cpus)
127285 + init_slave(cpu);
127286 + pr_info("Bman portals initialised\n");
127287 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
127288 + for_each_cpu(cpu, &offline_cpus)
127289 + bman_offline_cpu(cpu);
127290 +#ifdef CONFIG_HOTPLUG_CPU
127291 + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
127292 + "soc/qbman_portal:online",
127293 + bman_online_cpu, bman_offline_cpu);
127294 + if (ret < 0) {
127295 + pr_err("bman: failed to register hotplug callbacks.\n");
127296 + return 0;
127297 + }
127298 +#endif
127299 + return 0;
127300 +}
127301 +
127302 +__init int bman_resource_init(void)
127303 +{
127304 + struct device_node *dn;
127305 + int ret;
127306 +
127307 + /* Initialise BPID allocation ranges */
127308 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
127309 + ret = fsl_bpid_range_init(dn);
127310 + if (ret)
127311 + return ret;
127312 + }
127313 + return 0;
127314 +}
127315 +
127316 +#ifdef CONFIG_SUSPEND
127317 +void suspend_unused_bportal(void)
127318 +{
127319 + struct bm_portal_config *pcfg;
127320 +
127321 + if (list_empty(&unused_pcfgs))
127322 + return;
127323 +
127324 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
127325 +#ifdef CONFIG_PM_DEBUG
127326 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
127327 +#endif
127328 + /* save isdr, disable all via isdr, clear isr */
127329 + pcfg->saved_isdr =
127330 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
127331 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
127332 + 0xe08);
127333 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
127334 + 0xe00);
127335 + }
127336 + return;
127337 +}
127338 +
127339 +void resume_unused_bportal(void)
127340 +{
127341 + struct bm_portal_config *pcfg;
127342 +
127343 + if (list_empty(&unused_pcfgs))
127344 + return;
127345 +
127346 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
127347 +#ifdef CONFIG_PM_DEBUG
127348 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
127349 +#endif
127350 + /* restore isdr */
127351 + __raw_writel(pcfg->saved_isdr,
127352 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
127353 + }
127354 + return;
127355 +}
127356 +#endif
127357 --- /dev/null
127358 +++ b/drivers/staging/fsl_qbman/bman_high.c
127359 @@ -0,0 +1,1145 @@
127360 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127361 + *
127362 + * Redistribution and use in source and binary forms, with or without
127363 + * modification, are permitted provided that the following conditions are met:
127364 + * * Redistributions of source code must retain the above copyright
127365 + * notice, this list of conditions and the following disclaimer.
127366 + * * Redistributions in binary form must reproduce the above copyright
127367 + * notice, this list of conditions and the following disclaimer in the
127368 + * documentation and/or other materials provided with the distribution.
127369 + * * Neither the name of Freescale Semiconductor nor the
127370 + * names of its contributors may be used to endorse or promote products
127371 + * derived from this software without specific prior written permission.
127372 + *
127373 + *
127374 + * ALTERNATIVELY, this software may be distributed under the terms of the
127375 + * GNU General Public License ("GPL") as published by the Free Software
127376 + * Foundation, either version 2 of that License or (at your option) any
127377 + * later version.
127378 + *
127379 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127380 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127381 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127382 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127383 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127384 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127385 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127386 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127387 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127388 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127389 + */
127390 +
127391 +#include "bman_low.h"
127392 +
127393 +/* Compilation constants */
127394 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
127395 +#define IRQNAME "BMan portal %d"
127396 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
127397 +
127398 +struct bman_portal {
127399 + struct bm_portal p;
127400 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
127401 + struct bman_depletion *pools;
127402 + int thresh_set;
127403 + unsigned long irq_sources;
127404 + u32 slowpoll; /* only used when interrupts are off */
127405 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127406 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
127407 +#endif
127408 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127409 + raw_spinlock_t sharing_lock; /* only used if is_shared */
127410 + int is_shared;
127411 + struct bman_portal *sharing_redirect;
127412 +#endif
127413 + /* When the cpu-affine portal is activated, this is non-NULL */
127414 + const struct bm_portal_config *config;
127415 + /* This is needed for power management */
127416 + struct platform_device *pdev;
127417 + /* 64-entry hash-table of pool objects that are tracking depletion
127418 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
127419 + * we're not fussy about cache-misses and so forth - whereas the above
127420 + * members should all fit in one cacheline.
127421 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
127422 + * you'll never guess the hash-function ... */
127423 + struct bman_pool *cb[64];
127424 + char irqname[MAX_IRQNAME];
127425 + /* Track if the portal was alloced by the driver */
127426 + u8 alloced;
127427 + /* power management data */
127428 + u32 save_isdr;
127429 +};
127430 +
127431 +/* For an explanation of the locking, redirection, or affine-portal logic,
127432 + * please consult the Qman driver for details. This is the same, only simpler
127433 + * (no fiddly Qman-specific bits.) */
127434 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127435 +#define PORTAL_IRQ_LOCK(p, irqflags) \
127436 + do { \
127437 + if ((p)->is_shared) \
127438 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
127439 + else \
127440 + local_irq_save(irqflags); \
127441 + } while (0)
127442 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
127443 + do { \
127444 + if ((p)->is_shared) \
127445 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
127446 + irqflags); \
127447 + else \
127448 + local_irq_restore(irqflags); \
127449 + } while (0)
127450 +#else
127451 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
127452 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
127453 +#endif
127454 +
127455 +static cpumask_t affine_mask;
127456 +static DEFINE_SPINLOCK(affine_mask_lock);
127457 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
127458 +static inline struct bman_portal *get_raw_affine_portal(void)
127459 +{
127460 + return &get_cpu_var(bman_affine_portal);
127461 +}
127462 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127463 +static inline struct bman_portal *get_affine_portal(void)
127464 +{
127465 + struct bman_portal *p = get_raw_affine_portal();
127466 + if (p->sharing_redirect)
127467 + return p->sharing_redirect;
127468 + return p;
127469 +}
127470 +#else
127471 +#define get_affine_portal() get_raw_affine_portal()
127472 +#endif
127473 +static inline void put_affine_portal(void)
127474 +{
127475 + put_cpu_var(bman_affine_portal);
127476 +}
127477 +static inline struct bman_portal *get_poll_portal(void)
127478 +{
127479 + return &get_cpu_var(bman_affine_portal);
127480 +}
127481 +#define put_poll_portal()
127482 +
127483 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
127484 + * more than one such object per Bman buffer pool, eg. if different users of the
127485 + * pool are operating via different portals. */
127486 +struct bman_pool {
127487 + struct bman_pool_params params;
127488 + /* Used for hash-table admin when using depletion notifications. */
127489 + struct bman_portal *portal;
127490 + struct bman_pool *next;
127491 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
127492 + struct bm_buffer *sp;
127493 + unsigned int sp_fill;
127494 +#ifdef CONFIG_FSL_DPA_CHECKING
127495 + atomic_t in_use;
127496 +#endif
127497 +};
127498 +
127499 +/* (De)Registration of depletion notification callbacks */
127500 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
127501 +{
127502 + __maybe_unused unsigned long irqflags;
127503 + pool->portal = portal;
127504 + PORTAL_IRQ_LOCK(portal, irqflags);
127505 + pool->next = portal->cb[pool->params.bpid];
127506 + portal->cb[pool->params.bpid] = pool;
127507 + if (!pool->next)
127508 + /* First object for that bpid on this portal, enable the BSCN
127509 + * mask bit. */
127510 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
127511 + PORTAL_IRQ_UNLOCK(portal, irqflags);
127512 +}
127513 +static void depletion_unlink(struct bman_pool *pool)
127514 +{
127515 + struct bman_pool *it, *last = NULL;
127516 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
127517 + __maybe_unused unsigned long irqflags;
127518 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
127519 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
127520 + while (it != pool) {
127521 + last = it;
127522 + it = it->next;
127523 + }
127524 + if (!last)
127525 + *base = pool->next;
127526 + else
127527 + last->next = pool->next;
127528 + if (!last && !pool->next) {
127529 + /* Last object for that bpid on this portal, disable the BSCN
127530 + * mask bit. */
127531 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
127532 + /* And "forget" that we last saw this pool as depleted */
127533 + bman_depletion_unset(&pool->portal->pools[1],
127534 + pool->params.bpid);
127535 + }
127536 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
127537 +}
127538 +
127539 +/* In the case that the application's core loop calls qman_poll() and
127540 + * bman_poll(), we ought to balance how often we incur the overheads of the
127541 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
127542 + * constant is used when the last slow-poll detected no work to do, and the busy
127543 + * decrementer constant when the last slow-poll had work to do. */
127544 +#define SLOW_POLL_IDLE 1000
127545 +#define SLOW_POLL_BUSY 10
127546 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
127547 +
127548 +/* Portal interrupt handler */
127549 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
127550 +{
127551 + struct bman_portal *p = ptr;
127552 + u32 clear = p->irq_sources;
127553 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
127554 + clear |= __poll_portal_slow(p, is);
127555 + bm_isr_status_clear(&p->p, clear);
127556 + return IRQ_HANDLED;
127557 +}
127558 +
127559 +#ifdef CONFIG_SUSPEND
127560 +static int _bman_portal_suspend_noirq(struct device *dev)
127561 +{
127562 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
127563 +#ifdef CONFIG_PM_DEBUG
127564 + struct platform_device *pdev = to_platform_device(dev);
127565 +#endif
127566 + p->save_isdr = bm_isr_disable_read(&p->p);
127567 + bm_isr_disable_write(&p->p, 0xffffffff);
127568 + bm_isr_status_clear(&p->p, 0xffffffff);
127569 +#ifdef CONFIG_PM_DEBUG
127570 + pr_info("Suspend for %s\n", pdev->name);
127571 +#endif
127572 + return 0;
127573 +}
127574 +
127575 +static int _bman_portal_resume_noirq(struct device *dev)
127576 +{
127577 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
127578 +
127579 + /* restore isdr */
127580 + bm_isr_disable_write(&p->p, p->save_isdr);
127581 + return 0;
127582 +}
127583 +#else
127584 +#define _bman_portal_suspend_noirq NULL
127585 +#define _bman_portal_resume_noirq NULL
127586 +#endif
127587 +
127588 +struct dev_pm_domain bman_portal_device_pm_domain = {
127589 + .ops = {
127590 + USE_PLATFORM_PM_SLEEP_OPS
127591 + .suspend_noirq = _bman_portal_suspend_noirq,
127592 + .resume_noirq = _bman_portal_resume_noirq,
127593 + }
127594 +};
127595 +
127596 +struct bman_portal *bman_create_portal(
127597 + struct bman_portal *portal,
127598 + const struct bm_portal_config *config)
127599 +{
127600 + struct bm_portal *__p;
127601 + const struct bman_depletion *pools = &config->public_cfg.mask;
127602 + int ret;
127603 + u8 bpid = 0;
127604 + char buf[16];
127605 +
127606 + if (!portal) {
127607 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
127608 + if (!portal)
127609 + return portal;
127610 + portal->alloced = 1;
127611 + } else
127612 + portal->alloced = 0;
127613 +
127614 + __p = &portal->p;
127615 +
127616 + /* prep the low-level portal struct with the mapped addresses from the
127617 + * config, everything that follows depends on it and "config" is more
127618 + * for (de)reference... */
127619 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
127620 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
127621 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
127622 + pr_err("Bman RCR initialisation failed\n");
127623 + goto fail_rcr;
127624 + }
127625 + if (bm_mc_init(__p)) {
127626 + pr_err("Bman MC initialisation failed\n");
127627 + goto fail_mc;
127628 + }
127629 + if (bm_isr_init(__p)) {
127630 + pr_err("Bman ISR initialisation failed\n");
127631 + goto fail_isr;
127632 + }
127633 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
127634 + if (!portal->pools)
127635 + goto fail_pools;
127636 + portal->pools[0] = *pools;
127637 + bman_depletion_init(portal->pools + 1);
127638 + while (bpid < bman_pool_max) {
127639 + /* Default to all BPIDs disabled, we enable as required at
127640 + * run-time. */
127641 + bm_isr_bscn_mask(__p, bpid, 0);
127642 + bpid++;
127643 + }
127644 + portal->slowpoll = 0;
127645 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127646 + portal->rcri_owned = NULL;
127647 +#endif
127648 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127649 + raw_spin_lock_init(&portal->sharing_lock);
127650 + portal->is_shared = config->public_cfg.is_shared;
127651 + portal->sharing_redirect = NULL;
127652 +#endif
127653 + sprintf(buf, "bportal-%u", config->public_cfg.index);
127654 + portal->pdev = platform_device_alloc(buf, -1);
127655 + if (!portal->pdev)
127656 + goto fail_devalloc;
127657 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
127658 + portal->pdev->dev.platform_data = portal;
127659 + ret = platform_device_add(portal->pdev);
127660 + if (ret)
127661 + goto fail_devadd;
127662 + memset(&portal->cb, 0, sizeof(portal->cb));
127663 + /* Write-to-clear any stale interrupt status bits */
127664 + bm_isr_disable_write(__p, 0xffffffff);
127665 + portal->irq_sources = 0;
127666 + bm_isr_enable_write(__p, portal->irq_sources);
127667 + bm_isr_status_clear(__p, 0xffffffff);
127668 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
127669 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
127670 + portal)) {
127671 + pr_err("request_irq() failed\n");
127672 + goto fail_irq;
127673 + }
127674 + if ((config->public_cfg.cpu != -1) &&
127675 + irq_can_set_affinity(config->public_cfg.irq) &&
127676 + irq_set_affinity(config->public_cfg.irq,
127677 + cpumask_of(config->public_cfg.cpu))) {
127678 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
127679 + goto fail_affinity;
127680 + }
127681 +
127682 + /* Need RCR to be empty before continuing */
127683 + ret = bm_rcr_get_fill(__p);
127684 + if (ret) {
127685 + pr_err("Bman RCR unclean\n");
127686 + goto fail_rcr_empty;
127687 + }
127688 + /* Success */
127689 + portal->config = config;
127690 +
127691 + bm_isr_disable_write(__p, 0);
127692 + bm_isr_uninhibit(__p);
127693 + return portal;
127694 +fail_rcr_empty:
127695 +fail_affinity:
127696 + free_irq(config->public_cfg.irq, portal);
127697 +fail_irq:
127698 + platform_device_del(portal->pdev);
127699 +fail_devadd:
127700 + platform_device_put(portal->pdev);
127701 +fail_devalloc:
127702 + kfree(portal->pools);
127703 +fail_pools:
127704 + bm_isr_finish(__p);
127705 +fail_isr:
127706 + bm_mc_finish(__p);
127707 +fail_mc:
127708 + bm_rcr_finish(__p);
127709 +fail_rcr:
127710 + if (portal->alloced)
127711 + kfree(portal);
127712 + return NULL;
127713 +}
127714 +
127715 +struct bman_portal *bman_create_affine_portal(
127716 + const struct bm_portal_config *config)
127717 +{
127718 + struct bman_portal *portal;
127719 +
127720 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
127721 + portal = bman_create_portal(portal, config);
127722 + if (portal) {
127723 + spin_lock(&affine_mask_lock);
127724 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
127725 + spin_unlock(&affine_mask_lock);
127726 + }
127727 + return portal;
127728 +}
127729 +
127730 +
127731 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
127732 + int cpu)
127733 +{
127734 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127735 + struct bman_portal *p;
127736 + p = &per_cpu(bman_affine_portal, cpu);
127737 + BUG_ON(p->config);
127738 + BUG_ON(p->is_shared);
127739 + BUG_ON(!redirect->config->public_cfg.is_shared);
127740 + p->irq_sources = 0;
127741 + p->sharing_redirect = redirect;
127742 + return p;
127743 +#else
127744 + BUG();
127745 + return NULL;
127746 +#endif
127747 +}
127748 +
127749 +void bman_destroy_portal(struct bman_portal *bm)
127750 +{
127751 + const struct bm_portal_config *pcfg;
127752 + pcfg = bm->config;
127753 + bm_rcr_cce_update(&bm->p);
127754 + bm_rcr_cce_update(&bm->p);
127755 +
127756 + free_irq(pcfg->public_cfg.irq, bm);
127757 +
127758 + kfree(bm->pools);
127759 + bm_isr_finish(&bm->p);
127760 + bm_mc_finish(&bm->p);
127761 + bm_rcr_finish(&bm->p);
127762 + bm->config = NULL;
127763 + if (bm->alloced)
127764 + kfree(bm);
127765 +}
127766 +
127767 +const struct bm_portal_config *bman_destroy_affine_portal(void)
127768 +{
127769 + struct bman_portal *bm = get_raw_affine_portal();
127770 + const struct bm_portal_config *pcfg;
127771 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127772 + if (bm->sharing_redirect) {
127773 + bm->sharing_redirect = NULL;
127774 + put_affine_portal();
127775 + return NULL;
127776 + }
127777 + bm->is_shared = 0;
127778 +#endif
127779 + pcfg = bm->config;
127780 + bman_destroy_portal(bm);
127781 + spin_lock(&affine_mask_lock);
127782 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
127783 + spin_unlock(&affine_mask_lock);
127784 + put_affine_portal();
127785 + return pcfg;
127786 +}
127787 +
127788 +/* When release logic waits on available RCR space, we need a global waitqueue
127789 + * in the case of "affine" use (as the waits wake on different cpus which means
127790 + * different portals - so we can't wait on any per-portal waitqueue). */
127791 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
127792 +
127793 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
127794 +{
127795 + struct bman_depletion tmp;
127796 + u32 ret = is;
127797 +
127798 + /* There is a gotcha to be aware of. If we do the query before clearing
127799 + * the status register, we may miss state changes that occur between the
127800 + * two. If we write to clear the status register before the query, the
127801 + * cache-enabled query command may overtake the status register write
127802 + * unless we use a heavyweight sync (which we don't want). Instead, we
127803 + * write-to-clear the status register then *read it back* before doing
127804 + * the query, hence the odd while loop with the 'is' accumulation. */
127805 + if (is & BM_PIRQ_BSCN) {
127806 + struct bm_mc_result *mcr;
127807 + __maybe_unused unsigned long irqflags;
127808 + unsigned int i, j;
127809 + u32 __is;
127810 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
127811 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
127812 + is |= __is;
127813 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
127814 + }
127815 + is &= ~BM_PIRQ_BSCN;
127816 + PORTAL_IRQ_LOCK(p, irqflags);
127817 + bm_mc_start(&p->p);
127818 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
127819 + while (!(mcr = bm_mc_result(&p->p)))
127820 + cpu_relax();
127821 + tmp = mcr->query.ds.state;
127822 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
127823 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
127824 + PORTAL_IRQ_UNLOCK(p, irqflags);
127825 + for (i = 0; i < 2; i++) {
127826 + int idx = i * 32;
127827 + /* tmp is a mask of currently-depleted pools.
127828 + * pools[0] is mask of those we care about.
127829 + * pools[1] is our previous view (we only want to
127830 + * be told about changes). */
127831 + tmp.__state[i] &= p->pools[0].__state[i];
127832 + if (tmp.__state[i] == p->pools[1].__state[i])
127833 + /* fast-path, nothing to see, move along */
127834 + continue;
127835 + for (j = 0; j <= 31; j++, idx++) {
127836 + struct bman_pool *pool = p->cb[idx];
127837 + int b4 = bman_depletion_get(&p->pools[1], idx);
127838 + int af = bman_depletion_get(&tmp, idx);
127839 + if (b4 == af)
127840 + continue;
127841 + while (pool) {
127842 + pool->params.cb(p, pool,
127843 + pool->params.cb_ctx, af);
127844 + pool = pool->next;
127845 + }
127846 + }
127847 + }
127848 + p->pools[1] = tmp;
127849 + }
127850 +
127851 + if (is & BM_PIRQ_RCRI) {
127852 + __maybe_unused unsigned long irqflags;
127853 + PORTAL_IRQ_LOCK(p, irqflags);
127854 + bm_rcr_cce_update(&p->p);
127855 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127856 + /* If waiting for sync, we only cancel the interrupt threshold
127857 + * when the ring utilisation hits zero. */
127858 + if (p->rcri_owned) {
127859 + if (!bm_rcr_get_fill(&p->p)) {
127860 + p->rcri_owned = NULL;
127861 + bm_rcr_set_ithresh(&p->p, 0);
127862 + }
127863 + } else
127864 +#endif
127865 + bm_rcr_set_ithresh(&p->p, 0);
127866 + PORTAL_IRQ_UNLOCK(p, irqflags);
127867 + wake_up(&affine_queue);
127868 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
127869 + is &= ~BM_PIRQ_RCRI;
127870 + }
127871 +
127872 + /* There should be no status register bits left undefined */
127873 + DPA_ASSERT(!is);
127874 + return ret;
127875 +}
127876 +
127877 +const struct bman_portal_config *bman_get_portal_config(void)
127878 +{
127879 + struct bman_portal *p = get_affine_portal();
127880 + const struct bman_portal_config *ret = &p->config->public_cfg;
127881 + put_affine_portal();
127882 + return ret;
127883 +}
127884 +EXPORT_SYMBOL(bman_get_portal_config);
127885 +
127886 +u32 bman_irqsource_get(void)
127887 +{
127888 + struct bman_portal *p = get_raw_affine_portal();
127889 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
127890 + put_affine_portal();
127891 + return ret;
127892 +}
127893 +EXPORT_SYMBOL(bman_irqsource_get);
127894 +
127895 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
127896 +{
127897 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127898 + if (p->sharing_redirect)
127899 + return -EINVAL;
127900 + else
127901 +#endif
127902 + {
127903 + __maybe_unused unsigned long irqflags;
127904 + PORTAL_IRQ_LOCK(p, irqflags);
127905 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
127906 + bm_isr_enable_write(&p->p, p->irq_sources);
127907 + PORTAL_IRQ_UNLOCK(p, irqflags);
127908 + }
127909 + return 0;
127910 +}
127911 +EXPORT_SYMBOL(bman_p_irqsource_add);
127912 +
127913 +int bman_irqsource_add(__maybe_unused u32 bits)
127914 +{
127915 + struct bman_portal *p = get_raw_affine_portal();
127916 + int ret = 0;
127917 + ret = bman_p_irqsource_add(p, bits);
127918 + put_affine_portal();
127919 + return ret;
127920 +}
127921 +EXPORT_SYMBOL(bman_irqsource_add);
127922 +
127923 +int bman_irqsource_remove(u32 bits)
127924 +{
127925 + struct bman_portal *p = get_raw_affine_portal();
127926 + __maybe_unused unsigned long irqflags;
127927 + u32 ier;
127928 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127929 + if (p->sharing_redirect) {
127930 + put_affine_portal();
127931 + return -EINVAL;
127932 + }
127933 +#endif
127934 + /* Our interrupt handler only processes+clears status register bits that
127935 + * are in p->irq_sources. As we're trimming that mask, if one of them
127936 + * were to assert in the status register just before we remove it from
127937 + * the enable register, there would be an interrupt-storm when we
127938 + * release the IRQ lock. So we wait for the enable register update to
127939 + * take effect in h/w (by reading it back) and then clear all other bits
127940 + * in the status register. Ie. we clear them from ISR once it's certain
127941 + * IER won't allow them to reassert. */
127942 + PORTAL_IRQ_LOCK(p, irqflags);
127943 + bits &= BM_PIRQ_VISIBLE;
127944 + clear_bits(bits, &p->irq_sources);
127945 + bm_isr_enable_write(&p->p, p->irq_sources);
127946 + ier = bm_isr_enable_read(&p->p);
127947 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
127948 + * data-dependency, ie. to protect against re-ordering. */
127949 + bm_isr_status_clear(&p->p, ~ier);
127950 + PORTAL_IRQ_UNLOCK(p, irqflags);
127951 + put_affine_portal();
127952 + return 0;
127953 +}
127954 +EXPORT_SYMBOL(bman_irqsource_remove);
127955 +
127956 +const cpumask_t *bman_affine_cpus(void)
127957 +{
127958 + return &affine_mask;
127959 +}
127960 +EXPORT_SYMBOL(bman_affine_cpus);
127961 +
127962 +u32 bman_poll_slow(void)
127963 +{
127964 + struct bman_portal *p = get_poll_portal();
127965 + u32 ret;
127966 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127967 + if (unlikely(p->sharing_redirect))
127968 + ret = (u32)-1;
127969 + else
127970 +#endif
127971 + {
127972 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
127973 + ret = __poll_portal_slow(p, is);
127974 + bm_isr_status_clear(&p->p, ret);
127975 + }
127976 + put_poll_portal();
127977 + return ret;
127978 +}
127979 +EXPORT_SYMBOL(bman_poll_slow);
127980 +
127981 +/* Legacy wrapper */
127982 +void bman_poll(void)
127983 +{
127984 + struct bman_portal *p = get_poll_portal();
127985 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127986 + if (unlikely(p->sharing_redirect))
127987 + goto done;
127988 +#endif
127989 + if (!(p->slowpoll--)) {
127990 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
127991 + u32 active = __poll_portal_slow(p, is);
127992 + if (active)
127993 + p->slowpoll = SLOW_POLL_BUSY;
127994 + else
127995 + p->slowpoll = SLOW_POLL_IDLE;
127996 + }
127997 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127998 +done:
127999 +#endif
128000 + put_poll_portal();
128001 +}
128002 +EXPORT_SYMBOL(bman_poll);
128003 +
128004 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
128005 +
128006 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
128007 +{
128008 + struct bman_pool *pool = NULL;
128009 + u32 bpid;
128010 +
128011 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
128012 + int ret = bman_alloc_bpid(&bpid);
128013 + if (ret)
128014 + return NULL;
128015 + } else {
128016 + if (params->bpid >= bman_pool_max)
128017 + return NULL;
128018 + bpid = params->bpid;
128019 + }
128020 +#ifdef CONFIG_FSL_BMAN_CONFIG
128021 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
128022 + int ret = bm_pool_set(bpid, params->thresholds);
128023 + if (ret)
128024 + goto err;
128025 + }
128026 +#else
128027 + if (params->flags & BMAN_POOL_FLAG_THRESH)
128028 + goto err;
128029 +#endif
128030 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
128031 + if (!pool)
128032 + goto err;
128033 + pool->sp = NULL;
128034 + pool->sp_fill = 0;
128035 + pool->params = *params;
128036 +#ifdef CONFIG_FSL_DPA_CHECKING
128037 + atomic_set(&pool->in_use, 1);
128038 +#endif
128039 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
128040 + pool->params.bpid = bpid;
128041 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
128042 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
128043 + GFP_KERNEL);
128044 + if (!pool->sp)
128045 + goto err;
128046 + }
128047 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
128048 + struct bman_portal *p = get_affine_portal();
128049 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
128050 + pr_err("Depletion events disabled for bpid %d\n", bpid);
128051 + goto err;
128052 + }
128053 + depletion_link(p, pool);
128054 + put_affine_portal();
128055 + }
128056 + return pool;
128057 +err:
128058 +#ifdef CONFIG_FSL_BMAN_CONFIG
128059 + if (params->flags & BMAN_POOL_FLAG_THRESH)
128060 + bm_pool_set(bpid, zero_thresholds);
128061 +#endif
128062 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
128063 + bman_release_bpid(bpid);
128064 + if (pool) {
128065 + kfree(pool->sp);
128066 + kfree(pool);
128067 + }
128068 + return NULL;
128069 +}
128070 +EXPORT_SYMBOL(bman_new_pool);
128071 +
128072 +void bman_free_pool(struct bman_pool *pool)
128073 +{
128074 +#ifdef CONFIG_FSL_BMAN_CONFIG
128075 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
128076 + bm_pool_set(pool->params.bpid, zero_thresholds);
128077 +#endif
128078 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
128079 + depletion_unlink(pool);
128080 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
128081 + if (pool->sp_fill)
128082 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
128083 + pool->sp_fill, pool->params.bpid);
128084 + kfree(pool->sp);
128085 + pool->sp = NULL;
128086 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
128087 + }
128088 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
128089 + bman_release_bpid(pool->params.bpid);
128090 + kfree(pool);
128091 +}
128092 +EXPORT_SYMBOL(bman_free_pool);
128093 +
128094 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
128095 +{
128096 + return &pool->params;
128097 +}
128098 +EXPORT_SYMBOL(bman_get_params);
128099 +
128100 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
128101 +{
128102 + if (avail)
128103 + bm_rcr_cce_prefetch(&p->p);
128104 + else
128105 + bm_rcr_cce_update(&p->p);
128106 +}
128107 +
128108 +int bman_rcr_is_empty(void)
128109 +{
128110 + __maybe_unused unsigned long irqflags;
128111 + struct bman_portal *p = get_affine_portal();
128112 + u8 avail;
128113 +
128114 + PORTAL_IRQ_LOCK(p, irqflags);
128115 + update_rcr_ci(p, 0);
128116 + avail = bm_rcr_get_fill(&p->p);
128117 + PORTAL_IRQ_UNLOCK(p, irqflags);
128118 + put_affine_portal();
128119 + return avail == 0;
128120 +}
128121 +EXPORT_SYMBOL(bman_rcr_is_empty);
128122 +
128123 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
128124 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
128125 + __maybe_unused struct bman_pool *pool,
128126 +#endif
128127 + __maybe_unused unsigned long *irqflags,
128128 + __maybe_unused u32 flags)
128129 +{
128130 + struct bm_rcr_entry *r;
128131 + u8 avail;
128132 +
128133 + *p = get_affine_portal();
128134 + PORTAL_IRQ_LOCK(*p, (*irqflags));
128135 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128136 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128137 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
128138 + if ((*p)->rcri_owned) {
128139 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
128140 + put_affine_portal();
128141 + return NULL;
128142 + }
128143 + (*p)->rcri_owned = pool;
128144 + }
128145 +#endif
128146 + avail = bm_rcr_get_avail(&(*p)->p);
128147 + if (avail < 2)
128148 + update_rcr_ci(*p, avail);
128149 + r = bm_rcr_start(&(*p)->p);
128150 + if (unlikely(!r)) {
128151 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128152 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128153 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
128154 + (*p)->rcri_owned = NULL;
128155 +#endif
128156 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
128157 + put_affine_portal();
128158 + }
128159 + return r;
128160 +}
128161 +
128162 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
128163 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
128164 + struct bman_pool *pool,
128165 + __maybe_unused unsigned long *irqflags,
128166 + u32 flags)
128167 +{
128168 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
128169 + if (!rcr)
128170 + bm_rcr_set_ithresh(&(*p)->p, 1);
128171 + return rcr;
128172 +}
128173 +
128174 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
128175 + struct bman_pool *pool,
128176 + __maybe_unused unsigned long *irqflags,
128177 + u32 flags)
128178 +{
128179 + struct bm_rcr_entry *rcr;
128180 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128181 + pool = NULL;
128182 +#endif
128183 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
128184 + /* NB: return NULL if signal occurs before completion. Signal
128185 + * can occur during return. Caller must check for signal */
128186 + wait_event_interruptible(affine_queue,
128187 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
128188 + else
128189 + wait_event(affine_queue,
128190 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
128191 + return rcr;
128192 +}
128193 +#endif
128194 +
128195 +static inline int __bman_release(struct bman_pool *pool,
128196 + const struct bm_buffer *bufs, u8 num, u32 flags)
128197 +{
128198 + struct bman_portal *p;
128199 + struct bm_rcr_entry *r;
128200 + __maybe_unused unsigned long irqflags;
128201 + u32 i = num - 1;
128202 +
128203 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
128204 + if (flags & BMAN_RELEASE_FLAG_WAIT)
128205 + r = wait_rel_start(&p, pool, &irqflags, flags);
128206 + else
128207 + r = try_rel_start(&p, pool, &irqflags, flags);
128208 +#else
128209 + r = try_rel_start(&p, &irqflags, flags);
128210 +#endif
128211 + if (!r)
128212 + return -EBUSY;
128213 + /* We can copy all but the first entry, as this can trigger badness
128214 + * with the valid-bit. Use the overlay to mask the verb byte. */
128215 + r->bufs[0].opaque =
128216 + ((cpu_to_be64((bufs[0].opaque |
128217 + ((u64)pool->params.bpid<<48))
128218 + & 0x00ffffffffffffff)));
128219 + if (i) {
128220 + for (i = 1; i < num; i++)
128221 + r->bufs[i].opaque =
128222 + cpu_to_be64(bufs[i].opaque);
128223 + }
128224 +
128225 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
128226 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
128227 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128228 + /* if we wish to sync we need to set the threshold after h/w sees the
128229 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
128230 + * accesses, this requires a heavy-weight sync. */
128231 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128232 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
128233 + hwsync();
128234 + bm_rcr_set_ithresh(&p->p, 1);
128235 + }
128236 +#endif
128237 + PORTAL_IRQ_UNLOCK(p, irqflags);
128238 + put_affine_portal();
128239 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128240 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128241 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
128242 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
128243 + /* NB: return success even if signal occurs before
128244 + * condition is true. pvb_commit guarantees success */
128245 + wait_event_interruptible(affine_queue,
128246 + (p->rcri_owned != pool));
128247 + else
128248 + wait_event(affine_queue, (p->rcri_owned != pool));
128249 + }
128250 +#endif
128251 + return 0;
128252 +}
128253 +
128254 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
128255 + u32 flags)
128256 +{
128257 + int ret;
128258 +#ifdef CONFIG_FSL_DPA_CHECKING
128259 + if (!num || (num > 8))
128260 + return -EINVAL;
128261 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
128262 + return -EINVAL;
128263 +#endif
128264 + /* Without stockpile, this API is a pass-through to the h/w operation */
128265 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
128266 + return __bman_release(pool, bufs, num, flags);
128267 +#ifdef CONFIG_FSL_DPA_CHECKING
128268 + if (!atomic_dec_and_test(&pool->in_use)) {
128269 + pr_crit("Parallel attempts to enter bman_released() detected.");
128270 + panic("only one instance of bman_released/acquired allowed");
128271 + }
128272 +#endif
128273 + /* Two movements of buffers are possible, and can occur in either order.
128274 + * A: moving buffers from the caller to the stockpile.
128275 + * B: moving buffers from the stockpile to hardware.
128276 + * Order 1: if there is already enough space in the stockpile for A
128277 + * then we want to do A first, and only do B if we trigger the
128278 + * stockpile-high threshold.
128279 + * Order 2: if there is not enough space in the stockpile for A, then
128280 + * we want to do B first, then do A if B had succeeded. However in this
128281 + * case B is dependent on how many buffers the user needs to release,
128282 + * not the stockpile-high threshold.
128283 + * Due to the different handling of B between the two cases, putting A
128284 + * and B in a while() loop would require quite obscure logic, so handle
128285 + * the different sequences explicitly. */
128286 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
128287 + /* Order 1: do A */
128288 + copy_words(pool->sp + pool->sp_fill, bufs,
128289 + sizeof(struct bm_buffer) * num);
128290 + pool->sp_fill += num;
128291 + /* do B relative to STOCKPILE_HIGH */
128292 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
128293 + ret = __bman_release(pool,
128294 + pool->sp + (pool->sp_fill - 8), 8,
128295 + flags);
128296 + if (ret >= 0)
128297 + pool->sp_fill -= 8;
128298 + }
128299 + } else {
128300 + /* Order 2: do B relative to 'num' */
128301 + do {
128302 + ret = __bman_release(pool,
128303 + pool->sp + (pool->sp_fill - 8), 8,
128304 + flags);
128305 + if (ret < 0)
128306 + /* failure */
128307 + goto release_done;
128308 + pool->sp_fill -= 8;
128309 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
128310 + /* do A */
128311 + copy_words(pool->sp + pool->sp_fill, bufs,
128312 + sizeof(struct bm_buffer) * num);
128313 + pool->sp_fill += num;
128314 + }
128315 + /* success */
128316 + ret = 0;
128317 +release_done:
128318 +#ifdef CONFIG_FSL_DPA_CHECKING
128319 + atomic_inc(&pool->in_use);
128320 +#endif
128321 + return ret;
128322 +}
128323 +EXPORT_SYMBOL(bman_release);
128324 +
128325 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
128326 + u8 num)
128327 +{
128328 + struct bman_portal *p = get_affine_portal();
128329 + struct bm_mc_command *mcc;
128330 + struct bm_mc_result *mcr;
128331 + __maybe_unused unsigned long irqflags;
128332 + int ret, i;
128333 +
128334 + PORTAL_IRQ_LOCK(p, irqflags);
128335 + mcc = bm_mc_start(&p->p);
128336 + mcc->acquire.bpid = pool->params.bpid;
128337 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
128338 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
128339 + while (!(mcr = bm_mc_result(&p->p)))
128340 + cpu_relax();
128341 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
128342 + if (bufs) {
128343 + for (i = 0; i < num; i++)
128344 + bufs[i].opaque =
128345 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
128346 + }
128347 + PORTAL_IRQ_UNLOCK(p, irqflags);
128348 + put_affine_portal();
128349 + if (ret != num)
128350 + ret = -ENOMEM;
128351 + return ret;
128352 +}
128353 +
128354 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
128355 + u32 flags)
128356 +{
128357 + int ret;
128358 +#ifdef CONFIG_FSL_DPA_CHECKING
128359 + if (!num || (num > 8))
128360 + return -EINVAL;
128361 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
128362 + return -EINVAL;
128363 +#endif
128364 + /* Without stockpile, this API is a pass-through to the h/w operation */
128365 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
128366 + return __bman_acquire(pool, bufs, num);
128367 +#ifdef CONFIG_FSL_DPA_CHECKING
128368 + if (!atomic_dec_and_test(&pool->in_use)) {
128369 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
128370 + panic("only one instance of bman_released/acquired allowed");
128371 + }
128372 +#endif
128373 + /* Two movements of buffers are possible, and can occur in either order.
128374 + * A: moving buffers from stockpile to the caller.
128375 + * B: moving buffers from hardware to the stockpile.
128376 + * Order 1: if there are already enough buffers in the stockpile for A
128377 + * then we want to do A first, and only do B if we trigger the
128378 + * stockpile-low threshold.
128379 + * Order 2: if there are not enough buffers in the stockpile for A,
128380 + * then we want to do B first, then do A if B had succeeded. However in
128381 + * this case B is dependent on how many buffers the user needs, not the
128382 + * stockpile-low threshold.
128383 + * Due to the different handling of B between the two cases, putting A
128384 + * and B in a while() loop would require quite obscure logic, so handle
128385 + * the different sequences explicitly. */
128386 + if (num <= pool->sp_fill) {
128387 + /* Order 1: do A */
128388 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
128389 + sizeof(struct bm_buffer) * num);
128390 + pool->sp_fill -= num;
128391 + /* do B relative to STOCKPILE_LOW */
128392 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
128393 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
128394 + if (ret < 0)
128395 + ret = __bman_acquire(pool,
128396 + pool->sp + pool->sp_fill, 1);
128397 + if (ret < 0)
128398 + break;
128399 + pool->sp_fill += ret;
128400 + }
128401 + } else {
128402 + /* Order 2: do B relative to 'num' */
128403 + do {
128404 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
128405 + if (ret < 0)
128406 + ret = __bman_acquire(pool,
128407 + pool->sp + pool->sp_fill, 1);
128408 + if (ret < 0)
128409 + /* failure */
128410 + goto acquire_done;
128411 + pool->sp_fill += ret;
128412 + } while (pool->sp_fill < num);
128413 + /* do A */
128414 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
128415 + sizeof(struct bm_buffer) * num);
128416 + pool->sp_fill -= num;
128417 + }
128418 + /* success */
128419 + ret = num;
128420 +acquire_done:
128421 +#ifdef CONFIG_FSL_DPA_CHECKING
128422 + atomic_inc(&pool->in_use);
128423 +#endif
128424 + return ret;
128425 +}
128426 +EXPORT_SYMBOL(bman_acquire);
128427 +
128428 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
128429 +{
128430 + u8 num;
128431 + int ret;
128432 +
128433 + while (pool->sp_fill) {
128434 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
128435 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
128436 + num, flags);
128437 + if (ret)
128438 + return ret;
128439 + pool->sp_fill -= num;
128440 + }
128441 + return 0;
128442 +}
128443 +EXPORT_SYMBOL(bman_flush_stockpile);
128444 +
128445 +int bman_query_pools(struct bm_pool_state *state)
128446 +{
128447 + struct bman_portal *p = get_affine_portal();
128448 + struct bm_mc_result *mcr;
128449 + __maybe_unused unsigned long irqflags;
128450 +
128451 + PORTAL_IRQ_LOCK(p, irqflags);
128452 + bm_mc_start(&p->p);
128453 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
128454 + while (!(mcr = bm_mc_result(&p->p)))
128455 + cpu_relax();
128456 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
128457 + *state = mcr->query;
128458 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
128459 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
128460 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
128461 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
128462 + PORTAL_IRQ_UNLOCK(p, irqflags);
128463 + put_affine_portal();
128464 + return 0;
128465 +}
128466 +EXPORT_SYMBOL(bman_query_pools);
128467 +
128468 +#ifdef CONFIG_FSL_BMAN_CONFIG
128469 +u32 bman_query_free_buffers(struct bman_pool *pool)
128470 +{
128471 + return bm_pool_free_buffers(pool->params.bpid);
128472 +}
128473 +EXPORT_SYMBOL(bman_query_free_buffers);
128474 +
128475 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
128476 +{
128477 + u32 bpid;
128478 +
128479 + bpid = bman_get_params(pool)->bpid;
128480 +
128481 + return bm_pool_set(bpid, thresholds);
128482 +}
128483 +EXPORT_SYMBOL(bman_update_pool_thresholds);
128484 +#endif
128485 +
128486 +int bman_shutdown_pool(u32 bpid)
128487 +{
128488 + struct bman_portal *p = get_affine_portal();
128489 + __maybe_unused unsigned long irqflags;
128490 + int ret;
128491 +
128492 + PORTAL_IRQ_LOCK(p, irqflags);
128493 + ret = bm_shutdown_pool(&p->p, bpid);
128494 + PORTAL_IRQ_UNLOCK(p, irqflags);
128495 + put_affine_portal();
128496 + return ret;
128497 +}
128498 +EXPORT_SYMBOL(bman_shutdown_pool);
128499 +
128500 +const struct bm_portal_config *bman_get_bm_portal_config(
128501 + struct bman_portal *portal)
128502 +{
128503 + return portal->sharing_redirect ? NULL : portal->config;
128504 +}
128505 --- /dev/null
128506 +++ b/drivers/staging/fsl_qbman/bman_low.h
128507 @@ -0,0 +1,565 @@
128508 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128509 + *
128510 + * Redistribution and use in source and binary forms, with or without
128511 + * modification, are permitted provided that the following conditions are met:
128512 + * * Redistributions of source code must retain the above copyright
128513 + * notice, this list of conditions and the following disclaimer.
128514 + * * Redistributions in binary form must reproduce the above copyright
128515 + * notice, this list of conditions and the following disclaimer in the
128516 + * documentation and/or other materials provided with the distribution.
128517 + * * Neither the name of Freescale Semiconductor nor the
128518 + * names of its contributors may be used to endorse or promote products
128519 + * derived from this software without specific prior written permission.
128520 + *
128521 + *
128522 + * ALTERNATIVELY, this software may be distributed under the terms of the
128523 + * GNU General Public License ("GPL") as published by the Free Software
128524 + * Foundation, either version 2 of that License or (at your option) any
128525 + * later version.
128526 + *
128527 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128528 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128529 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128530 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128531 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128532 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128533 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128534 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128535 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128536 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128537 + */
128538 +
128539 +#include "bman_private.h"
128540 +
128541 +/***************************/
128542 +/* Portal register assists */
128543 +/***************************/
128544 +
128545 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
128546 +
128547 +/* Cache-inhibited register offsets */
128548 +#define BM_REG_RCR_PI_CINH 0x0000
128549 +#define BM_REG_RCR_CI_CINH 0x0004
128550 +#define BM_REG_RCR_ITR 0x0008
128551 +#define BM_REG_CFG 0x0100
128552 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
128553 +#define BM_REG_ISR 0x0e00
128554 +#define BM_REG_IIR 0x0e0c
128555 +
128556 +/* Cache-enabled register offsets */
128557 +#define BM_CL_CR 0x0000
128558 +#define BM_CL_RR0 0x0100
128559 +#define BM_CL_RR1 0x0140
128560 +#define BM_CL_RCR 0x1000
128561 +#define BM_CL_RCR_PI_CENA 0x3000
128562 +#define BM_CL_RCR_CI_CENA 0x3100
128563 +
128564 +#endif
128565 +
128566 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
128567 +
128568 +/* Cache-inhibited register offsets */
128569 +#define BM_REG_RCR_PI_CINH 0x3000
128570 +#define BM_REG_RCR_CI_CINH 0x3100
128571 +#define BM_REG_RCR_ITR 0x3200
128572 +#define BM_REG_CFG 0x3300
128573 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
128574 +#define BM_REG_ISR 0x3e00
128575 +#define BM_REG_IIR 0x3ec0
128576 +
128577 +/* Cache-enabled register offsets */
128578 +#define BM_CL_CR 0x0000
128579 +#define BM_CL_RR0 0x0100
128580 +#define BM_CL_RR1 0x0140
128581 +#define BM_CL_RCR 0x1000
128582 +#define BM_CL_RCR_PI_CENA 0x3000
128583 +#define BM_CL_RCR_CI_CENA 0x3100
128584 +
128585 +#endif
128586 +
128587 +/* BTW, the drivers (and h/w programming model) already obtain the required
128588 + * synchronisation for portal accesses via lwsync(), hwsync(), and
128589 + * data-dependencies. Use of barrier()s or other order-preserving primitives
128590 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
128591 + * simply ensure that the compiler treats the portal registers as volatile (ie.
128592 + * non-coherent). */
128593 +
128594 +/* Cache-inhibited register access. */
128595 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
128596 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
128597 + (bm)->addr_ci + (o));
128598 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
128599 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
128600 +
128601 +/* Cache-enabled (index) register access */
128602 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
128603 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
128604 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
128605 +#define __bm_cl_out(bm, o, val) \
128606 + do { \
128607 + u32 *__tmpclout = (bm)->addr_ce + (o); \
128608 + __raw_writel(cpu_to_be32(val), __tmpclout); \
128609 + dcbf(__tmpclout); \
128610 + } while (0)
128611 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
128612 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
128613 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
128614 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
128615 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
128616 +#define bm_cl_invalidate(reg)\
128617 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
128618 +
128619 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
128620 + * analysis, look at using the "extra" bit in the ring index registers to avoid
128621 + * cyclic issues. */
128622 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
128623 +{
128624 + /* 'first' is included, 'last' is excluded */
128625 + if (first <= last)
128626 + return last - first;
128627 + return ringsize + last - first;
128628 +}
128629 +
128630 +/* Portal modes.
128631 + * Enum types;
128632 + * pmode == production mode
128633 + * cmode == consumption mode,
128634 + * Enum values use 3 letter codes. First letter matches the portal mode,
128635 + * remaining two letters indicate;
128636 + * ci == cache-inhibited portal register
128637 + * ce == cache-enabled portal register
128638 + * vb == in-band valid-bit (cache-enabled)
128639 + */
128640 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
128641 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
128642 + bm_rcr_pce = 1, /* PI index, cache-enabled */
128643 + bm_rcr_pvb = 2 /* valid-bit */
128644 +};
128645 +enum bm_rcr_cmode { /* s/w-only */
128646 + bm_rcr_cci, /* CI index, cache-inhibited */
128647 + bm_rcr_cce /* CI index, cache-enabled */
128648 +};
128649 +
128650 +
128651 +/* ------------------------- */
128652 +/* --- Portal structures --- */
128653 +
128654 +#define BM_RCR_SIZE 8
128655 +
128656 +struct bm_rcr {
128657 + struct bm_rcr_entry *ring, *cursor;
128658 + u8 ci, available, ithresh, vbit;
128659 +#ifdef CONFIG_FSL_DPA_CHECKING
128660 + u32 busy;
128661 + enum bm_rcr_pmode pmode;
128662 + enum bm_rcr_cmode cmode;
128663 +#endif
128664 +};
128665 +
128666 +struct bm_mc {
128667 + struct bm_mc_command *cr;
128668 + struct bm_mc_result *rr;
128669 + u8 rridx, vbit;
128670 +#ifdef CONFIG_FSL_DPA_CHECKING
128671 + enum {
128672 + /* Can only be _mc_start()ed */
128673 + mc_idle,
128674 + /* Can only be _mc_commit()ed or _mc_abort()ed */
128675 + mc_user,
128676 + /* Can only be _mc_retry()ed */
128677 + mc_hw
128678 + } state;
128679 +#endif
128680 +};
128681 +
128682 +struct bm_addr {
128683 + void __iomem *addr_ce; /* cache-enabled */
128684 + void __iomem *addr_ci; /* cache-inhibited */
128685 +};
128686 +
128687 +struct bm_portal {
128688 + struct bm_addr addr;
128689 + struct bm_rcr rcr;
128690 + struct bm_mc mc;
128691 + struct bm_portal_config config;
128692 +} ____cacheline_aligned;
128693 +
128694 +
128695 +/* --------------- */
128696 +/* --- RCR API --- */
128697 +
128698 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
128699 +#define RCR_CARRYCLEAR(p) \
128700 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
128701 +
128702 +/* Bit-wise logic to convert a ring pointer to a ring index */
128703 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
128704 +{
128705 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
128706 +}
128707 +
128708 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
128709 +static inline void RCR_INC(struct bm_rcr *rcr)
128710 +{
128711 + /* NB: this is odd-looking, but experiments show that it generates
128712 + * fast code with essentially no branching overheads. We increment to
128713 + * the next RCR pointer and handle overflow and 'vbit'. */
128714 + struct bm_rcr_entry *partial = rcr->cursor + 1;
128715 + rcr->cursor = RCR_CARRYCLEAR(partial);
128716 + if (partial != rcr->cursor)
128717 + rcr->vbit ^= BM_RCR_VERB_VBIT;
128718 +}
128719 +
128720 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
128721 + __maybe_unused enum bm_rcr_cmode cmode)
128722 +{
128723 + /* This use of 'register', as well as all other occurrences, is because
128724 + * it has been observed to generate much faster code with gcc than is
128725 + * otherwise the case. */
128726 + register struct bm_rcr *rcr = &portal->rcr;
128727 + u32 cfg;
128728 + u8 pi;
128729 +
128730 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
128731 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
128732 +
128733 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
128734 + rcr->cursor = rcr->ring + pi;
128735 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
128736 + rcr->available = BM_RCR_SIZE - 1
128737 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
128738 + rcr->ithresh = bm_in(RCR_ITR);
128739 +#ifdef CONFIG_FSL_DPA_CHECKING
128740 + rcr->busy = 0;
128741 + rcr->pmode = pmode;
128742 + rcr->cmode = cmode;
128743 +#endif
128744 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
128745 + bm_out(CFG, cfg);
128746 + return 0;
128747 +}
128748 +
128749 +static inline void bm_rcr_finish(struct bm_portal *portal)
128750 +{
128751 + register struct bm_rcr *rcr = &portal->rcr;
128752 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
128753 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
128754 + DPA_ASSERT(!rcr->busy);
128755 + if (pi != RCR_PTR2IDX(rcr->cursor))
128756 + pr_crit("losing uncommited RCR entries\n");
128757 + if (ci != rcr->ci)
128758 + pr_crit("missing existing RCR completions\n");
128759 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
128760 + pr_crit("RCR destroyed unquiesced\n");
128761 +}
128762 +
128763 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
128764 +{
128765 + register struct bm_rcr *rcr = &portal->rcr;
128766 + DPA_ASSERT(!rcr->busy);
128767 + if (!rcr->available)
128768 + return NULL;
128769 +#ifdef CONFIG_FSL_DPA_CHECKING
128770 + rcr->busy = 1;
128771 +#endif
128772 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
128773 + dcbz_64(rcr->cursor);
128774 +#endif
128775 + return rcr->cursor;
128776 +}
128777 +
128778 +static inline void bm_rcr_abort(struct bm_portal *portal)
128779 +{
128780 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
128781 + DPA_ASSERT(rcr->busy);
128782 +#ifdef CONFIG_FSL_DPA_CHECKING
128783 + rcr->busy = 0;
128784 +#endif
128785 +}
128786 +
128787 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
128788 + struct bm_portal *portal, u8 myverb)
128789 +{
128790 + register struct bm_rcr *rcr = &portal->rcr;
128791 + DPA_ASSERT(rcr->busy);
128792 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
128793 + if (rcr->available == 1)
128794 + return NULL;
128795 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
128796 + dcbf_64(rcr->cursor);
128797 + RCR_INC(rcr);
128798 + rcr->available--;
128799 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
128800 + dcbz_64(rcr->cursor);
128801 +#endif
128802 + return rcr->cursor;
128803 +}
128804 +
128805 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
128806 +{
128807 + register struct bm_rcr *rcr = &portal->rcr;
128808 + DPA_ASSERT(rcr->busy);
128809 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
128810 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
128811 + RCR_INC(rcr);
128812 + rcr->available--;
128813 + hwsync();
128814 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
128815 +#ifdef CONFIG_FSL_DPA_CHECKING
128816 + rcr->busy = 0;
128817 +#endif
128818 +}
128819 +
128820 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
128821 +{
128822 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
128823 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
128824 + bm_cl_invalidate(RCR_PI);
128825 + bm_cl_touch_rw(RCR_PI);
128826 +}
128827 +
128828 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
128829 +{
128830 + register struct bm_rcr *rcr = &portal->rcr;
128831 + DPA_ASSERT(rcr->busy);
128832 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
128833 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
128834 + RCR_INC(rcr);
128835 + rcr->available--;
128836 + lwsync();
128837 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
128838 +#ifdef CONFIG_FSL_DPA_CHECKING
128839 + rcr->busy = 0;
128840 +#endif
128841 +}
128842 +
128843 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
128844 +{
128845 + register struct bm_rcr *rcr = &portal->rcr;
128846 + struct bm_rcr_entry *rcursor;
128847 + DPA_ASSERT(rcr->busy);
128848 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
128849 + lwsync();
128850 + rcursor = rcr->cursor;
128851 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
128852 + dcbf_64(rcursor);
128853 + RCR_INC(rcr);
128854 + rcr->available--;
128855 +#ifdef CONFIG_FSL_DPA_CHECKING
128856 + rcr->busy = 0;
128857 +#endif
128858 +}
128859 +
128860 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
128861 +{
128862 + register struct bm_rcr *rcr = &portal->rcr;
128863 + u8 diff, old_ci = rcr->ci;
128864 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
128865 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
128866 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
128867 + rcr->available += diff;
128868 + return diff;
128869 +}
128870 +
128871 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
128872 +{
128873 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
128874 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
128875 + bm_cl_touch_ro(RCR_CI);
128876 +}
128877 +
128878 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
128879 +{
128880 + register struct bm_rcr *rcr = &portal->rcr;
128881 + u8 diff, old_ci = rcr->ci;
128882 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
128883 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
128884 + bm_cl_invalidate(RCR_CI);
128885 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
128886 + rcr->available += diff;
128887 + return diff;
128888 +}
128889 +
128890 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
128891 +{
128892 + register struct bm_rcr *rcr = &portal->rcr;
128893 + return rcr->ithresh;
128894 +}
128895 +
128896 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
128897 +{
128898 + register struct bm_rcr *rcr = &portal->rcr;
128899 + rcr->ithresh = ithresh;
128900 + bm_out(RCR_ITR, ithresh);
128901 +}
128902 +
128903 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
128904 +{
128905 + register struct bm_rcr *rcr = &portal->rcr;
128906 + return rcr->available;
128907 +}
128908 +
128909 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
128910 +{
128911 + register struct bm_rcr *rcr = &portal->rcr;
128912 + return BM_RCR_SIZE - 1 - rcr->available;
128913 +}
128914 +
128915 +
128916 +/* ------------------------------ */
128917 +/* --- Management command API --- */
128918 +
128919 +static inline int bm_mc_init(struct bm_portal *portal)
128920 +{
128921 + register struct bm_mc *mc = &portal->mc;
128922 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
128923 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
128924 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
128925 + BM_MCC_VERB_VBIT) ? 0 : 1;
128926 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
128927 +#ifdef CONFIG_FSL_DPA_CHECKING
128928 + mc->state = mc_idle;
128929 +#endif
128930 + return 0;
128931 +}
128932 +
128933 +static inline void bm_mc_finish(struct bm_portal *portal)
128934 +{
128935 + __maybe_unused register struct bm_mc *mc = &portal->mc;
128936 + DPA_ASSERT(mc->state == mc_idle);
128937 +#ifdef CONFIG_FSL_DPA_CHECKING
128938 + if (mc->state != mc_idle)
128939 + pr_crit("Losing incomplete MC command\n");
128940 +#endif
128941 +}
128942 +
128943 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
128944 +{
128945 + register struct bm_mc *mc = &portal->mc;
128946 + DPA_ASSERT(mc->state == mc_idle);
128947 +#ifdef CONFIG_FSL_DPA_CHECKING
128948 + mc->state = mc_user;
128949 +#endif
128950 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
128951 + dcbz_64(mc->cr);
128952 +#endif
128953 + return mc->cr;
128954 +}
128955 +
128956 +static inline void bm_mc_abort(struct bm_portal *portal)
128957 +{
128958 + __maybe_unused register struct bm_mc *mc = &portal->mc;
128959 + DPA_ASSERT(mc->state == mc_user);
128960 +#ifdef CONFIG_FSL_DPA_CHECKING
128961 + mc->state = mc_idle;
128962 +#endif
128963 +}
128964 +
128965 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
128966 +{
128967 + register struct bm_mc *mc = &portal->mc;
128968 + struct bm_mc_result *rr = mc->rr + mc->rridx;
128969 + DPA_ASSERT(mc->state == mc_user);
128970 + lwsync();
128971 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
128972 + dcbf(mc->cr);
128973 + dcbit_ro(rr);
128974 +#ifdef CONFIG_FSL_DPA_CHECKING
128975 + mc->state = mc_hw;
128976 +#endif
128977 +}
128978 +
128979 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
128980 +{
128981 + register struct bm_mc *mc = &portal->mc;
128982 + struct bm_mc_result *rr = mc->rr + mc->rridx;
128983 + DPA_ASSERT(mc->state == mc_hw);
128984 + /* The inactive response register's verb byte always returns zero until
128985 + * its command is submitted and completed. This includes the valid-bit,
128986 + * in case you were wondering... */
128987 + if (!__raw_readb(&rr->verb)) {
128988 + dcbit_ro(rr);
128989 + return NULL;
128990 + }
128991 + mc->rridx ^= 1;
128992 + mc->vbit ^= BM_MCC_VERB_VBIT;
128993 +#ifdef CONFIG_FSL_DPA_CHECKING
128994 + mc->state = mc_idle;
128995 +#endif
128996 + return rr;
128997 +}
128998 +
128999 +
129000 +/* ------------------------------------- */
129001 +/* --- Portal interrupt register API --- */
129002 +
129003 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
129004 +{
129005 + return 0;
129006 +}
129007 +
129008 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
129009 +{
129010 +}
129011 +
129012 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
129013 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
129014 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
129015 + int enable)
129016 +{
129017 + u32 val;
129018 + DPA_ASSERT(bpid < bman_pool_max);
129019 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
129020 + val = __bm_in(&portal->addr, SCN_REG(bpid));
129021 + if (enable)
129022 + val |= SCN_BIT(bpid);
129023 + else
129024 + val &= ~SCN_BIT(bpid);
129025 + __bm_out(&portal->addr, SCN_REG(bpid), val);
129026 +}
129027 +
129028 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
129029 +{
129030 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
129031 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
129032 +#else
129033 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
129034 +#endif
129035 +}
129036 +
129037 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
129038 + u32 val)
129039 +{
129040 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
129041 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
129042 +#else
129043 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
129044 +#endif
129045 +}
129046 +
129047 +/* Buffer Pool Cleanup */
129048 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
129049 +{
129050 + struct bm_mc_command *bm_cmd;
129051 + struct bm_mc_result *bm_res;
129052 +
129053 + int aq_count = 0;
129054 + bool stop = false;
129055 + while (!stop) {
129056 + /* Acquire buffers until empty */
129057 + bm_cmd = bm_mc_start(p);
129058 + bm_cmd->acquire.bpid = bpid;
129059 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
129060 + while (!(bm_res = bm_mc_result(p)))
129061 + cpu_relax();
129062 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
129063 + /* Pool is empty */
129064 + /* TBD : Should we do a few extra iterations in
129065 + case some other some blocks keep buffers 'on deck',
129066 + which may also be problematic */
129067 + stop = true;
129068 + } else
129069 + ++aq_count;
129070 + }
129071 + return 0;
129072 +}
129073 --- /dev/null
129074 +++ b/drivers/staging/fsl_qbman/bman_private.h
129075 @@ -0,0 +1,166 @@
129076 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
129077 + *
129078 + * Redistribution and use in source and binary forms, with or without
129079 + * modification, are permitted provided that the following conditions are met:
129080 + * * Redistributions of source code must retain the above copyright
129081 + * notice, this list of conditions and the following disclaimer.
129082 + * * Redistributions in binary form must reproduce the above copyright
129083 + * notice, this list of conditions and the following disclaimer in the
129084 + * documentation and/or other materials provided with the distribution.
129085 + * * Neither the name of Freescale Semiconductor nor the
129086 + * names of its contributors may be used to endorse or promote products
129087 + * derived from this software without specific prior written permission.
129088 + *
129089 + *
129090 + * ALTERNATIVELY, this software may be distributed under the terms of the
129091 + * GNU General Public License ("GPL") as published by the Free Software
129092 + * Foundation, either version 2 of that License or (at your option) any
129093 + * later version.
129094 + *
129095 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129096 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129097 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129098 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129099 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129100 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129101 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129102 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129103 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129104 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129105 + */
129106 +
129107 +#include "dpa_sys.h"
129108 +#include <linux/fsl_bman.h>
129109 +
129110 +/* Revision info (for errata and feature handling) */
129111 +#define BMAN_REV10 0x0100
129112 +#define BMAN_REV20 0x0200
129113 +#define BMAN_REV21 0x0201
129114 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
129115 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
129116 +
129117 +/*
129118 + * Global variables of the max portal/pool number this bman version supported
129119 + */
129120 +extern u16 bman_pool_max;
129121 +
129122 +/* used by CCSR and portal interrupt code */
129123 +enum bm_isr_reg {
129124 + bm_isr_status = 0,
129125 + bm_isr_enable = 1,
129126 + bm_isr_disable = 2,
129127 + bm_isr_inhibit = 3
129128 +};
129129 +
129130 +struct bm_portal_config {
129131 + /* Corenet portal addresses;
129132 + * [0]==cache-enabled, [1]==cache-inhibited. */
129133 + __iomem void *addr_virt[2];
129134 + struct resource addr_phys[2];
129135 + /* Allow these to be joined in lists */
129136 + struct list_head list;
129137 + /* User-visible portal configuration settings */
129138 + struct bman_portal_config public_cfg;
129139 + /* power management saved data */
129140 + u32 saved_isdr;
129141 +};
129142 +
129143 +#ifdef CONFIG_FSL_BMAN_CONFIG
129144 +/* Hooks from bman_driver.c to bman_config.c */
129145 +int bman_init_ccsr(struct device_node *node);
129146 +#endif
129147 +
129148 +/* Hooks from bman_driver.c in to bman_high.c */
129149 +struct bman_portal *bman_create_portal(
129150 + struct bman_portal *portal,
129151 + const struct bm_portal_config *config);
129152 +struct bman_portal *bman_create_affine_portal(
129153 + const struct bm_portal_config *config);
129154 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
129155 + int cpu);
129156 +void bman_destroy_portal(struct bman_portal *bm);
129157 +
129158 +const struct bm_portal_config *bman_destroy_affine_portal(void);
129159 +
129160 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
129161 +struct bm_portal_config *bm_get_unused_portal(void);
129162 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
129163 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
129164 +void bm_set_liodns(struct bm_portal_config *pcfg);
129165 +
129166 +/* Pool logic in the portal driver, during initialisation, needs to know if
129167 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
129168 +#ifdef CONFIG_FSL_BMAN_CONFIG
129169 +int bman_have_ccsr(void);
129170 +#else
129171 +#define bman_have_ccsr() 0
129172 +#endif
129173 +
129174 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
129175 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
129176 + * might fail (if the buffer pool is depleted). So this value provides some
129177 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
129178 + * are requested at once or if h/w has been tested a couple of times without
129179 + * luck. The _HIGH value: when bman_release() is called and the stockpile
129180 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
129181 + * the release ring is full). So this value provides some "stagger" so that
129182 + * ring-access is retried a couple of times prior to the API returning a
129183 + * failure. The following *must* be true;
129184 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
129185 + * (to avoid thrashing)
129186 + * BMAN_STOCKPILE_SZ >= 16
129187 + * (as the release logic expects to either send 8 buffers to hw prior to
129188 + * adding the given buffers to the stockpile or add the buffers to the
129189 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
129190 + * success/fail.)
129191 + */
129192 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
129193 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
129194 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
129195 +
129196 +/*************************************************/
129197 +/* BMan s/w corenet portal, low-level i/face */
129198 +/*************************************************/
129199 +
129200 +/* Used by all portal interrupt registers except 'inhibit'
129201 + * This mask contains all the "irqsource" bits visible to API users
129202 + */
129203 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
129204 +
129205 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
129206 + * the disable register" rather than "disable the ability to write". */
129207 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
129208 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
129209 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
129210 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
129211 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
129212 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
129213 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
129214 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
129215 +
129216 +#ifdef CONFIG_FSL_BMAN_CONFIG
129217 +/* Set depletion thresholds associated with a buffer pool. Requires that the
129218 + * operating system have access to Bman CCSR (ie. compiled in support and
129219 + * run-time access courtesy of the device-tree). */
129220 +int bm_pool_set(u32 bpid, const u32 *thresholds);
129221 +#define BM_POOL_THRESH_SW_ENTER 0
129222 +#define BM_POOL_THRESH_SW_EXIT 1
129223 +#define BM_POOL_THRESH_HW_ENTER 2
129224 +#define BM_POOL_THRESH_HW_EXIT 3
129225 +
129226 +/* Read the free buffer count for a given buffer */
129227 +u32 bm_pool_free_buffers(u32 bpid);
129228 +
129229 +__init int bman_init(void);
129230 +__init int bman_resource_init(void);
129231 +
129232 +const struct bm_portal_config *bman_get_bm_portal_config(
129233 + struct bman_portal *portal);
129234 +
129235 +/* power management */
129236 +#ifdef CONFIG_SUSPEND
129237 +void suspend_unused_bportal(void);
129238 +void resume_unused_bportal(void);
129239 +#endif
129240 +
129241 +#endif /* CONFIG_FSL_BMAN_CONFIG */
129242 --- /dev/null
129243 +++ b/drivers/staging/fsl_qbman/bman_test.c
129244 @@ -0,0 +1,56 @@
129245 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
129246 + *
129247 + * Redistribution and use in source and binary forms, with or without
129248 + * modification, are permitted provided that the following conditions are met:
129249 + * * Redistributions of source code must retain the above copyright
129250 + * notice, this list of conditions and the following disclaimer.
129251 + * * Redistributions in binary form must reproduce the above copyright
129252 + * notice, this list of conditions and the following disclaimer in the
129253 + * documentation and/or other materials provided with the distribution.
129254 + * * Neither the name of Freescale Semiconductor nor the
129255 + * names of its contributors may be used to endorse or promote products
129256 + * derived from this software without specific prior written permission.
129257 + *
129258 + *
129259 + * ALTERNATIVELY, this software may be distributed under the terms of the
129260 + * GNU General Public License ("GPL") as published by the Free Software
129261 + * Foundation, either version 2 of that License or (at your option) any
129262 + * later version.
129263 + *
129264 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129265 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129266 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129267 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129268 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129269 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129270 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129271 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129272 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129273 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129274 + */
129275 +
129276 +#include "bman_test.h"
129277 +
129278 +MODULE_AUTHOR("Geoff Thorpe");
129279 +MODULE_LICENSE("Dual BSD/GPL");
129280 +MODULE_DESCRIPTION("Bman testing");
129281 +
129282 +static int test_init(void)
129283 +{
129284 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
129285 + int loop = 1;
129286 + while (loop--)
129287 + bman_test_high();
129288 +#endif
129289 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
129290 + bman_test_thresh();
129291 +#endif
129292 + return 0;
129293 +}
129294 +
129295 +static void test_exit(void)
129296 +{
129297 +}
129298 +
129299 +module_init(test_init);
129300 +module_exit(test_exit);
129301 --- /dev/null
129302 +++ b/drivers/staging/fsl_qbman/bman_test.h
129303 @@ -0,0 +1,44 @@
129304 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
129305 + *
129306 + * Redistribution and use in source and binary forms, with or without
129307 + * modification, are permitted provided that the following conditions are met:
129308 + * * Redistributions of source code must retain the above copyright
129309 + * notice, this list of conditions and the following disclaimer.
129310 + * * Redistributions in binary form must reproduce the above copyright
129311 + * notice, this list of conditions and the following disclaimer in the
129312 + * documentation and/or other materials provided with the distribution.
129313 + * * Neither the name of Freescale Semiconductor nor the
129314 + * names of its contributors may be used to endorse or promote products
129315 + * derived from this software without specific prior written permission.
129316 + *
129317 + *
129318 + * ALTERNATIVELY, this software may be distributed under the terms of the
129319 + * GNU General Public License ("GPL") as published by the Free Software
129320 + * Foundation, either version 2 of that License or (at your option) any
129321 + * later version.
129322 + *
129323 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129324 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129325 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129326 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129327 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129328 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129329 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129330 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129331 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129332 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129333 + */
129334 +
129335 +#include <linux/kernel.h>
129336 +#include <linux/errno.h>
129337 +#include <linux/io.h>
129338 +#include <linux/slab.h>
129339 +#include <linux/module.h>
129340 +#include <linux/interrupt.h>
129341 +#include <linux/delay.h>
129342 +#include <linux/kthread.h>
129343 +
129344 +#include <linux/fsl_bman.h>
129345 +
129346 +void bman_test_high(void);
129347 +void bman_test_thresh(void);
129348 --- /dev/null
129349 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
129350 @@ -0,0 +1,183 @@
129351 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
129352 + *
129353 + * Redistribution and use in source and binary forms, with or without
129354 + * modification, are permitted provided that the following conditions are met:
129355 + * * Redistributions of source code must retain the above copyright
129356 + * notice, this list of conditions and the following disclaimer.
129357 + * * Redistributions in binary form must reproduce the above copyright
129358 + * notice, this list of conditions and the following disclaimer in the
129359 + * documentation and/or other materials provided with the distribution.
129360 + * * Neither the name of Freescale Semiconductor nor the
129361 + * names of its contributors may be used to endorse or promote products
129362 + * derived from this software without specific prior written permission.
129363 + *
129364 + *
129365 + * ALTERNATIVELY, this software may be distributed under the terms of the
129366 + * GNU General Public License ("GPL") as published by the Free Software
129367 + * Foundation, either version 2 of that License or (at your option) any
129368 + * later version.
129369 + *
129370 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129371 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129372 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129373 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129374 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129375 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129376 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129377 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129378 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129379 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129380 + */
129381 +
129382 +#include "bman_test.h"
129383 +#include "bman_private.h"
129384 +
129385 +/*************/
129386 +/* constants */
129387 +/*************/
129388 +
129389 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
129390 +#define POOL_OPAQUE ((void *)0xdeadabba)
129391 +#define NUM_BUFS 93
129392 +#define LOOPS 3
129393 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
129394 +
129395 +/***************/
129396 +/* global vars */
129397 +/***************/
129398 +
129399 +static struct bman_pool *pool;
129400 +static int depleted;
129401 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
129402 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
129403 +static int bufs_received;
129404 +
129405 +/* Predeclare the callback so we can instantiate pool parameters */
129406 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
129407 +
129408 +/**********************/
129409 +/* internal functions */
129410 +/**********************/
129411 +
129412 +static void bufs_init(void)
129413 +{
129414 + int i;
129415 + for (i = 0; i < NUM_BUFS; i++)
129416 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
129417 + bufs_received = 0;
129418 +}
129419 +
129420 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
129421 +{
129422 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
129423 +
129424 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
129425 + * LS-bits of buffer addresses, masking off the upper 8-bits on
129426 + * release commands. The API provides for 48-bit addresses
129427 + * because some SoCs support all 48-bits. When generating
129428 + * garbage addresses for testing, we either need to zero the
129429 + * upper 8-bits when releasing to Bman (otherwise we'll be
129430 + * disappointed when the buffers we acquire back from Bman
129431 + * don't match), or we need to mask the upper 8-bits off when
129432 + * comparing. We do the latter.
129433 + */
129434 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
129435 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
129436 + return -1;
129437 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
129438 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
129439 + return 1;
129440 + } else {
129441 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
129442 + return -1;
129443 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
129444 + return 1;
129445 + }
129446 +
129447 + return 0;
129448 +}
129449 +
129450 +static void bufs_confirm(void)
129451 +{
129452 + int i, j;
129453 + for (i = 0; i < NUM_BUFS; i++) {
129454 + int matches = 0;
129455 + for (j = 0; j < NUM_BUFS; j++)
129456 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
129457 + matches++;
129458 + BUG_ON(matches != 1);
129459 + }
129460 +}
129461 +
129462 +/********/
129463 +/* test */
129464 +/********/
129465 +
129466 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
129467 + void *pool_ctx, int __depleted)
129468 +{
129469 + BUG_ON(__pool != pool);
129470 + BUG_ON(pool_ctx != POOL_OPAQUE);
129471 + depleted = __depleted;
129472 +}
129473 +
129474 +void bman_test_high(void)
129475 +{
129476 + struct bman_pool_params pparams = {
129477 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
129478 + .cb = depletion_cb,
129479 + .cb_ctx = POOL_OPAQUE,
129480 + };
129481 + int i, loops = LOOPS;
129482 + struct bm_buffer tmp_buf;
129483 +
129484 + bufs_init();
129485 +
129486 + pr_info("BMAN: --- starting high-level test ---\n");
129487 +
129488 + pool = bman_new_pool(&pparams);
129489 + BUG_ON(!pool);
129490 +
129491 + /*******************/
129492 + /* Release buffers */
129493 + /*******************/
129494 +do_loop:
129495 + i = 0;
129496 + while (i < NUM_BUFS) {
129497 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
129498 + int num = 8;
129499 + if ((i + num) > NUM_BUFS)
129500 + num = NUM_BUFS - i;
129501 + if ((i + num) == NUM_BUFS)
129502 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
129503 + if (bman_release(pool, bufs_in + i, num, flags))
129504 + panic("bman_release() failed\n");
129505 + i += num;
129506 + }
129507 +
129508 + /*******************/
129509 + /* Acquire buffers */
129510 + /*******************/
129511 + while (i > 0) {
129512 + int tmp, num = 8;
129513 + if (num > i)
129514 + num = i;
129515 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
129516 + BUG_ON(tmp != num);
129517 + i -= num;
129518 + }
129519 +
129520 + i = bman_acquire(pool, &tmp_buf, 1, 0);
129521 + BUG_ON(i > 0);
129522 +
129523 + bufs_confirm();
129524 +
129525 + if (--loops)
129526 + goto do_loop;
129527 +
129528 + /************/
129529 + /* Clean up */
129530 + /************/
129531 + bman_free_pool(pool);
129532 + pr_info("BMAN: --- finished high-level test ---\n");
129533 +}
129534 --- /dev/null
129535 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
129536 @@ -0,0 +1,196 @@
129537 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
129538 + *
129539 + * Redistribution and use in source and binary forms, with or without
129540 + * modification, are permitted provided that the following conditions are met:
129541 + * * Redistributions of source code must retain the above copyright
129542 + * notice, this list of conditions and the following disclaimer.
129543 + * * Redistributions in binary form must reproduce the above copyright
129544 + * notice, this list of conditions and the following disclaimer in the
129545 + * documentation and/or other materials provided with the distribution.
129546 + * * Neither the name of Freescale Semiconductor nor the
129547 + * names of its contributors may be used to endorse or promote products
129548 + * derived from this software without specific prior written permission.
129549 + *
129550 + *
129551 + * ALTERNATIVELY, this software may be distributed under the terms of the
129552 + * GNU General Public License ("GPL") as published by the Free Software
129553 + * Foundation, either version 2 of that License or (at your option) any
129554 + * later version.
129555 + *
129556 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129557 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129558 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129559 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129560 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129561 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129562 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129563 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129564 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129565 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129566 + */
129567 +
129568 +#include "bman_test.h"
129569 +
129570 +/* Test constants */
129571 +#define TEST_NUMBUFS 129728
129572 +#define TEST_EXIT 129536
129573 +#define TEST_ENTRY 129024
129574 +
129575 +struct affine_test_data {
129576 + struct task_struct *t;
129577 + int cpu;
129578 + int expect_affinity;
129579 + int drain;
129580 + int num_enter;
129581 + int num_exit;
129582 + struct list_head node;
129583 + struct completion wakethread;
129584 + struct completion wakeparent;
129585 +};
129586 +
129587 +static void cb_depletion(struct bman_portal *portal,
129588 + struct bman_pool *pool,
129589 + void *opaque,
129590 + int depleted)
129591 +{
129592 + struct affine_test_data *data = opaque;
129593 + int c = smp_processor_id();
129594 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
129595 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
129596 + /* We should be executing on the CPU of the thread that owns the pool if
129597 + * and that CPU has an affine portal (ie. it isn't slaved). */
129598 + BUG_ON((c != data->cpu) && data->expect_affinity);
129599 + BUG_ON((c == data->cpu) && !data->expect_affinity);
129600 + if (depleted)
129601 + data->num_enter++;
129602 + else
129603 + data->num_exit++;
129604 +}
129605 +
129606 +/* Params used to set up a pool, this also dynamically allocates a BPID */
129607 +static const struct bman_pool_params params_nocb = {
129608 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
129609 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
129610 +};
129611 +
129612 +/* Params used to set up each cpu's pool with callbacks enabled */
129613 +static struct bman_pool_params params_cb = {
129614 + .bpid = 0, /* will be replaced to match pool_nocb */
129615 + .flags = BMAN_POOL_FLAG_DEPLETION,
129616 + .cb = cb_depletion
129617 +};
129618 +
129619 +static struct bman_pool *pool_nocb;
129620 +static LIST_HEAD(threads);
129621 +
129622 +static int affine_test(void *__data)
129623 +{
129624 + struct bman_pool *pool;
129625 + struct affine_test_data *data = __data;
129626 + struct bman_pool_params my_params = params_cb;
129627 +
129628 + pr_info("thread %d: starting\n", data->cpu);
129629 + /* create the pool */
129630 + my_params.cb_ctx = data;
129631 + pool = bman_new_pool(&my_params);
129632 + BUG_ON(!pool);
129633 + complete(&data->wakeparent);
129634 + wait_for_completion(&data->wakethread);
129635 + init_completion(&data->wakethread);
129636 +
129637 + /* if we're the drainer, we get signalled for that */
129638 + if (data->drain) {
129639 + struct bm_buffer buf;
129640 + int ret;
129641 + pr_info("thread %d: draining...\n", data->cpu);
129642 + do {
129643 + ret = bman_acquire(pool, &buf, 1, 0);
129644 + } while (ret > 0);
129645 + pr_info("thread %d: draining done.\n", data->cpu);
129646 + complete(&data->wakeparent);
129647 + wait_for_completion(&data->wakethread);
129648 + init_completion(&data->wakethread);
129649 + }
129650 +
129651 + /* cleanup */
129652 + bman_free_pool(pool);
129653 + while (!kthread_should_stop())
129654 + cpu_relax();
129655 + pr_info("thread %d: exiting\n", data->cpu);
129656 + return 0;
129657 +}
129658 +
129659 +static struct affine_test_data *start_affine_test(int cpu, int drain)
129660 +{
129661 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
129662 +
129663 + if (!data)
129664 + return NULL;
129665 + data->cpu = cpu;
129666 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
129667 + data->drain = drain;
129668 + data->num_enter = 0;
129669 + data->num_exit = 0;
129670 + init_completion(&data->wakethread);
129671 + init_completion(&data->wakeparent);
129672 + list_add_tail(&data->node, &threads);
129673 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
129674 + BUG_ON(IS_ERR(data->t));
129675 + kthread_bind(data->t, cpu);
129676 + wake_up_process(data->t);
129677 + return data;
129678 +}
129679 +
129680 +void bman_test_thresh(void)
129681 +{
129682 + int loop = TEST_NUMBUFS;
129683 + int ret, num_cpus = 0;
129684 + struct affine_test_data *data, *drainer = NULL;
129685 +
129686 + pr_info("bman_test_thresh: start\n");
129687 +
129688 + /* allocate a BPID and seed it */
129689 + pool_nocb = bman_new_pool(&params_nocb);
129690 + BUG_ON(!pool_nocb);
129691 + while (loop--) {
129692 + struct bm_buffer buf;
129693 + bm_buffer_set64(&buf, 0x0badbeef + loop);
129694 + ret = bman_release(pool_nocb, &buf, 1,
129695 + BMAN_RELEASE_FLAG_WAIT);
129696 + BUG_ON(ret);
129697 + }
129698 + while (!bman_rcr_is_empty())
129699 + cpu_relax();
129700 + pr_info("bman_test_thresh: buffers are in\n");
129701 +
129702 + /* create threads and wait for them to create pools */
129703 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
129704 + for_each_cpu(loop, cpu_online_mask) {
129705 + data = start_affine_test(loop, drainer ? 0 : 1);
129706 + BUG_ON(!data);
129707 + if (!drainer)
129708 + drainer = data;
129709 + num_cpus++;
129710 + wait_for_completion(&data->wakeparent);
129711 + }
129712 +
129713 + /* signal the drainer to start draining */
129714 + complete(&drainer->wakethread);
129715 + wait_for_completion(&drainer->wakeparent);
129716 + init_completion(&drainer->wakeparent);
129717 +
129718 + /* tear down */
129719 + list_for_each_entry_safe(data, drainer, &threads, node) {
129720 + complete(&data->wakethread);
129721 + ret = kthread_stop(data->t);
129722 + BUG_ON(ret);
129723 + list_del(&data->node);
129724 + /* check that we get the expected callbacks (and no others) */
129725 + BUG_ON(data->num_enter != 1);
129726 + BUG_ON(data->num_exit != 0);
129727 + kfree(data);
129728 + }
129729 + bman_free_pool(pool_nocb);
129730 +
129731 + pr_info("bman_test_thresh: done\n");
129732 +}
129733 --- /dev/null
129734 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
129735 @@ -0,0 +1,706 @@
129736 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
129737 + *
129738 + * Redistribution and use in source and binary forms, with or without
129739 + * modification, are permitted provided that the following conditions are met:
129740 + * * Redistributions of source code must retain the above copyright
129741 + * notice, this list of conditions and the following disclaimer.
129742 + * * Redistributions in binary form must reproduce the above copyright
129743 + * notice, this list of conditions and the following disclaimer in the
129744 + * documentation and/or other materials provided with the distribution.
129745 + * * Neither the name of Freescale Semiconductor nor the
129746 + * names of its contributors may be used to endorse or promote products
129747 + * derived from this software without specific prior written permission.
129748 + *
129749 + *
129750 + * ALTERNATIVELY, this software may be distributed under the terms of the
129751 + * GNU General Public License ("GPL") as published by the Free Software
129752 + * Foundation, either version 2 of that License or (at your option) any
129753 + * later version.
129754 + *
129755 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129756 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129757 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129758 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129759 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129760 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129761 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129762 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129763 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129764 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129765 + */
129766 +
129767 +#include "dpa_sys.h"
129768 +#include <linux/fsl_qman.h>
129769 +#include <linux/fsl_bman.h>
129770 +
129771 +/* Qman and Bman APIs are front-ends to the common code; */
129772 +
129773 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
129774 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
129775 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
129776 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
129777 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
129778 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
129779 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
129780 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
129781 +
129782 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
129783 + * FQIDs (probably from user-space), it can filter out those that aren't in the
129784 + * OOS state (better to leak a h/w resource than to crash). This function
129785 + * returns the number of invalid IDs that were not released. */
129786 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
129787 + int (*is_valid)(u32 id))
129788 +{
129789 + int valid_mode = 0;
129790 + u32 loop = id, total_invalid = 0;
129791 + while (loop < (id + count)) {
129792 + int isvalid = is_valid ? is_valid(loop) : 1;
129793 + if (!valid_mode) {
129794 + /* We're looking for a valid ID to terminate an invalid
129795 + * range */
129796 + if (isvalid) {
129797 + /* We finished a range of invalid IDs, a valid
129798 + * range is now underway */
129799 + valid_mode = 1;
129800 + count -= (loop - id);
129801 + id = loop;
129802 + } else
129803 + total_invalid++;
129804 + } else {
129805 + /* We're looking for an invalid ID to terminate a
129806 + * valid range */
129807 + if (!isvalid) {
129808 + /* Release the range of valid IDs, an unvalid
129809 + * range is now underway */
129810 + if (loop > id)
129811 + dpa_alloc_free(alloc, id, loop - id);
129812 + valid_mode = 0;
129813 + }
129814 + }
129815 + loop++;
129816 + }
129817 + /* Release any unterminated range of valid IDs */
129818 + if (valid_mode && count)
129819 + dpa_alloc_free(alloc, id, count);
129820 + return total_invalid;
129821 +}
129822 +
129823 +/* BPID allocator front-end */
129824 +
129825 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
129826 +{
129827 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
129828 +}
129829 +EXPORT_SYMBOL(bman_alloc_bpid_range);
129830 +
129831 +static int bp_cleanup(u32 bpid)
129832 +{
129833 + return bman_shutdown_pool(bpid) == 0;
129834 +}
129835 +void bman_release_bpid_range(u32 bpid, u32 count)
129836 +{
129837 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
129838 + if (total_invalid)
129839 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
129840 + bpid, bpid + count - 1, count, total_invalid);
129841 +}
129842 +EXPORT_SYMBOL(bman_release_bpid_range);
129843 +
129844 +void bman_seed_bpid_range(u32 bpid, u32 count)
129845 +{
129846 + dpa_alloc_seed(&bpalloc, bpid, count);
129847 +}
129848 +EXPORT_SYMBOL(bman_seed_bpid_range);
129849 +
129850 +int bman_reserve_bpid_range(u32 bpid, u32 count)
129851 +{
129852 + return dpa_alloc_reserve(&bpalloc, bpid, count);
129853 +}
129854 +EXPORT_SYMBOL(bman_reserve_bpid_range);
129855 +
129856 +
129857 +/* FQID allocator front-end */
129858 +
129859 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
129860 +{
129861 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
129862 +}
129863 +EXPORT_SYMBOL(qman_alloc_fqid_range);
129864 +
129865 +static int fq_cleanup(u32 fqid)
129866 +{
129867 + return qman_shutdown_fq(fqid) == 0;
129868 +}
129869 +void qman_release_fqid_range(u32 fqid, u32 count)
129870 +{
129871 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
129872 + if (total_invalid)
129873 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
129874 + fqid, fqid + count - 1, count, total_invalid);
129875 +}
129876 +EXPORT_SYMBOL(qman_release_fqid_range);
129877 +
129878 +int qman_reserve_fqid_range(u32 fqid, u32 count)
129879 +{
129880 + return dpa_alloc_reserve(&fqalloc, fqid, count);
129881 +}
129882 +EXPORT_SYMBOL(qman_reserve_fqid_range);
129883 +
129884 +void qman_seed_fqid_range(u32 fqid, u32 count)
129885 +{
129886 + dpa_alloc_seed(&fqalloc, fqid, count);
129887 +}
129888 +EXPORT_SYMBOL(qman_seed_fqid_range);
129889 +
129890 +/* Pool-channel allocator front-end */
129891 +
129892 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
129893 +{
129894 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
129895 +}
129896 +EXPORT_SYMBOL(qman_alloc_pool_range);
129897 +
129898 +static int qpool_cleanup(u32 qp)
129899 +{
129900 + /* We query all FQDs starting from
129901 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
129902 + * whose destination channel is the pool-channel being released.
129903 + * When a non-OOS FQD is found we attempt to clean it up */
129904 + struct qman_fq fq = {
129905 + .fqid = 1
129906 + };
129907 + int err;
129908 + do {
129909 + struct qm_mcr_queryfq_np np;
129910 + err = qman_query_fq_np(&fq, &np);
129911 + if (err)
129912 + /* FQID range exceeded, found no problems */
129913 + return 1;
129914 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
129915 + struct qm_fqd fqd;
129916 + err = qman_query_fq(&fq, &fqd);
129917 + BUG_ON(err);
129918 + if (fqd.dest.channel == qp) {
129919 + /* The channel is the FQ's target, clean it */
129920 + if (qman_shutdown_fq(fq.fqid) != 0)
129921 + /* Couldn't shut down the FQ
129922 + so the pool must be leaked */
129923 + return 0;
129924 + }
129925 + }
129926 + /* Move to the next FQID */
129927 + fq.fqid++;
129928 + } while (1);
129929 +}
129930 +void qman_release_pool_range(u32 qp, u32 count)
129931 +{
129932 + u32 total_invalid = release_id_range(&qpalloc, qp,
129933 + count, qpool_cleanup);
129934 + if (total_invalid) {
129935 + /* Pool channels are almost always used individually */
129936 + if (count == 1)
129937 + pr_err("Pool channel 0x%x had %d leaks\n",
129938 + qp, total_invalid);
129939 + else
129940 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
129941 + qp, qp + count - 1, count, total_invalid);
129942 + }
129943 +}
129944 +EXPORT_SYMBOL(qman_release_pool_range);
129945 +
129946 +
129947 +void qman_seed_pool_range(u32 poolid, u32 count)
129948 +{
129949 + dpa_alloc_seed(&qpalloc, poolid, count);
129950 +
129951 +}
129952 +EXPORT_SYMBOL(qman_seed_pool_range);
129953 +
129954 +int qman_reserve_pool_range(u32 poolid, u32 count)
129955 +{
129956 + return dpa_alloc_reserve(&qpalloc, poolid, count);
129957 +}
129958 +EXPORT_SYMBOL(qman_reserve_pool_range);
129959 +
129960 +
129961 +/* CGR ID allocator front-end */
129962 +
129963 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
129964 +{
129965 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
129966 +}
129967 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
129968 +
129969 +static int cqr_cleanup(u32 cgrid)
129970 +{
129971 + /* We query all FQDs starting from
129972 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
129973 + * whose CGR is the CGR being released.
129974 + */
129975 + struct qman_fq fq = {
129976 + .fqid = 1
129977 + };
129978 + int err;
129979 + do {
129980 + struct qm_mcr_queryfq_np np;
129981 + err = qman_query_fq_np(&fq, &np);
129982 + if (err)
129983 + /* FQID range exceeded, found no problems */
129984 + return 1;
129985 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
129986 + struct qm_fqd fqd;
129987 + err = qman_query_fq(&fq, &fqd);
129988 + BUG_ON(err);
129989 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
129990 + (fqd.cgid == cgrid)) {
129991 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
129992 + " CGR will be leaked\n",
129993 + cgrid, fq.fqid);
129994 + return 1;
129995 + }
129996 + }
129997 + /* Move to the next FQID */
129998 + fq.fqid++;
129999 + } while (1);
130000 +}
130001 +
130002 +void qman_release_cgrid_range(u32 cgrid, u32 count)
130003 +{
130004 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
130005 + count, cqr_cleanup);
130006 + if (total_invalid)
130007 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
130008 + cgrid, cgrid + count - 1, count, total_invalid);
130009 +}
130010 +EXPORT_SYMBOL(qman_release_cgrid_range);
130011 +
130012 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
130013 +{
130014 + dpa_alloc_seed(&cgralloc, cgrid, count);
130015 +
130016 +}
130017 +EXPORT_SYMBOL(qman_seed_cgrid_range);
130018 +
130019 +/* CEETM CHANNEL ID allocator front-end */
130020 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
130021 + int partial)
130022 +{
130023 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
130024 +}
130025 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
130026 +
130027 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
130028 + int partial)
130029 +{
130030 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
130031 +}
130032 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
130033 +
130034 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
130035 +{
130036 + u32 total_invalid;
130037 +
130038 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
130039 + NULL);
130040 + if (total_invalid)
130041 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
130042 + channelid, channelid + count - 1, count, total_invalid);
130043 +}
130044 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
130045 +
130046 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
130047 +{
130048 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
130049 +
130050 +}
130051 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
130052 +
130053 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
130054 +{
130055 + u32 total_invalid;
130056 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
130057 + NULL);
130058 + if (total_invalid)
130059 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
130060 + channelid, channelid + count - 1, count, total_invalid);
130061 +}
130062 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
130063 +
130064 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
130065 +{
130066 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
130067 +
130068 +}
130069 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
130070 +
130071 +/* CEETM LFQID allocator front-end */
130072 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
130073 + int partial)
130074 +{
130075 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
130076 +}
130077 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
130078 +
130079 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
130080 + int partial)
130081 +{
130082 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
130083 +}
130084 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
130085 +
130086 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
130087 +{
130088 + u32 total_invalid;
130089 +
130090 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
130091 + NULL);
130092 + if (total_invalid)
130093 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
130094 + lfqid, lfqid + count - 1, count, total_invalid);
130095 +}
130096 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
130097 +
130098 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
130099 +{
130100 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
130101 +
130102 +}
130103 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
130104 +
130105 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
130106 +{
130107 + u32 total_invalid;
130108 +
130109 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
130110 + NULL);
130111 + if (total_invalid)
130112 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
130113 + lfqid, lfqid + count - 1, count, total_invalid);
130114 +}
130115 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
130116 +
130117 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
130118 +{
130119 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
130120 +
130121 +}
130122 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
130123 +
130124 +
130125 +/* Everything else is the common backend to all the allocators */
130126 +
130127 +/* The allocator is a (possibly-empty) list of these; */
130128 +struct alloc_node {
130129 + struct list_head list;
130130 + u32 base;
130131 + u32 num;
130132 + /* refcount and is_alloced are only set
130133 + when the node is in the used list */
130134 + unsigned int refcount;
130135 + int is_alloced;
130136 +};
130137 +
130138 +/* #define DPA_ALLOC_DEBUG */
130139 +
130140 +#ifdef DPA_ALLOC_DEBUG
130141 +#define DPRINT pr_info
130142 +static void DUMP(struct dpa_alloc *alloc)
130143 +{
130144 + int off = 0;
130145 + char buf[256];
130146 + struct alloc_node *p;
130147 + pr_info("Free Nodes\n");
130148 + list_for_each_entry(p, &alloc->free, list) {
130149 + if (off < 255)
130150 + off += snprintf(buf + off, 255-off, "{%d,%d}",
130151 + p->base, p->base + p->num - 1);
130152 + }
130153 + pr_info("%s\n", buf);
130154 +
130155 + off = 0;
130156 + pr_info("Used Nodes\n");
130157 + list_for_each_entry(p, &alloc->used, list) {
130158 + if (off < 255)
130159 + off += snprintf(buf + off, 255-off, "{%d,%d}",
130160 + p->base, p->base + p->num - 1);
130161 + }
130162 + pr_info("%s\n", buf);
130163 +
130164 +
130165 +
130166 +}
130167 +#else
130168 +#define DPRINT(x...)
130169 +#define DUMP(a)
130170 +#endif
130171 +
130172 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
130173 + int partial)
130174 +{
130175 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
130176 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
130177 + struct alloc_node *margin_left, *margin_right;
130178 +
130179 + *result = (u32)-1;
130180 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
130181 + DUMP(alloc);
130182 + /* If 'align' is 0, it should behave as though it was 1 */
130183 + if (!align)
130184 + align = 1;
130185 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
130186 + if (!margin_left)
130187 + goto err;
130188 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
130189 + if (!margin_right) {
130190 + kfree(margin_left);
130191 + goto err;
130192 + }
130193 + spin_lock_irq(&alloc->lock);
130194 + list_for_each_entry(i, &alloc->free, list) {
130195 + base = (i->base + align - 1) / align;
130196 + base *= align;
130197 + if ((base - i->base) >= i->num)
130198 + /* alignment is impossible, regardless of count */
130199 + continue;
130200 + num = i->num - (base - i->base);
130201 + if (num >= count) {
130202 + /* this one will do nicely */
130203 + num = count;
130204 + goto done;
130205 + }
130206 + if (num > next_best_num) {
130207 + next_best = i;
130208 + next_best_base = base;
130209 + next_best_num = num;
130210 + }
130211 + }
130212 + if (partial && next_best) {
130213 + i = next_best;
130214 + base = next_best_base;
130215 + num = next_best_num;
130216 + } else
130217 + i = NULL;
130218 +done:
130219 + if (i) {
130220 + if (base != i->base) {
130221 + margin_left->base = i->base;
130222 + margin_left->num = base - i->base;
130223 + list_add_tail(&margin_left->list, &i->list);
130224 + } else
130225 + kfree(margin_left);
130226 + if ((base + num) < (i->base + i->num)) {
130227 + margin_right->base = base + num;
130228 + margin_right->num = (i->base + i->num) -
130229 + (base + num);
130230 + list_add(&margin_right->list, &i->list);
130231 + } else
130232 + kfree(margin_right);
130233 + list_del(&i->list);
130234 + kfree(i);
130235 + *result = base;
130236 + } else {
130237 + spin_unlock_irq(&alloc->lock);
130238 + kfree(margin_left);
130239 + kfree(margin_right);
130240 + }
130241 +
130242 +err:
130243 + DPRINT("returning %d\n", i ? num : -ENOMEM);
130244 + DUMP(alloc);
130245 + if (!i)
130246 + return -ENOMEM;
130247 +
130248 + /* Add the allocation to the used list with a refcount of 1 */
130249 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
130250 + if (!used_node) {
130251 + spin_unlock_irq(&alloc->lock);
130252 + return -ENOMEM;
130253 + }
130254 + used_node->base = *result;
130255 + used_node->num = num;
130256 + used_node->refcount = 1;
130257 + used_node->is_alloced = 1;
130258 + list_add_tail(&used_node->list, &alloc->used);
130259 + spin_unlock_irq(&alloc->lock);
130260 + return (int)num;
130261 +}
130262 +
130263 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
130264 + * forcing error-handling on to users in the deallocation path. */
130265 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
130266 +{
130267 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
130268 + BUG_ON(!node);
130269 + DPRINT("release_range(%d,%d)\n", base_id, count);
130270 + DUMP(alloc);
130271 + BUG_ON(!count);
130272 + spin_lock_irq(&alloc->lock);
130273 +
130274 +
130275 + node->base = base_id;
130276 + node->num = count;
130277 + list_for_each_entry(i, &alloc->free, list) {
130278 + if (i->base >= node->base) {
130279 + /* BUG_ON(any overlapping) */
130280 + BUG_ON(i->base < (node->base + node->num));
130281 + list_add_tail(&node->list, &i->list);
130282 + goto done;
130283 + }
130284 + }
130285 + list_add_tail(&node->list, &alloc->free);
130286 +done:
130287 + /* Merge to the left */
130288 + i = list_entry(node->list.prev, struct alloc_node, list);
130289 + if (node->list.prev != &alloc->free) {
130290 + BUG_ON((i->base + i->num) > node->base);
130291 + if ((i->base + i->num) == node->base) {
130292 + node->base = i->base;
130293 + node->num += i->num;
130294 + list_del(&i->list);
130295 + kfree(i);
130296 + }
130297 + }
130298 + /* Merge to the right */
130299 + i = list_entry(node->list.next, struct alloc_node, list);
130300 + if (node->list.next != &alloc->free) {
130301 + BUG_ON((node->base + node->num) > i->base);
130302 + if ((node->base + node->num) == i->base) {
130303 + node->num += i->num;
130304 + list_del(&i->list);
130305 + kfree(i);
130306 + }
130307 + }
130308 + spin_unlock_irq(&alloc->lock);
130309 + DUMP(alloc);
130310 +}
130311 +
130312 +
130313 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
130314 +{
130315 + struct alloc_node *i = NULL;
130316 + spin_lock_irq(&alloc->lock);
130317 +
130318 + /* First find the node in the used list and decrement its ref count */
130319 + list_for_each_entry(i, &alloc->used, list) {
130320 + if (i->base == base_id && i->num == count) {
130321 + --i->refcount;
130322 + if (i->refcount == 0) {
130323 + list_del(&i->list);
130324 + spin_unlock_irq(&alloc->lock);
130325 + if (i->is_alloced)
130326 + _dpa_alloc_free(alloc, base_id, count);
130327 + kfree(i);
130328 + return;
130329 + }
130330 + spin_unlock_irq(&alloc->lock);
130331 + return;
130332 + }
130333 + }
130334 + /* Couldn't find the allocation */
130335 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
130336 + base_id, count);
130337 + spin_unlock_irq(&alloc->lock);
130338 +}
130339 +
130340 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
130341 +{
130342 + /* Same as free but no previous allocation checking is needed */
130343 + _dpa_alloc_free(alloc, base_id, count);
130344 +}
130345 +
130346 +
130347 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
130348 +{
130349 + struct alloc_node *i = NULL, *used_node;
130350 +
130351 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
130352 + DUMP(alloc);
130353 +
130354 + spin_lock_irq(&alloc->lock);
130355 +
130356 + /* Check for the node in the used list.
130357 + If found, increase it's refcount */
130358 + list_for_each_entry(i, &alloc->used, list) {
130359 + if ((i->base == base) && (i->num == num)) {
130360 + ++i->refcount;
130361 + spin_unlock_irq(&alloc->lock);
130362 + return 0;
130363 + }
130364 + if ((base >= i->base) && (base < (i->base + i->num))) {
130365 + /* This is an attempt to reserve a region that was
130366 + already reserved or alloced with a different
130367 + base or num */
130368 + pr_err("Cannot reserve %d - %d, it overlaps with"
130369 + " existing reservation from %d - %d\n",
130370 + base, base + num - 1, i->base,
130371 + i->base + i->num - 1);
130372 + spin_unlock_irq(&alloc->lock);
130373 + return -1;
130374 + }
130375 + }
130376 + /* Check to make sure this ID isn't in the free list */
130377 + list_for_each_entry(i, &alloc->free, list) {
130378 + if ((base >= i->base) && (base < (i->base + i->num))) {
130379 + /* yep, the reservation is within this node */
130380 + pr_err("Cannot reserve %d - %d, it overlaps with"
130381 + " free range %d - %d and must be alloced\n",
130382 + base, base + num - 1,
130383 + i->base, i->base + i->num - 1);
130384 + spin_unlock_irq(&alloc->lock);
130385 + return -1;
130386 + }
130387 + }
130388 + /* Add the allocation to the used list with a refcount of 1 */
130389 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
130390 + if (!used_node) {
130391 + spin_unlock_irq(&alloc->lock);
130392 + return -ENOMEM;
130393 +
130394 + }
130395 + used_node->base = base;
130396 + used_node->num = num;
130397 + used_node->refcount = 1;
130398 + used_node->is_alloced = 0;
130399 + list_add_tail(&used_node->list, &alloc->used);
130400 + spin_unlock_irq(&alloc->lock);
130401 + return 0;
130402 +}
130403 +
130404 +
130405 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
130406 +{
130407 + struct alloc_node *i = NULL;
130408 + DPRINT("alloc_pop()\n");
130409 + DUMP(alloc);
130410 + spin_lock_irq(&alloc->lock);
130411 + if (!list_empty(&alloc->free)) {
130412 + i = list_entry(alloc->free.next, struct alloc_node, list);
130413 + list_del(&i->list);
130414 + }
130415 + spin_unlock_irq(&alloc->lock);
130416 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
130417 + DUMP(alloc);
130418 + if (!i)
130419 + return -ENOMEM;
130420 + *result = i->base;
130421 + *count = i->num;
130422 + kfree(i);
130423 + return 0;
130424 +}
130425 +
130426 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
130427 +{
130428 + struct alloc_node *i = NULL;
130429 + int res = 0;
130430 + DPRINT("alloc_check()\n");
130431 + spin_lock_irq(&list_head->lock);
130432 +
130433 + list_for_each_entry(i, &list_head->free, list) {
130434 + if ((item >= i->base) && (item < (i->base + i->num))) {
130435 + res = 1;
130436 + break;
130437 + }
130438 + }
130439 + spin_unlock_irq(&list_head->lock);
130440 + return res;
130441 +}
130442 --- /dev/null
130443 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
130444 @@ -0,0 +1,259 @@
130445 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
130446 + *
130447 + * Redistribution and use in source and binary forms, with or without
130448 + * modification, are permitted provided that the following conditions are met:
130449 + * * Redistributions of source code must retain the above copyright
130450 + * notice, this list of conditions and the following disclaimer.
130451 + * * Redistributions in binary form must reproduce the above copyright
130452 + * notice, this list of conditions and the following disclaimer in the
130453 + * documentation and/or other materials provided with the distribution.
130454 + * * Neither the name of Freescale Semiconductor nor the
130455 + * names of its contributors may be used to endorse or promote products
130456 + * derived from this software without specific prior written permission.
130457 + *
130458 + *
130459 + * ALTERNATIVELY, this software may be distributed under the terms of the
130460 + * GNU General Public License ("GPL") as published by the Free Software
130461 + * Foundation, either version 2 of that License or (at your option) any
130462 + * later version.
130463 + *
130464 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130465 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130466 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130467 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130468 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130469 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130470 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130471 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130472 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130473 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130474 + */
130475 +
130476 +#ifndef DPA_SYS_H
130477 +#define DPA_SYS_H
130478 +
130479 +#include <linux/kernel.h>
130480 +#include <linux/errno.h>
130481 +#include <linux/io.h>
130482 +#include <linux/dma-mapping.h>
130483 +#include <linux/bootmem.h>
130484 +#include <linux/slab.h>
130485 +#include <linux/module.h>
130486 +#include <linux/init.h>
130487 +#include <linux/interrupt.h>
130488 +#include <linux/delay.h>
130489 +#include <linux/of_platform.h>
130490 +#include <linux/of_address.h>
130491 +#include <linux/of_irq.h>
130492 +#include <linux/kthread.h>
130493 +#include <linux/memblock.h>
130494 +#include <linux/completion.h>
130495 +#include <linux/log2.h>
130496 +#include <linux/types.h>
130497 +#include <linux/ioctl.h>
130498 +#include <linux/miscdevice.h>
130499 +#include <linux/uaccess.h>
130500 +#include <linux/debugfs.h>
130501 +#include <linux/seq_file.h>
130502 +#include <linux/device.h>
130503 +#include <linux/uio_driver.h>
130504 +#include <linux/smp.h>
130505 +#include <linux/fsl_hypervisor.h>
130506 +#include <linux/vmalloc.h>
130507 +#include <linux/ctype.h>
130508 +#include <linux/math64.h>
130509 +#include <linux/bitops.h>
130510 +
130511 +#include <linux/fsl_usdpaa.h>
130512 +
130513 +/* When copying aligned words or shorts, try to avoid memcpy() */
130514 +#define CONFIG_TRY_BETTER_MEMCPY
130515 +
130516 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
130517 +#define DPA_PORTAL_CE 0
130518 +#define DPA_PORTAL_CI 1
130519 +
130520 +/***********************/
130521 +/* Misc inline assists */
130522 +/***********************/
130523 +
130524 +#if defined CONFIG_PPC32
130525 +#include "dpa_sys_ppc32.h"
130526 +#elif defined CONFIG_PPC64
130527 +#include "dpa_sys_ppc64.h"
130528 +#elif defined CONFIG_ARM
130529 +#include "dpa_sys_arm.h"
130530 +#elif defined CONFIG_ARM64
130531 +#include "dpa_sys_arm64.h"
130532 +#endif
130533 +
130534 +
130535 +#ifdef CONFIG_FSL_DPA_CHECKING
130536 +#define DPA_ASSERT(x) \
130537 + do { \
130538 + if (!(x)) { \
130539 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
130540 + __stringify_1(x)); \
130541 + dump_stack(); \
130542 + panic("assertion failure"); \
130543 + } \
130544 + } while (0)
130545 +#else
130546 +#define DPA_ASSERT(x)
130547 +#endif
130548 +
130549 +/* memcpy() stuff - when you know alignments in advance */
130550 +#ifdef CONFIG_TRY_BETTER_MEMCPY
130551 +static inline void copy_words(void *dest, const void *src, size_t sz)
130552 +{
130553 + u32 *__dest = dest;
130554 + const u32 *__src = src;
130555 + size_t __sz = sz >> 2;
130556 + BUG_ON((unsigned long)dest & 0x3);
130557 + BUG_ON((unsigned long)src & 0x3);
130558 + BUG_ON(sz & 0x3);
130559 + while (__sz--)
130560 + *(__dest++) = *(__src++);
130561 +}
130562 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
130563 +{
130564 + u16 *__dest = dest;
130565 + const u16 *__src = src;
130566 + size_t __sz = sz >> 1;
130567 + BUG_ON((unsigned long)dest & 0x1);
130568 + BUG_ON((unsigned long)src & 0x1);
130569 + BUG_ON(sz & 0x1);
130570 + while (__sz--)
130571 + *(__dest++) = *(__src++);
130572 +}
130573 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
130574 +{
130575 + u8 *__dest = dest;
130576 + const u8 *__src = src;
130577 + while (sz--)
130578 + *(__dest++) = *(__src++);
130579 +}
130580 +#else
130581 +#define copy_words memcpy
130582 +#define copy_shorts memcpy
130583 +#define copy_bytes memcpy
130584 +#endif
130585 +
130586 +/************/
130587 +/* RB-trees */
130588 +/************/
130589 +
130590 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
130591 + * non-linux systems. This also encapsulates the extra plumbing that linux code
130592 + * usually provides when using RB-trees. This encapsulation assumes that the
130593 + * data type held by the tree is u32. */
130594 +
130595 +struct dpa_rbtree {
130596 + struct rb_root root;
130597 +};
130598 +#define DPA_RBTREE { .root = RB_ROOT }
130599 +
130600 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
130601 +{
130602 + tree->root = RB_ROOT;
130603 +}
130604 +
130605 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
130606 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
130607 +{ \
130608 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
130609 + while (*p) { \
130610 + u32 item; \
130611 + parent = *p; \
130612 + item = rb_entry(parent, type, node_field)->val_field; \
130613 + if (obj->val_field < item) \
130614 + p = &parent->rb_left; \
130615 + else if (obj->val_field > item) \
130616 + p = &parent->rb_right; \
130617 + else \
130618 + return -EBUSY; \
130619 + } \
130620 + rb_link_node(&obj->node_field, parent, p); \
130621 + rb_insert_color(&obj->node_field, &tree->root); \
130622 + return 0; \
130623 +} \
130624 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
130625 +{ \
130626 + rb_erase(&obj->node_field, &tree->root); \
130627 +} \
130628 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
130629 +{ \
130630 + type *ret; \
130631 + struct rb_node *p = tree->root.rb_node; \
130632 + while (p) { \
130633 + ret = rb_entry(p, type, node_field); \
130634 + if (val < ret->val_field) \
130635 + p = p->rb_left; \
130636 + else if (val > ret->val_field) \
130637 + p = p->rb_right; \
130638 + else \
130639 + return ret; \
130640 + } \
130641 + return NULL; \
130642 +}
130643 +
130644 +/************/
130645 +/* Bootargs */
130646 +/************/
130647 +
130648 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
130649 + * though; a comma-separated list of items, each item being a cpu index and/or a
130650 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
130651 + * that the portal associated with that cpu should be shared. See bman_driver.c
130652 + * for more specifics. */
130653 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
130654 +{
130655 + *cpu = 0;
130656 + if (!isdigit(**s))
130657 + return -EINVAL;
130658 + while (isdigit(**s))
130659 + *cpu = *cpu * 10 + (*((*s)++) - '0');
130660 + return 0;
130661 +}
130662 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
130663 + struct cpumask *want_unshared,
130664 + const char *argname)
130665 +{
130666 + const char *s = str;
130667 + unsigned int shared, cpu1, cpu2, loop;
130668 +
130669 +keep_going:
130670 + if (*s == 's') {
130671 + shared = 1;
130672 + s++;
130673 + } else
130674 + shared = 0;
130675 + if (__parse_portals_cpu(&s, &cpu1))
130676 + goto err;
130677 + if (*s == '-') {
130678 + s++;
130679 + if (__parse_portals_cpu(&s, &cpu2))
130680 + goto err;
130681 + if (cpu2 < cpu1)
130682 + goto err;
130683 + } else
130684 + cpu2 = cpu1;
130685 + for (loop = cpu1; loop <= cpu2; loop++)
130686 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
130687 + if (*s == ',') {
130688 + s++;
130689 + goto keep_going;
130690 + } else if ((*s == '\0') || isspace(*s))
130691 + return 0;
130692 +err:
130693 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
130694 + (unsigned long)s - (unsigned long)str);
130695 + return -EINVAL;
130696 +}
130697 +#ifdef CONFIG_FSL_USDPAA
130698 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
130699 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
130700 + enum usdpaa_portal_type ptype, unsigned int *irq,
130701 + void **iir_reg);
130702 +#endif
130703 +#endif /* DPA_SYS_H */
130704 --- /dev/null
130705 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
130706 @@ -0,0 +1,95 @@
130707 +/* Copyright 2016 Freescale Semiconductor, Inc.
130708 + *
130709 + * Redistribution and use in source and binary forms, with or without
130710 + * modification, are permitted provided that the following conditions are met:
130711 + * * Redistributions of source code must retain the above copyright
130712 + * notice, this list of conditions and the following disclaimer.
130713 + * * Redistributions in binary form must reproduce the above copyright
130714 + * notice, this list of conditions and the following disclaimer in the
130715 + * documentation and/or other materials provided with the distribution.
130716 + * * Neither the name of Freescale Semiconductor nor the
130717 + * names of its contributors may be used to endorse or promote products
130718 + * derived from this software without specific prior written permission.
130719 + *
130720 + *
130721 + * ALTERNATIVELY, this software may be distributed under the terms of the
130722 + * GNU General Public License ("GPL") as published by the Free Software
130723 + * Foundation, either version 2 of that License or (at your option) any
130724 + * later version.
130725 + *
130726 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130727 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130728 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130729 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130730 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130731 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130732 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130733 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130734 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130735 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130736 + */
130737 +
130738 +#ifndef DPA_SYS_ARM_H
130739 +#define DPA_SYS_ARM_H
130740 +
130741 +#include <asm/cacheflush.h>
130742 +#include <asm/barrier.h>
130743 +
130744 +/* Implementation of ARM specific routines */
130745 +
130746 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
130747 + * barriers and that dcb*() won't fall victim to compiler or execution
130748 + * reordering with respect to other code/instructions that manipulate the same
130749 + * cacheline. */
130750 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
130751 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
130752 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
130753 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
130754 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
130755 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
130756 +
130757 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
130758 +
130759 +#define dcbf_64(p) \
130760 + do { \
130761 + dcbf((u32)p); \
130762 + } while (0)
130763 +/* Commonly used combo */
130764 +#define dcbit_ro(p) \
130765 + do { \
130766 + dcbi((u32)p); \
130767 + dcbt_ro((u32)p); \
130768 + } while (0)
130769 +
130770 +static inline u64 mfatb(void)
130771 +{
130772 + return get_cycles();
130773 +}
130774 +
130775 +static inline u32 in_be32(volatile void *addr)
130776 +{
130777 + return be32_to_cpu(*((volatile u32 *) addr));
130778 +}
130779 +
130780 +static inline void out_be32(void *addr, u32 val)
130781 +{
130782 + *((u32 *) addr) = cpu_to_be32(val);
130783 +}
130784 +
130785 +
130786 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
130787 +{
130788 + *p |= mask;
130789 +}
130790 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
130791 +{
130792 + *p &= ~mask;
130793 +}
130794 +
130795 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
130796 +{
130797 + __cpuc_flush_dcache_area((void *) start, stop - start);
130798 +}
130799 +
130800 +#define hard_smp_processor_id() raw_smp_processor_id()
130801 +#endif
130802 --- /dev/null
130803 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
130804 @@ -0,0 +1,102 @@
130805 +/* Copyright 2014 Freescale Semiconductor, Inc.
130806 + *
130807 + * Redistribution and use in source and binary forms, with or without
130808 + * modification, are permitted provided that the following conditions are met:
130809 + * * Redistributions of source code must retain the above copyright
130810 + * notice, this list of conditions and the following disclaimer.
130811 + * * Redistributions in binary form must reproduce the above copyright
130812 + * notice, this list of conditions and the following disclaimer in the
130813 + * documentation and/or other materials provided with the distribution.
130814 + * * Neither the name of Freescale Semiconductor nor the
130815 + * names of its contributors may be used to endorse or promote products
130816 + * derived from this software without specific prior written permission.
130817 + *
130818 + *
130819 + * ALTERNATIVELY, this software may be distributed under the terms of the
130820 + * GNU General Public License ("GPL") as published by the Free Software
130821 + * Foundation, either version 2 of that License or (at your option) any
130822 + * later version.
130823 + *
130824 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130825 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130826 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130827 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130828 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130829 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130830 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130831 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130832 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130833 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130834 + */
130835 +
130836 +#ifndef DPA_SYS_ARM64_H
130837 +#define DPA_SYS_ARM64_H
130838 +
130839 +#include <asm/cacheflush.h>
130840 +#include <asm/barrier.h>
130841 +
130842 +/* Implementation of ARM 64 bit specific routines */
130843 +
130844 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
130845 + * barriers and that dcb*() won't fall victim to compiler or execution
130846 + * reordering with respect to other code/instructions that manipulate the same
130847 + * cacheline. */
130848 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
130849 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
130850 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
130851 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
130852 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
130853 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
130854 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
130855 +
130856 +#define dcbz_64(p) \
130857 + do { \
130858 + dcbz(p); \
130859 + } while (0)
130860 +
130861 +#define dcbf_64(p) \
130862 + do { \
130863 + dcbf(p); \
130864 + } while (0)
130865 +/* Commonly used combo */
130866 +#define dcbit_ro(p) \
130867 + do { \
130868 + dcbi(p); \
130869 + dcbt_ro(p); \
130870 + } while (0)
130871 +
130872 +static inline u64 mfatb(void)
130873 +{
130874 + return get_cycles();
130875 +}
130876 +
130877 +static inline u32 in_be32(volatile void *addr)
130878 +{
130879 + return be32_to_cpu(*((volatile u32 *) addr));
130880 +}
130881 +
130882 +static inline void out_be32(void *addr, u32 val)
130883 +{
130884 + *((u32 *) addr) = cpu_to_be32(val);
130885 +}
130886 +
130887 +
130888 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
130889 +{
130890 + *p |= mask;
130891 +}
130892 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
130893 +{
130894 + *p &= ~mask;
130895 +}
130896 +
130897 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
130898 +{
130899 + __flush_dcache_area((void *) start, stop - start);
130900 +}
130901 +
130902 +#define hard_smp_processor_id() raw_smp_processor_id()
130903 +
130904 +
130905 +
130906 +#endif
130907 --- /dev/null
130908 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
130909 @@ -0,0 +1,70 @@
130910 +/* Copyright 2014 Freescale Semiconductor, Inc.
130911 + *
130912 + * Redistribution and use in source and binary forms, with or without
130913 + * modification, are permitted provided that the following conditions are met:
130914 + * * Redistributions of source code must retain the above copyright
130915 + * notice, this list of conditions and the following disclaimer.
130916 + * * Redistributions in binary form must reproduce the above copyright
130917 + * notice, this list of conditions and the following disclaimer in the
130918 + * documentation and/or other materials provided with the distribution.
130919 + * * Neither the name of Freescale Semiconductor nor the
130920 + * names of its contributors may be used to endorse or promote products
130921 + * derived from this software without specific prior written permission.
130922 + *
130923 + *
130924 + * ALTERNATIVELY, this software may be distributed under the terms of the
130925 + * GNU General Public License ("GPL") as published by the Free Software
130926 + * Foundation, either version 2 of that License or (at your option) any
130927 + * later version.
130928 + *
130929 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130930 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130931 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130932 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130933 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130934 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130935 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130936 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130937 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130938 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130939 + */
130940 +
130941 +#ifndef DPA_SYS_PPC32_H
130942 +#define DPA_SYS_PPC32_H
130943 +
130944 +/* Implementation of PowerPC 32 bit specific routines */
130945 +
130946 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
130947 + * barriers and that dcb*() won't fall victim to compiler or execution
130948 + * reordering with respect to other code/instructions that manipulate the same
130949 + * cacheline. */
130950 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
130951 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
130952 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
130953 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
130954 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
130955 +#define dcbi(p) dcbf(p)
130956 +
130957 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
130958 +#define dcbz_64(p) dcbzl(p)
130959 +#define dcbf_64(p) dcbf(p)
130960 +
130961 +/* Commonly used combo */
130962 +#define dcbit_ro(p) \
130963 + do { \
130964 + dcbi(p); \
130965 + dcbt_ro(p); \
130966 + } while (0)
130967 +
130968 +static inline u64 mfatb(void)
130969 +{
130970 + u32 hi, lo, chk;
130971 + do {
130972 + hi = mfspr(SPRN_ATBU);
130973 + lo = mfspr(SPRN_ATBL);
130974 + chk = mfspr(SPRN_ATBU);
130975 + } while (unlikely(hi != chk));
130976 + return ((u64)hi << 32) | (u64)lo;
130977 +}
130978 +
130979 +#endif
130980 --- /dev/null
130981 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
130982 @@ -0,0 +1,79 @@
130983 +/* Copyright 2014 Freescale Semiconductor, Inc.
130984 + *
130985 + * Redistribution and use in source and binary forms, with or without
130986 + * modification, are permitted provided that the following conditions are met:
130987 + * * Redistributions of source code must retain the above copyright
130988 + * notice, this list of conditions and the following disclaimer.
130989 + * * Redistributions in binary form must reproduce the above copyright
130990 + * notice, this list of conditions and the following disclaimer in the
130991 + * documentation and/or other materials provided with the distribution.
130992 + * * Neither the name of Freescale Semiconductor nor the
130993 + * names of its contributors may be used to endorse or promote products
130994 + * derived from this software without specific prior written permission.
130995 + *
130996 + *
130997 + * ALTERNATIVELY, this software may be distributed under the terms of the
130998 + * GNU General Public License ("GPL") as published by the Free Software
130999 + * Foundation, either version 2 of that License or (at your option) any
131000 + * later version.
131001 + *
131002 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131003 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131004 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131005 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131006 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131007 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131008 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131009 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131010 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131011 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131012 + */
131013 +
131014 +#ifndef DPA_SYS_PPC64_H
131015 +#define DPA_SYS_PPC64_H
131016 +
131017 +/* Implementation of PowerPC 64 bit specific routines */
131018 +
131019 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
131020 + * barriers and that dcb*() won't fall victim to compiler or execution
131021 + * reordering with respect to other code/instructions that manipulate the same
131022 + * cacheline. */
131023 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
131024 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
131025 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
131026 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
131027 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
131028 +#define dcbi(p) dcbf(p)
131029 +
131030 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
131031 +#define dcbz_64(p) \
131032 + do { \
131033 + dcbz((void*)p + 32); \
131034 + dcbz(p); \
131035 + } while (0)
131036 +#define dcbf_64(p) \
131037 + do { \
131038 + dcbf((void*)p + 32); \
131039 + dcbf(p); \
131040 + } while (0)
131041 +/* Commonly used combo */
131042 +#define dcbit_ro(p) \
131043 + do { \
131044 + dcbi(p); \
131045 + dcbi((void*)p + 32); \
131046 + dcbt_ro(p); \
131047 + dcbt_ro((void*)p + 32); \
131048 + } while (0)
131049 +
131050 +static inline u64 mfatb(void)
131051 +{
131052 + u32 hi, lo, chk;
131053 + do {
131054 + hi = mfspr(SPRN_ATBU);
131055 + lo = mfspr(SPRN_ATBL);
131056 + chk = mfspr(SPRN_ATBU);
131057 + } while (unlikely(hi != chk));
131058 + return ((u64)hi << 32) | (u64)lo;
131059 +}
131060 +
131061 +#endif
131062 --- /dev/null
131063 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
131064 @@ -0,0 +1,2008 @@
131065 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
131066 + * Authors: Andy Fleming <afleming@freescale.com>
131067 + * Timur Tabi <timur@freescale.com>
131068 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
131069 + *
131070 + * This file is licensed under the terms of the GNU General Public License
131071 + * version 2. This program is licensed "as is" without any warranty of any
131072 + * kind, whether express or implied.
131073 + */
131074 +
131075 +
131076 +#include <linux/miscdevice.h>
131077 +#include <linux/fs.h>
131078 +#include <linux/cdev.h>
131079 +#include <linux/mm.h>
131080 +#include <linux/of.h>
131081 +#include <linux/memblock.h>
131082 +#include <linux/slab.h>
131083 +#include <linux/mman.h>
131084 +#include <linux/of_reserved_mem.h>
131085 +
131086 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
131087 +#include <mm/mmu_decl.h>
131088 +#endif
131089 +
131090 +#include "dpa_sys.h"
131091 +#include <linux/fsl_usdpaa.h>
131092 +#include "bman_low.h"
131093 +#include "qman_low.h"
131094 +
131095 +/* Physical address range of the memory reservation, exported for mm/mem.c */
131096 +static u64 phys_start;
131097 +static u64 phys_size;
131098 +static u64 arg_phys_size;
131099 +
131100 +/* PFN versions of the above */
131101 +static unsigned long pfn_start;
131102 +static unsigned long pfn_size;
131103 +
131104 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
131105 + * isn't atomic_t). */
131106 +static DEFINE_SPINLOCK(mem_lock);
131107 +
131108 +/* The range of TLB1 indices */
131109 +static unsigned int first_tlb;
131110 +static unsigned int num_tlb = 1;
131111 +static unsigned int current_tlb; /* loops around for fault handling */
131112 +
131113 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
131114 + * may be mapped. Unmapped fragments are always merged where possible. */
131115 +static LIST_HEAD(mem_list);
131116 +
131117 +struct mem_mapping;
131118 +
131119 +/* Memory fragments are in 'mem_list'. */
131120 +struct mem_fragment {
131121 + u64 base;
131122 + u64 len;
131123 + unsigned long pfn_base; /* PFN version of 'base' */
131124 + unsigned long pfn_len; /* PFN version of 'len' */
131125 + unsigned int refs; /* zero if unmapped */
131126 + u64 root_len; /* Size of the orignal fragment */
131127 + unsigned long root_pfn; /* PFN of the orignal fragment */
131128 + struct list_head list;
131129 + /* if mapped, flags+name captured at creation time */
131130 + u32 flags;
131131 + char name[USDPAA_DMA_NAME_MAX];
131132 + u64 map_len;
131133 + /* support multi-process locks per-memory-fragment. */
131134 + int has_locking;
131135 + wait_queue_head_t wq;
131136 + struct mem_mapping *owner;
131137 +};
131138 +
131139 +/* Mappings of memory fragments in 'struct ctx'. These are created from
131140 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
131141 + * mmap(). */
131142 +struct mem_mapping {
131143 + struct mem_fragment *root_frag;
131144 + u32 frag_count;
131145 + u64 total_size;
131146 + struct list_head list;
131147 + int refs;
131148 + void *virt_addr;
131149 +};
131150 +
131151 +struct portal_mapping {
131152 + struct usdpaa_ioctl_portal_map user;
131153 + union {
131154 + struct qm_portal_config *qportal;
131155 + struct bm_portal_config *bportal;
131156 + };
131157 + /* Declare space for the portals in case the process
131158 + exits unexpectedly and needs to be cleaned by the kernel */
131159 + union {
131160 + struct qm_portal qman_portal_low;
131161 + struct bm_portal bman_portal_low;
131162 + };
131163 + struct list_head list;
131164 + struct resource *phys;
131165 + struct iommu_domain *iommu_domain;
131166 +};
131167 +
131168 +/* Track the DPAA resources the process is using */
131169 +struct active_resource {
131170 + struct list_head list;
131171 + u32 id;
131172 + u32 num;
131173 + unsigned int refcount;
131174 +};
131175 +
131176 +/* Per-FD state (which should also be per-process but we don't enforce that) */
131177 +struct ctx {
131178 + /* Lock to protect the context */
131179 + spinlock_t lock;
131180 + /* Allocated resources get put here for accounting */
131181 + struct list_head resources[usdpaa_id_max];
131182 + /* list of DMA maps */
131183 + struct list_head maps;
131184 + /* list of portal maps */
131185 + struct list_head portals;
131186 +};
131187 +
131188 +/* Different resource classes */
131189 +static const struct alloc_backend {
131190 + enum usdpaa_id_type id_type;
131191 + int (*alloc)(u32 *, u32, u32, int);
131192 + void (*release)(u32 base, unsigned int count);
131193 + int (*reserve)(u32 base, unsigned int count);
131194 + const char *acronym;
131195 +} alloc_backends[] = {
131196 + {
131197 + .id_type = usdpaa_id_fqid,
131198 + .alloc = qman_alloc_fqid_range,
131199 + .release = qman_release_fqid_range,
131200 + .reserve = qman_reserve_fqid_range,
131201 + .acronym = "FQID"
131202 + },
131203 + {
131204 + .id_type = usdpaa_id_bpid,
131205 + .alloc = bman_alloc_bpid_range,
131206 + .release = bman_release_bpid_range,
131207 + .reserve = bman_reserve_bpid_range,
131208 + .acronym = "BPID"
131209 + },
131210 + {
131211 + .id_type = usdpaa_id_qpool,
131212 + .alloc = qman_alloc_pool_range,
131213 + .release = qman_release_pool_range,
131214 + .reserve = qman_reserve_pool_range,
131215 + .acronym = "QPOOL"
131216 + },
131217 + {
131218 + .id_type = usdpaa_id_cgrid,
131219 + .alloc = qman_alloc_cgrid_range,
131220 + .release = qman_release_cgrid_range,
131221 + .acronym = "CGRID"
131222 + },
131223 + {
131224 + .id_type = usdpaa_id_ceetm0_lfqid,
131225 + .alloc = qman_alloc_ceetm0_lfqid_range,
131226 + .release = qman_release_ceetm0_lfqid_range,
131227 + .acronym = "CEETM0_LFQID"
131228 + },
131229 + {
131230 + .id_type = usdpaa_id_ceetm0_channelid,
131231 + .alloc = qman_alloc_ceetm0_channel_range,
131232 + .release = qman_release_ceetm0_channel_range,
131233 + .acronym = "CEETM0_LFQID"
131234 + },
131235 + {
131236 + .id_type = usdpaa_id_ceetm1_lfqid,
131237 + .alloc = qman_alloc_ceetm1_lfqid_range,
131238 + .release = qman_release_ceetm1_lfqid_range,
131239 + .acronym = "CEETM1_LFQID"
131240 + },
131241 + {
131242 + .id_type = usdpaa_id_ceetm1_channelid,
131243 + .alloc = qman_alloc_ceetm1_channel_range,
131244 + .release = qman_release_ceetm1_channel_range,
131245 + .acronym = "CEETM1_LFQID"
131246 + },
131247 + {
131248 + /* This terminates the array */
131249 + .id_type = usdpaa_id_max
131250 + }
131251 +};
131252 +
131253 +/* Determines the largest acceptable page size for a given size
131254 + The sizes are determined by what the TLB1 acceptable page sizes are */
131255 +static u32 largest_page_size(u32 size)
131256 +{
131257 + int shift = 30; /* Start at 1G size */
131258 + if (size < 4096)
131259 + return 0;
131260 + do {
131261 + if (size >= (1<<shift))
131262 + return 1<<shift;
131263 + shift -= 2;
131264 + } while (shift >= 12); /* Up to 4k */
131265 + return 0;
131266 +}
131267 +
131268 +/* Determine if value is power of 4 */
131269 +static inline bool is_power_of_4(u64 x)
131270 +{
131271 + if (x == 0 || ((x & (x - 1)) != 0))
131272 + return false;
131273 + return !!(x & 0x5555555555555555ull);
131274 +}
131275 +
131276 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
131277 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
131278 + * until it has a suitable fragment size.) */
131279 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
131280 +{
131281 + struct mem_fragment *x[3];
131282 +
131283 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
131284 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
131285 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
131286 + if (!x[0] || !x[1] || !x[2]) {
131287 + kfree(x[0]);
131288 + kfree(x[1]);
131289 + kfree(x[2]);
131290 + return NULL;
131291 + }
131292 + BUG_ON(frag->refs);
131293 + frag->len >>= 2;
131294 + frag->pfn_len >>= 2;
131295 + x[0]->base = frag->base + frag->len;
131296 + x[1]->base = x[0]->base + frag->len;
131297 + x[2]->base = x[1]->base + frag->len;
131298 + x[0]->len = x[1]->len = x[2]->len = frag->len;
131299 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
131300 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
131301 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
131302 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
131303 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
131304 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
131305 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
131306 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
131307 + list_add_tail(&x[0]->list, &frag->list);
131308 + list_add_tail(&x[1]->list, &x[0]->list);
131309 + list_add_tail(&x[2]->list, &x[1]->list);
131310 + return x[2];
131311 +}
131312 +
131313 +static __maybe_unused void dump_frags(void)
131314 +{
131315 + struct mem_fragment *frag;
131316 + int i = 0;
131317 + list_for_each_entry(frag, &mem_list, list) {
131318 + 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",
131319 + i, frag->base, frag->pfn_base,
131320 + frag->len, frag->root_len, frag->root_pfn,
131321 + frag->refs, frag->name);
131322 + ++i;
131323 + }
131324 +}
131325 +
131326 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
131327 +static void compress_frags(void)
131328 +{
131329 + /* Walk the fragment list and combine fragments */
131330 + struct mem_fragment *frag, *nxtfrag;
131331 + u64 len = 0;
131332 +
131333 + int i, numfrags;
131334 +
131335 +
131336 + frag = list_entry(mem_list.next, struct mem_fragment, list);
131337 +
131338 + while (&frag->list != &mem_list) {
131339 + /* Must combine consecutive fragemenst with
131340 + same root_pfn such that they are power of 4 */
131341 + if (frag->refs != 0) {
131342 + frag = list_entry(frag->list.next,
131343 + struct mem_fragment, list);
131344 + continue; /* Not this window */
131345 + }
131346 + len = frag->len;
131347 + numfrags = 0;
131348 + nxtfrag = list_entry(frag->list.next,
131349 + struct mem_fragment, list);
131350 + while (true) {
131351 + if (&nxtfrag->list == &mem_list) {
131352 + numfrags = 0;
131353 + break; /* End of list */
131354 + }
131355 + if (nxtfrag->refs) {
131356 + numfrags = 0;
131357 + break; /* In use still */
131358 + }
131359 + if (nxtfrag->root_pfn != frag->root_pfn) {
131360 + numfrags = 0;
131361 + break; /* Crosses root fragment boundary */
131362 + }
131363 + len += nxtfrag->len;
131364 + numfrags++;
131365 + if (is_power_of_4(len)) {
131366 + /* These fragments can be combined */
131367 + break;
131368 + }
131369 + nxtfrag = list_entry(nxtfrag->list.next,
131370 + struct mem_fragment, list);
131371 + }
131372 + if (numfrags == 0) {
131373 + frag = list_entry(frag->list.next,
131374 + struct mem_fragment, list);
131375 + continue; /* try the next window */
131376 + }
131377 + for (i = 0; i < numfrags; i++) {
131378 + struct mem_fragment *todel =
131379 + list_entry(nxtfrag->list.prev,
131380 + struct mem_fragment, list);
131381 + nxtfrag->len += todel->len;
131382 + nxtfrag->pfn_len += todel->pfn_len;
131383 + list_del(&todel->list);
131384 + }
131385 + /* Re evaluate the list, things may merge now */
131386 + frag = list_entry(mem_list.next, struct mem_fragment, list);
131387 + }
131388 +}
131389 +
131390 +/* Hook from arch/powerpc/mm/mem.c */
131391 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
131392 +{
131393 + struct mem_fragment *frag;
131394 + int idx = -1;
131395 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
131396 + return -1;
131397 + /* It's in-range, we need to find the fragment */
131398 + spin_lock(&mem_lock);
131399 + list_for_each_entry(frag, &mem_list, list) {
131400 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
131401 + frag->pfn_len))) {
131402 + *phys_addr = frag->base;
131403 + *size = frag->len;
131404 + idx = current_tlb++;
131405 + if (current_tlb >= (first_tlb + num_tlb))
131406 + current_tlb = first_tlb;
131407 + break;
131408 + }
131409 + }
131410 + spin_unlock(&mem_lock);
131411 + return idx;
131412 +}
131413 +
131414 +static int usdpaa_open(struct inode *inode, struct file *filp)
131415 +{
131416 + const struct alloc_backend *backend = &alloc_backends[0];
131417 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
131418 + if (!ctx)
131419 + return -ENOMEM;
131420 + filp->private_data = ctx;
131421 +
131422 + while (backend->id_type != usdpaa_id_max) {
131423 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
131424 + backend++;
131425 + }
131426 +
131427 + INIT_LIST_HEAD(&ctx->maps);
131428 + INIT_LIST_HEAD(&ctx->portals);
131429 + spin_lock_init(&ctx->lock);
131430 +
131431 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
131432 +
131433 + return 0;
131434 +}
131435 +
131436 +#define DQRR_MAXFILL 15
131437 +
131438 +
131439 +/* Invalidate a portal */
131440 +void dbci_portal(void *addr)
131441 +{
131442 + int i;
131443 +
131444 + for (i = 0; i < 0x4000; i += 64)
131445 + dcbi(addr + i);
131446 +}
131447 +
131448 +/* Reset a QMan portal to its default state */
131449 +static int init_qm_portal(struct qm_portal_config *config,
131450 + struct qm_portal *portal)
131451 +{
131452 + const struct qm_dqrr_entry *dqrr = NULL;
131453 + int i;
131454 +
131455 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
131456 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
131457 +
131458 + /* Make sure interrupts are inhibited */
131459 + qm_out(IIR, 1);
131460 +
131461 + /*
131462 + * Invalidate the entire CE portal are to ensure no stale
131463 + * cachelines are present. This should be done on all
131464 + * cores as the portal is mapped as M=0 (non-coherent).
131465 + */
131466 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
131467 +
131468 + /* Initialize the DQRR. This will stop any dequeue
131469 + commands that are in progress */
131470 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
131471 + qm_dqrr_cdc, DQRR_MAXFILL)) {
131472 + pr_err("qm_dqrr_init() failed when trying to"
131473 + " recover portal, portal will be leaked\n");
131474 + return 1;
131475 + }
131476 +
131477 + /* Discard any entries on the DQRR */
131478 + /* If we consume the ring twice something is wrong */
131479 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
131480 + qm_dqrr_pvb_update(portal);
131481 + dqrr = qm_dqrr_current(portal);
131482 + if (!dqrr)
131483 + break;
131484 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
131485 + qm_dqrr_pvb_update(portal);
131486 + qm_dqrr_next(portal);
131487 + }
131488 + /* Initialize the EQCR */
131489 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
131490 + qm_eqcr_get_ci_stashing(portal), 1)) {
131491 + pr_err("Qman EQCR initialisation failed\n");
131492 + return 1;
131493 + }
131494 + /* initialize the MR */
131495 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
131496 + pr_err("Qman MR initialisation failed\n");
131497 + return 1;
131498 + }
131499 + qm_mr_pvb_update(portal);
131500 + while (qm_mr_current(portal)) {
131501 + qm_mr_next(portal);
131502 + qm_mr_cci_consume_to_current(portal);
131503 + qm_mr_pvb_update(portal);
131504 + }
131505 +
131506 + if (qm_mc_init(portal)) {
131507 + pr_err("Qman MC initialisation failed\n");
131508 + return 1;
131509 + }
131510 + return 0;
131511 +}
131512 +
131513 +static int init_bm_portal(struct bm_portal_config *config,
131514 + struct bm_portal *portal)
131515 +{
131516 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
131517 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
131518 +
131519 + /*
131520 + * Invalidate the entire CE portal are to ensure no stale
131521 + * cachelines are present. This should be done on all
131522 + * cores as the portal is mapped as M=0 (non-coherent).
131523 + */
131524 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
131525 +
131526 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
131527 + pr_err("Bman RCR initialisation failed\n");
131528 + return 1;
131529 + }
131530 + if (bm_mc_init(portal)) {
131531 + pr_err("Bman MC initialisation failed\n");
131532 + return 1;
131533 + }
131534 + return 0;
131535 +}
131536 +
131537 +/* Function that will scan all FQ's in the system. For each FQ that is not
131538 + OOS it will call the check_channel helper to determine if the FQ should
131539 + be torn down. If the check_channel helper returns true the FQ will be
131540 + transitioned to the OOS state */
131541 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
131542 + bool (*check_channel)(void*, u32))
131543 +{
131544 + u32 fq_id = 0;
131545 + while (1) {
131546 + struct qm_mc_command *mcc;
131547 + struct qm_mc_result *mcr;
131548 + u8 state;
131549 + u32 channel;
131550 +
131551 + /* Determine the channel for the FQID */
131552 + mcc = qm_mc_start(portal);
131553 + mcc->queryfq.fqid = fq_id;
131554 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
131555 + while (!(mcr = qm_mc_result(portal)))
131556 + cpu_relax();
131557 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
131558 + == QM_MCR_VERB_QUERYFQ);
131559 + if (mcr->result != QM_MCR_RESULT_OK)
131560 + break; /* End of valid FQIDs */
131561 +
131562 + channel = mcr->queryfq.fqd.dest.channel;
131563 + /* Determine the state of the FQID */
131564 + mcc = qm_mc_start(portal);
131565 + mcc->queryfq_np.fqid = fq_id;
131566 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
131567 + while (!(mcr = qm_mc_result(portal)))
131568 + cpu_relax();
131569 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
131570 + == QM_MCR_VERB_QUERYFQ_NP);
131571 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
131572 + if (state == QM_MCR_NP_STATE_OOS)
131573 + /* Already OOS, no need to do anymore checks */
131574 + goto next;
131575 +
131576 + if (check_channel(ctx, channel))
131577 + qm_shutdown_fq(&portal, 1, fq_id);
131578 + next:
131579 + ++fq_id;
131580 + }
131581 + return 0;
131582 +}
131583 +
131584 +static bool check_channel_device(void *_ctx, u32 channel)
131585 +{
131586 + struct ctx *ctx = _ctx;
131587 + struct portal_mapping *portal, *tmpportal;
131588 + struct active_resource *res;
131589 +
131590 + /* See if the FQ is destined for one of the portals we're cleaning up */
131591 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
131592 + if (portal->user.type == usdpaa_portal_qman) {
131593 + if (portal->qportal->public_cfg.channel == channel) {
131594 + /* This FQs destination is a portal
131595 + we're cleaning, send a retire */
131596 + return true;
131597 + }
131598 + }
131599 + }
131600 +
131601 + /* Check the pool channels that will be released as well */
131602 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
131603 + if ((res->id >= channel) &&
131604 + ((res->id + res->num - 1) <= channel))
131605 + return true;
131606 + }
131607 + return false;
131608 +}
131609 +
131610 +static bool check_portal_channel(void *ctx, u32 channel)
131611 +{
131612 + u32 portal_channel = *(u32 *)ctx;
131613 + if (portal_channel == channel) {
131614 + /* This FQs destination is a portal
131615 + we're cleaning, send a retire */
131616 + return true;
131617 + }
131618 + return false;
131619 +}
131620 +
131621 +
131622 +
131623 +
131624 +static int usdpaa_release(struct inode *inode, struct file *filp)
131625 +{
131626 + struct ctx *ctx = filp->private_data;
131627 + struct mem_mapping *map, *tmpmap;
131628 + struct portal_mapping *portal, *tmpportal;
131629 + const struct alloc_backend *backend = &alloc_backends[0];
131630 + struct active_resource *res;
131631 + struct qm_portal *qm_cleanup_portal = NULL;
131632 + struct bm_portal *bm_cleanup_portal = NULL;
131633 + struct qm_portal_config *qm_alloced_portal = NULL;
131634 + struct bm_portal_config *bm_alloced_portal = NULL;
131635 +
131636 + struct qm_portal *portal_array[qman_portal_max];
131637 + int portal_count = 0;
131638 +
131639 + /* Ensure the release operation cannot be migrated to another
131640 + CPU as CPU specific variables may be needed during cleanup */
131641 +#ifdef CONFIG_PREEMPT_RT_FULL
131642 + migrate_disable();
131643 +#endif
131644 + /* The following logic is used to recover resources that were not
131645 + correctly released by the process that is closing the FD.
131646 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
131647 + in the kernel
131648 + */
131649 +
131650 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
131651 + /* Try to recover any portals that weren't shut down */
131652 + if (portal->user.type == usdpaa_portal_qman) {
131653 + portal_array[portal_count] = &portal->qman_portal_low;
131654 + ++portal_count;
131655 + init_qm_portal(portal->qportal,
131656 + &portal->qman_portal_low);
131657 + if (!qm_cleanup_portal) {
131658 + qm_cleanup_portal = &portal->qman_portal_low;
131659 + } else {
131660 + /* Clean FQs on the dedicated channel */
131661 + u32 chan = portal->qportal->public_cfg.channel;
131662 + qm_check_and_destroy_fqs(
131663 + &portal->qman_portal_low, &chan,
131664 + check_portal_channel);
131665 + }
131666 + } else {
131667 + /* BMAN */
131668 + init_bm_portal(portal->bportal,
131669 + &portal->bman_portal_low);
131670 + if (!bm_cleanup_portal)
131671 + bm_cleanup_portal = &portal->bman_portal_low;
131672 + }
131673 + }
131674 + /* If no portal was found, allocate one for cleanup */
131675 + if (!qm_cleanup_portal) {
131676 + qm_alloced_portal = qm_get_unused_portal();
131677 + if (!qm_alloced_portal) {
131678 + pr_crit("No QMan portal avalaible for cleanup\n");
131679 +#ifdef CONFIG_PREEMPT_RT_FULL
131680 + migrate_enable();
131681 +#endif
131682 + return -1;
131683 + }
131684 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
131685 + GFP_KERNEL);
131686 + if (!qm_cleanup_portal) {
131687 +#ifdef CONFIG_PREEMPT_RT_FULL
131688 + migrate_enable();
131689 +#endif
131690 + return -ENOMEM;
131691 + }
131692 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
131693 + portal_array[portal_count] = qm_cleanup_portal;
131694 + ++portal_count;
131695 + }
131696 + if (!bm_cleanup_portal) {
131697 + bm_alloced_portal = bm_get_unused_portal();
131698 + if (!bm_alloced_portal) {
131699 + pr_crit("No BMan portal avalaible for cleanup\n");
131700 +#ifdef CONFIG_PREEMPT_RT_FULL
131701 + migrate_enable();
131702 +#endif
131703 + return -1;
131704 + }
131705 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
131706 + GFP_KERNEL);
131707 + if (!bm_cleanup_portal) {
131708 +#ifdef CONFIG_PREEMPT_RT_FULL
131709 + migrate_enable();
131710 +#endif
131711 + return -ENOMEM;
131712 + }
131713 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
131714 + }
131715 +
131716 + /* OOS the FQs associated with this process */
131717 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
131718 +
131719 + while (backend->id_type != usdpaa_id_max) {
131720 + int leaks = 0;
131721 + list_for_each_entry(res, &ctx->resources[backend->id_type],
131722 + list) {
131723 + if (backend->id_type == usdpaa_id_fqid) {
131724 + int i = 0;
131725 + for (; i < res->num; i++) {
131726 + /* Clean FQs with the cleanup portal */
131727 + qm_shutdown_fq(portal_array,
131728 + portal_count,
131729 + res->id + i);
131730 + }
131731 + }
131732 + leaks += res->num;
131733 + backend->release(res->id, res->num);
131734 + }
131735 + if (leaks)
131736 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
131737 + backend->acronym, (leaks > 1) ? "s" : "");
131738 + backend++;
131739 + }
131740 + /* Release any DMA regions */
131741 + spin_lock(&mem_lock);
131742 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
131743 + struct mem_fragment *current_frag = map->root_frag;
131744 + int i;
131745 + if (map->root_frag->has_locking &&
131746 + (map->root_frag->owner == map)) {
131747 + map->root_frag->owner = NULL;
131748 + wake_up(&map->root_frag->wq);
131749 + }
131750 + /* Check each fragment and merge if the ref count is 0 */
131751 + for (i = 0; i < map->frag_count; i++) {
131752 + --current_frag->refs;
131753 + current_frag = list_entry(current_frag->list.prev,
131754 + struct mem_fragment, list);
131755 + }
131756 +
131757 + compress_frags();
131758 + list_del(&map->list);
131759 + kfree(map);
131760 + }
131761 + spin_unlock(&mem_lock);
131762 +
131763 + /* Return portals */
131764 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
131765 + if (portal->user.type == usdpaa_portal_qman) {
131766 + /* Give the portal back to the allocator */
131767 + init_qm_portal(portal->qportal,
131768 + &portal->qman_portal_low);
131769 + qm_put_unused_portal(portal->qportal);
131770 + } else {
131771 + init_bm_portal(portal->bportal,
131772 + &portal->bman_portal_low);
131773 + bm_put_unused_portal(portal->bportal);
131774 + }
131775 + list_del(&portal->list);
131776 + kfree(portal);
131777 + }
131778 + if (qm_alloced_portal) {
131779 + qm_put_unused_portal(qm_alloced_portal);
131780 + kfree(qm_cleanup_portal);
131781 + }
131782 + if (bm_alloced_portal) {
131783 + bm_put_unused_portal(bm_alloced_portal);
131784 + kfree(bm_cleanup_portal);
131785 + }
131786 +
131787 + kfree(ctx);
131788 +#ifdef CONFIG_PREEMPT_RT_FULL
131789 + migrate_enable();
131790 +#endif
131791 + return 0;
131792 +}
131793 +
131794 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
131795 + int *match, unsigned long *pfn)
131796 +{
131797 + struct mem_mapping *map;
131798 +
131799 + list_for_each_entry(map, &ctx->maps, list) {
131800 + int i;
131801 + struct mem_fragment *frag = map->root_frag;
131802 +
131803 + for (i = 0; i < map->frag_count; i++) {
131804 + if (frag->pfn_base == vma->vm_pgoff) {
131805 + *match = 1;
131806 + *pfn = frag->pfn_base;
131807 + return 0;
131808 + }
131809 + frag = list_entry(frag->list.next, struct mem_fragment,
131810 + list);
131811 + }
131812 + }
131813 + *match = 0;
131814 + return 0;
131815 +}
131816 +
131817 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
131818 + int *match, unsigned long *pfn)
131819 +{
131820 + *pfn = res->start >> PAGE_SHIFT;
131821 + if (*pfn == vma->vm_pgoff) {
131822 + *match = 1;
131823 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
131824 + return -EINVAL;
131825 + } else
131826 + *match = 0;
131827 + return 0;
131828 +}
131829 +
131830 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
131831 + int *match, unsigned long *pfn)
131832 +{
131833 + struct portal_mapping *portal;
131834 + int ret;
131835 +
131836 + list_for_each_entry(portal, &ctx->portals, list) {
131837 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
131838 + match, pfn);
131839 + if (*match) {
131840 + vma->vm_page_prot =
131841 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
131842 + pgprot_cached_ns(vma->vm_page_prot);
131843 +#else
131844 + pgprot_cached_noncoherent(vma->vm_page_prot);
131845 +#endif
131846 + return ret;
131847 + }
131848 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
131849 + match, pfn);
131850 + if (*match) {
131851 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
131852 + return ret;
131853 + }
131854 + }
131855 + *match = 0;
131856 + return 0;
131857 +}
131858 +
131859 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
131860 +{
131861 + struct ctx *ctx = filp->private_data;
131862 + unsigned long pfn = 0;
131863 + int match, ret;
131864 +
131865 + spin_lock(&mem_lock);
131866 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
131867 + if (!match)
131868 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
131869 + spin_unlock(&mem_lock);
131870 + if (!match)
131871 + return -EINVAL;
131872 + if (!ret)
131873 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
131874 + vma->vm_end - vma->vm_start,
131875 + vma->vm_page_prot);
131876 + return ret;
131877 +}
131878 +
131879 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
131880 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
131881 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
131882 + ({ \
131883 + unsigned long foo_align = (sz) - 1; \
131884 + ((addr) + foo_align) & ~foo_align; \
131885 + })
131886 +/* Searching for a size-aligned virtual address range starting from 'addr' */
131887 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
131888 + unsigned long addr,
131889 + unsigned long len,
131890 + unsigned long pgoff,
131891 + unsigned long flags)
131892 +{
131893 + struct vm_area_struct *vma;
131894 +
131895 + if (len % PAGE_SIZE)
131896 + return -EINVAL;
131897 + if (!len)
131898 + return -EINVAL;
131899 +
131900 + /* Need to align the address to the largest pagesize of the mapping
131901 + * because the MMU requires the virtual address to have the same
131902 + * alignment as the physical address */
131903 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
131904 + vma = find_vma(current->mm, addr);
131905 + /* Keep searching until we reach the end of currently-used virtual
131906 + * address-space or we find a big enough gap. */
131907 + while (vma) {
131908 + if ((addr + len) < vma->vm_start)
131909 + return addr;
131910 +
131911 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
131912 + vma = vma->vm_next;
131913 + }
131914 + if ((TASK_SIZE - len) < addr)
131915 + return -ENOMEM;
131916 + return addr;
131917 +}
131918 +
131919 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
131920 +{
131921 + struct usdpaa_ioctl_id_alloc i;
131922 + const struct alloc_backend *backend;
131923 + struct active_resource *res;
131924 + int ret = copy_from_user(&i, arg, sizeof(i));
131925 + if (ret)
131926 + return ret;
131927 + if ((i.id_type >= usdpaa_id_max) || !i.num)
131928 + return -EINVAL;
131929 + backend = &alloc_backends[i.id_type];
131930 + /* Allocate the required resource type */
131931 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
131932 + if (ret < 0)
131933 + return ret;
131934 + i.num = ret;
131935 + /* Copy the result to user-space */
131936 + ret = copy_to_user(arg, &i, sizeof(i));
131937 + if (ret) {
131938 + backend->release(i.base, i.num);
131939 + return ret;
131940 + }
131941 + /* Assign the allocated range to the FD accounting */
131942 + res = kmalloc(sizeof(*res), GFP_KERNEL);
131943 + if (!res) {
131944 + backend->release(i.base, i.num);
131945 + return -ENOMEM;
131946 + }
131947 + spin_lock(&ctx->lock);
131948 + res->id = i.base;
131949 + res->num = i.num;
131950 + res->refcount = 1;
131951 + list_add(&res->list, &ctx->resources[i.id_type]);
131952 + spin_unlock(&ctx->lock);
131953 + return 0;
131954 +}
131955 +
131956 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
131957 +{
131958 + struct usdpaa_ioctl_id_release i;
131959 + const struct alloc_backend *backend;
131960 + struct active_resource *tmp, *pos;
131961 +
131962 + int ret = copy_from_user(&i, arg, sizeof(i));
131963 + if (ret)
131964 + return ret;
131965 + if ((i.id_type >= usdpaa_id_max) || !i.num)
131966 + return -EINVAL;
131967 + backend = &alloc_backends[i.id_type];
131968 + /* Pull the range out of the FD accounting - the range is valid iff this
131969 + * succeeds. */
131970 + spin_lock(&ctx->lock);
131971 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
131972 + if (pos->id == i.base && pos->num == i.num) {
131973 + pos->refcount--;
131974 + if (pos->refcount) {
131975 + spin_unlock(&ctx->lock);
131976 + return 0; /* Still being used */
131977 + }
131978 + list_del(&pos->list);
131979 + kfree(pos);
131980 + spin_unlock(&ctx->lock);
131981 + goto found;
131982 + }
131983 + }
131984 + /* Failed to find the resource */
131985 + spin_unlock(&ctx->lock);
131986 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
131987 + i.id_type, i.base, i.num);
131988 + return -EINVAL;
131989 +found:
131990 + /* Release the resource to the backend */
131991 + backend->release(i.base, i.num);
131992 + return 0;
131993 +}
131994 +
131995 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
131996 +{
131997 + struct usdpaa_ioctl_id_reserve i;
131998 + const struct alloc_backend *backend;
131999 + struct active_resource *tmp, *pos;
132000 +
132001 + int ret = copy_from_user(&i, arg, sizeof(i));
132002 + if (ret)
132003 + return ret;
132004 + if ((i.id_type >= usdpaa_id_max) || !i.num)
132005 + return -EINVAL;
132006 + backend = &alloc_backends[i.id_type];
132007 + if (!backend->reserve)
132008 + return -EINVAL;
132009 + /* Pull the range out of the FD accounting - the range is valid iff this
132010 + * succeeds. */
132011 + spin_lock(&ctx->lock);
132012 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
132013 + if (pos->id == i.base && pos->num == i.num) {
132014 + pos->refcount++;
132015 + spin_unlock(&ctx->lock);
132016 + return 0;
132017 + }
132018 + }
132019 +
132020 + /* Failed to find the resource */
132021 + spin_unlock(&ctx->lock);
132022 +
132023 + /* Reserve the resource in the backend */
132024 + ret = backend->reserve(i.base, i.num);
132025 + if (ret)
132026 + return ret;
132027 + /* Assign the reserved range to the FD accounting */
132028 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
132029 + if (!pos) {
132030 + backend->release(i.base, i.num);
132031 + return -ENOMEM;
132032 + }
132033 + spin_lock(&ctx->lock);
132034 + pos->id = i.base;
132035 + pos->num = i.num;
132036 + pos->refcount = 1;
132037 + list_add(&pos->list, &ctx->resources[i.id_type]);
132038 + spin_unlock(&ctx->lock);
132039 + return 0;
132040 +}
132041 +
132042 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
132043 + struct usdpaa_ioctl_dma_map *i)
132044 +{
132045 + struct mem_fragment *frag, *start_frag, *next_frag;
132046 + struct mem_mapping *map, *tmp;
132047 + int ret = 0;
132048 + u32 largest_page, so_far = 0;
132049 + int frag_count = 0;
132050 + unsigned long next_addr = PAGE_SIZE, populate;
132051 +
132052 + /* error checking to ensure values copied from user space are valid */
132053 + if (i->len % PAGE_SIZE)
132054 + return -EINVAL;
132055 +
132056 + map = kmalloc(sizeof(*map), GFP_KERNEL);
132057 + if (!map)
132058 + return -ENOMEM;
132059 +
132060 + spin_lock(&mem_lock);
132061 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
132062 + list_for_each_entry(frag, &mem_list, list) {
132063 + if (frag->refs && (frag->flags &
132064 + USDPAA_DMA_FLAG_SHARE) &&
132065 + !strncmp(i->name, frag->name,
132066 + USDPAA_DMA_NAME_MAX)) {
132067 + /* Matching entry */
132068 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
132069 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
132070 + ret = -EBUSY;
132071 + goto out;
132072 + }
132073 +
132074 + /* Check to ensure size matches record */
132075 + if (i->len != frag->map_len && i->len) {
132076 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
132077 + frag->name);
132078 + return -EINVAL;
132079 + }
132080 +
132081 + /* Check if this has already been mapped
132082 + to this process */
132083 + list_for_each_entry(tmp, &ctx->maps, list)
132084 + if (tmp->root_frag == frag) {
132085 + /* Already mapped, just need to
132086 + inc ref count */
132087 + tmp->refs++;
132088 + kfree(map);
132089 + i->did_create = 0;
132090 + i->len = tmp->total_size;
132091 + i->phys_addr = frag->base;
132092 + i->ptr = tmp->virt_addr;
132093 + spin_unlock(&mem_lock);
132094 + return 0;
132095 + }
132096 + /* Matching entry - just need to map */
132097 + i->has_locking = frag->has_locking;
132098 + i->did_create = 0;
132099 + i->len = frag->map_len;
132100 + start_frag = frag;
132101 + goto do_map;
132102 + }
132103 + }
132104 + /* No matching entry */
132105 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
132106 + pr_err("ioctl_dma_map() No matching entry\n");
132107 + ret = -ENOMEM;
132108 + goto out;
132109 + }
132110 + }
132111 + /* New fragment required, size must be provided. */
132112 + if (!i->len) {
132113 + ret = -EINVAL;
132114 + goto out;
132115 + }
132116 +
132117 + /* Find one of more contiguous fragments that satisfy the total length
132118 + trying to minimize the number of fragments
132119 + compute the largest page size that the allocation could use */
132120 + largest_page = largest_page_size(i->len);
132121 + start_frag = NULL;
132122 + while (largest_page &&
132123 + largest_page <= largest_page_size(phys_size) &&
132124 + start_frag == NULL) {
132125 + /* Search the list for a frag of that size */
132126 + list_for_each_entry(frag, &mem_list, list) {
132127 + if (!frag->refs && (frag->len == largest_page)) {
132128 + /* See if the next x fragments are free
132129 + and can accomidate the size */
132130 + u32 found_size = largest_page;
132131 + next_frag = list_entry(frag->list.prev,
132132 + struct mem_fragment,
132133 + list);
132134 + /* If the fragement is too small check
132135 + if the neighbours cab support it */
132136 + while (found_size < i->len) {
132137 + if (&mem_list == &next_frag->list)
132138 + break; /* End of list */
132139 + if (next_frag->refs != 0 ||
132140 + next_frag->len == 0)
132141 + break; /* not enough space */
132142 + found_size += next_frag->len;
132143 + next_frag = list_entry(
132144 + next_frag->list.prev,
132145 + struct mem_fragment,
132146 + list);
132147 + }
132148 + if (found_size >= i->len) {
132149 + /* Success! there is enough contigous
132150 + free space */
132151 + start_frag = frag;
132152 + break;
132153 + }
132154 + }
132155 + } /* next frag loop */
132156 + /* Couldn't statisfy the request with this
132157 + largest page size, try a smaller one */
132158 + largest_page <<= 2;
132159 + }
132160 + if (start_frag == NULL) {
132161 + /* Couldn't find proper amount of space */
132162 + ret = -ENOMEM;
132163 + goto out;
132164 + }
132165 + i->did_create = 1;
132166 +do_map:
132167 + /* Verify there is sufficient space to do the mapping */
132168 + down_write(&current->mm->mmap_sem);
132169 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
132170 + up_write(&current->mm->mmap_sem);
132171 +
132172 + if (next_addr & ~PAGE_MASK) {
132173 + ret = -ENOMEM;
132174 + goto out;
132175 + }
132176 +
132177 + /* We may need to divide the final fragment to accomidate the mapping */
132178 + next_frag = start_frag;
132179 + while (so_far != i->len) {
132180 + BUG_ON(next_frag->len == 0);
132181 + while ((next_frag->len + so_far) > i->len) {
132182 + /* Split frag until they match */
132183 + split_frag(next_frag);
132184 + }
132185 + so_far += next_frag->len;
132186 + next_frag->refs++;
132187 + ++frag_count;
132188 + next_frag = list_entry(next_frag->list.prev,
132189 + struct mem_fragment, list);
132190 + }
132191 + if (i->did_create) {
132192 + size_t name_len = 0;
132193 + start_frag->flags = i->flags;
132194 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
132195 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
132196 + if (name_len >= USDPAA_DMA_NAME_MAX) {
132197 + ret = -EFAULT;
132198 + goto out;
132199 + }
132200 + start_frag->map_len = i->len;
132201 + start_frag->has_locking = i->has_locking;
132202 + init_waitqueue_head(&start_frag->wq);
132203 + start_frag->owner = NULL;
132204 + }
132205 +
132206 + /* Setup the map entry */
132207 + map->root_frag = start_frag;
132208 + map->total_size = i->len;
132209 + map->frag_count = frag_count;
132210 + map->refs = 1;
132211 + list_add(&map->list, &ctx->maps);
132212 + i->phys_addr = start_frag->base;
132213 +out:
132214 + spin_unlock(&mem_lock);
132215 +
132216 + if (!ret) {
132217 + unsigned long longret;
132218 + down_write(&current->mm->mmap_sem);
132219 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
132220 + PROT_READ |
132221 + (i->flags &
132222 + USDPAA_DMA_FLAG_RDONLY ? 0
132223 + : PROT_WRITE),
132224 + MAP_SHARED,
132225 + start_frag->pfn_base,
132226 + &populate,
132227 + NULL);
132228 + up_write(&current->mm->mmap_sem);
132229 + if (longret & ~PAGE_MASK) {
132230 + ret = (int)longret;
132231 + } else {
132232 + i->ptr = (void *)longret;
132233 + map->virt_addr = i->ptr;
132234 + }
132235 + } else
132236 + kfree(map);
132237 + return ret;
132238 +}
132239 +
132240 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
132241 +{
132242 + struct mem_mapping *map;
132243 + struct vm_area_struct *vma;
132244 + int ret, i;
132245 + struct mem_fragment *current_frag;
132246 + size_t sz;
132247 + unsigned long base;
132248 + unsigned long vaddr;
132249 +
132250 + down_write(&current->mm->mmap_sem);
132251 + vma = find_vma(current->mm, (unsigned long)arg);
132252 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
132253 + up_write(&current->mm->mmap_sem);
132254 + return -EFAULT;
132255 + }
132256 + spin_lock(&mem_lock);
132257 + list_for_each_entry(map, &ctx->maps, list) {
132258 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
132259 + /* Drop the map lock if we hold it */
132260 + if (map->root_frag->has_locking &&
132261 + (map->root_frag->owner == map)) {
132262 + map->root_frag->owner = NULL;
132263 + wake_up(&map->root_frag->wq);
132264 + }
132265 + goto map_match;
132266 + }
132267 + }
132268 + /* Failed to find a matching mapping for this process */
132269 + ret = -EFAULT;
132270 + spin_unlock(&mem_lock);
132271 + goto out;
132272 +map_match:
132273 + map->refs--;
132274 + if (map->refs != 0) {
132275 + /* Another call the dma_map is referencing this */
132276 + ret = 0;
132277 + spin_unlock(&mem_lock);
132278 + goto out;
132279 + }
132280 +
132281 + current_frag = map->root_frag;
132282 + vaddr = (unsigned long) map->virt_addr;
132283 + for (i = 0; i < map->frag_count; i++) {
132284 + DPA_ASSERT(current_frag->refs > 0);
132285 + --current_frag->refs;
132286 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
132287 + /*
132288 + * Make sure we invalidate the TLB entry for
132289 + * this fragment, otherwise a remap of a different
132290 + * page to this vaddr would give acces to an
132291 + * incorrect piece of memory
132292 + */
132293 + cleartlbcam(vaddr, mfspr(SPRN_PID));
132294 +#endif
132295 + vaddr += current_frag->len;
132296 + current_frag = list_entry(current_frag->list.prev,
132297 + struct mem_fragment, list);
132298 + }
132299 + map->root_frag->name[0] = 0;
132300 + list_del(&map->list);
132301 + compress_frags();
132302 + spin_unlock(&mem_lock);
132303 +
132304 + base = vma->vm_start;
132305 + sz = vma->vm_end - vma->vm_start;
132306 + do_munmap(current->mm, base, sz, NULL);
132307 + ret = 0;
132308 + out:
132309 + up_write(&current->mm->mmap_sem);
132310 + return ret;
132311 +}
132312 +
132313 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
132314 +{
132315 + struct mem_fragment *frag;
132316 + struct usdpaa_ioctl_dma_used result;
132317 +
132318 + result.free_bytes = 0;
132319 + result.total_bytes = phys_size;
132320 +
132321 + list_for_each_entry(frag, &mem_list, list) {
132322 + if (frag->refs == 0)
132323 + result.free_bytes += frag->len;
132324 + }
132325 +
132326 + return copy_to_user(arg, &result, sizeof(result)); }
132327 +
132328 +static int test_lock(struct mem_mapping *map)
132329 +{
132330 + int ret = 0;
132331 + spin_lock(&mem_lock);
132332 + if (!map->root_frag->owner) {
132333 + map->root_frag->owner = map;
132334 + ret = 1;
132335 + }
132336 + spin_unlock(&mem_lock);
132337 + return ret;
132338 +}
132339 +
132340 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
132341 +{
132342 + struct mem_mapping *map;
132343 + struct vm_area_struct *vma;
132344 +
132345 + down_read(&current->mm->mmap_sem);
132346 + vma = find_vma(current->mm, (unsigned long)arg);
132347 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
132348 + up_read(&current->mm->mmap_sem);
132349 + return -EFAULT;
132350 + }
132351 + spin_lock(&mem_lock);
132352 + list_for_each_entry(map, &ctx->maps, list) {
132353 + if (map->root_frag->pfn_base == vma->vm_pgoff)
132354 + goto map_match;
132355 + }
132356 + map = NULL;
132357 +map_match:
132358 + spin_unlock(&mem_lock);
132359 + up_read(&current->mm->mmap_sem);
132360 +
132361 + if (!map)
132362 + return -EFAULT;
132363 + if (!map->root_frag->has_locking)
132364 + return -ENODEV;
132365 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
132366 +}
132367 +
132368 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
132369 +{
132370 + struct mem_mapping *map;
132371 + struct vm_area_struct *vma;
132372 + int ret;
132373 +
132374 + down_read(&current->mm->mmap_sem);
132375 + vma = find_vma(current->mm, (unsigned long)arg);
132376 + if (!vma || (vma->vm_start > (unsigned long)arg))
132377 + ret = -EFAULT;
132378 + else {
132379 + spin_lock(&mem_lock);
132380 + list_for_each_entry(map, &ctx->maps, list) {
132381 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
132382 + if (!map->root_frag->has_locking)
132383 + ret = -ENODEV;
132384 + else if (map->root_frag->owner == map) {
132385 + map->root_frag->owner = NULL;
132386 + wake_up(&map->root_frag->wq);
132387 + ret = 0;
132388 + } else
132389 + ret = -EBUSY;
132390 + goto map_match;
132391 + }
132392 + }
132393 + ret = -EINVAL;
132394 +map_match:
132395 + spin_unlock(&mem_lock);
132396 + }
132397 + up_read(&current->mm->mmap_sem);
132398 + return ret;
132399 +}
132400 +
132401 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
132402 +{
132403 + unsigned long longret = 0, populate;
132404 + resource_size_t len;
132405 +
132406 + down_write(&current->mm->mmap_sem);
132407 + len = resource_size(res);
132408 + if (len != (unsigned long)len)
132409 + return -EINVAL;
132410 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
132411 + PROT_READ | PROT_WRITE, MAP_SHARED,
132412 + res->start >> PAGE_SHIFT, &populate, NULL);
132413 + up_write(&current->mm->mmap_sem);
132414 +
132415 + if (longret & ~PAGE_MASK)
132416 + return (int)longret;
132417 +
132418 + *ptr = (void *) longret;
132419 + return 0;
132420 +}
132421 +
132422 +static void portal_munmap(struct resource *res, void *ptr)
132423 +{
132424 + down_write(&current->mm->mmap_sem);
132425 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res), NULL);
132426 + up_write(&current->mm->mmap_sem);
132427 +}
132428 +
132429 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
132430 + struct usdpaa_ioctl_portal_map *arg)
132431 +{
132432 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
132433 + int ret;
132434 +
132435 + if (!mapping)
132436 + return -ENOMEM;
132437 +
132438 + mapping->user = *arg;
132439 + mapping->iommu_domain = NULL;
132440 +
132441 + if (mapping->user.type == usdpaa_portal_qman) {
132442 + mapping->qportal =
132443 + qm_get_unused_portal_idx(mapping->user.index);
132444 + if (!mapping->qportal) {
132445 + ret = -ENODEV;
132446 + goto err_get_portal;
132447 + }
132448 + mapping->phys = &mapping->qportal->addr_phys[0];
132449 + mapping->user.channel = mapping->qportal->public_cfg.channel;
132450 + mapping->user.pools = mapping->qportal->public_cfg.pools;
132451 + mapping->user.index = mapping->qportal->public_cfg.index;
132452 + } else if (mapping->user.type == usdpaa_portal_bman) {
132453 + mapping->bportal =
132454 + bm_get_unused_portal_idx(mapping->user.index);
132455 + if (!mapping->bportal) {
132456 + ret = -ENODEV;
132457 + goto err_get_portal;
132458 + }
132459 + mapping->phys = &mapping->bportal->addr_phys[0];
132460 + mapping->user.index = mapping->bportal->public_cfg.index;
132461 + } else {
132462 + ret = -EINVAL;
132463 + goto err_copy_from_user;
132464 + }
132465 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
132466 + * handlers look it up. */
132467 + spin_lock(&mem_lock);
132468 + list_add(&mapping->list, &ctx->portals);
132469 + spin_unlock(&mem_lock);
132470 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
132471 + &mapping->user.addr.cena);
132472 + if (ret)
132473 + goto err_mmap_cena;
132474 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
132475 + &mapping->user.addr.cinh);
132476 + if (ret)
132477 + goto err_mmap_cinh;
132478 + *arg = mapping->user;
132479 + return ret;
132480 +
132481 +err_mmap_cinh:
132482 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
132483 +err_mmap_cena:
132484 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
132485 + qm_put_unused_portal(mapping->qportal);
132486 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
132487 + bm_put_unused_portal(mapping->bportal);
132488 + spin_lock(&mem_lock);
132489 + list_del(&mapping->list);
132490 + spin_unlock(&mem_lock);
132491 +err_get_portal:
132492 +err_copy_from_user:
132493 + kfree(mapping);
132494 + return ret;
132495 +}
132496 +
132497 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
132498 +{
132499 + struct portal_mapping *mapping;
132500 + struct vm_area_struct *vma;
132501 + unsigned long pfn;
132502 + u32 channel;
132503 +
132504 + /* Get the PFN corresponding to one of the virt addresses */
132505 + down_read(&current->mm->mmap_sem);
132506 + vma = find_vma(current->mm, (unsigned long)i->cinh);
132507 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
132508 + up_read(&current->mm->mmap_sem);
132509 + return -EFAULT;
132510 + }
132511 + pfn = vma->vm_pgoff;
132512 + up_read(&current->mm->mmap_sem);
132513 +
132514 + /* Find the corresponding portal */
132515 + spin_lock(&mem_lock);
132516 + list_for_each_entry(mapping, &ctx->portals, list) {
132517 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
132518 + goto found;
132519 + }
132520 + mapping = NULL;
132521 +found:
132522 + if (mapping)
132523 + list_del(&mapping->list);
132524 + spin_unlock(&mem_lock);
132525 + if (!mapping)
132526 + return -ENODEV;
132527 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
132528 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
132529 + if (mapping->user.type == usdpaa_portal_qman) {
132530 + init_qm_portal(mapping->qportal,
132531 + &mapping->qman_portal_low);
132532 +
132533 + /* Tear down any FQs this portal is referencing */
132534 + channel = mapping->qportal->public_cfg.channel;
132535 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
132536 + &channel,
132537 + check_portal_channel);
132538 + qm_put_unused_portal(mapping->qportal);
132539 + } else if (mapping->user.type == usdpaa_portal_bman) {
132540 + init_bm_portal(mapping->bportal,
132541 + &mapping->bman_portal_low);
132542 + bm_put_unused_portal(mapping->bportal);
132543 + }
132544 + kfree(mapping);
132545 + return 0;
132546 +}
132547 +
132548 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
132549 + uint32_t cpu, uint32_t cache, uint32_t window)
132550 +{
132551 +#ifdef CONFIG_FSL_PAMU
132552 + int ret;
132553 + int window_count = 1;
132554 + struct iommu_domain_geometry geom_attr;
132555 + struct pamu_stash_attribute stash_attr;
132556 +
132557 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
132558 + if (!pcfg->iommu_domain) {
132559 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
132560 + __func__);
132561 + goto _no_iommu;
132562 + }
132563 + geom_attr.aperture_start = 0;
132564 + geom_attr.aperture_end =
132565 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
132566 + geom_attr.force_aperture = true;
132567 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
132568 + &geom_attr);
132569 + if (ret < 0) {
132570 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132571 + __func__, ret);
132572 + goto _iommu_domain_free;
132573 + }
132574 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
132575 + &window_count);
132576 + if (ret < 0) {
132577 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132578 + __func__, ret);
132579 + goto _iommu_domain_free;
132580 + }
132581 + stash_attr.cpu = cpu;
132582 + stash_attr.cache = cache;
132583 + /* set stash information for the window */
132584 + stash_attr.window = 0;
132585 +
132586 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
132587 + DOMAIN_ATTR_FSL_PAMU_STASH,
132588 + &stash_attr);
132589 + if (ret < 0) {
132590 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132591 + __func__, ret);
132592 + goto _iommu_domain_free;
132593 + }
132594 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
132595 + IOMMU_READ | IOMMU_WRITE);
132596 + if (ret < 0) {
132597 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
132598 + __func__, ret);
132599 + goto _iommu_domain_free;
132600 + }
132601 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
132602 + if (ret < 0) {
132603 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
132604 + __func__, ret);
132605 + goto _iommu_domain_free;
132606 + }
132607 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
132608 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
132609 + &window_count);
132610 + if (ret < 0) {
132611 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132612 + __func__, ret);
132613 + goto _iommu_detach_device;
132614 + }
132615 +_no_iommu:
132616 +#endif
132617 +
132618 +#ifdef CONFIG_FSL_QMAN_CONFIG
132619 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
132620 +#endif
132621 + pr_warn("Failed to set QMan portal's stash request queue\n");
132622 +
132623 + return;
132624 +
132625 +#ifdef CONFIG_FSL_PAMU
132626 +_iommu_detach_device:
132627 + iommu_detach_device(pcfg->iommu_domain, NULL);
132628 +_iommu_domain_free:
132629 + iommu_domain_free(pcfg->iommu_domain);
132630 +#endif
132631 +}
132632 +
132633 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
132634 + struct usdpaa_ioctl_raw_portal *arg)
132635 +{
132636 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
132637 + int ret;
132638 +
132639 + if (!mapping)
132640 + return -ENOMEM;
132641 +
132642 + mapping->user.type = arg->type;
132643 + mapping->iommu_domain = NULL;
132644 + if (arg->type == usdpaa_portal_qman) {
132645 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
132646 + if (!mapping->qportal) {
132647 + ret = -ENODEV;
132648 + goto err;
132649 + }
132650 + mapping->phys = &mapping->qportal->addr_phys[0];
132651 + arg->index = mapping->qportal->public_cfg.index;
132652 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
132653 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
132654 + if (arg->enable_stash) {
132655 + /* Setup the PAMU with the supplied parameters */
132656 + portal_config_pamu(mapping->qportal, arg->sdest,
132657 + arg->cpu, arg->cache, arg->window);
132658 + }
132659 + } else if (mapping->user.type == usdpaa_portal_bman) {
132660 + mapping->bportal =
132661 + bm_get_unused_portal_idx(arg->index);
132662 + if (!mapping->bportal) {
132663 + ret = -ENODEV;
132664 + goto err;
132665 + }
132666 + mapping->phys = &mapping->bportal->addr_phys[0];
132667 + arg->index = mapping->bportal->public_cfg.index;
132668 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
132669 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
132670 + } else {
132671 + ret = -EINVAL;
132672 + goto err;
132673 + }
132674 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
132675 + * handlers look it up. */
132676 + spin_lock(&mem_lock);
132677 + list_add(&mapping->list, &ctx->portals);
132678 + spin_unlock(&mem_lock);
132679 + return 0;
132680 +err:
132681 + kfree(mapping);
132682 + return ret;
132683 +}
132684 +
132685 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
132686 + struct usdpaa_ioctl_raw_portal *arg)
132687 +{
132688 + struct portal_mapping *mapping;
132689 + u32 channel;
132690 +
132691 + /* Find the corresponding portal */
132692 + spin_lock(&mem_lock);
132693 + list_for_each_entry(mapping, &ctx->portals, list) {
132694 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
132695 + goto found;
132696 + }
132697 + mapping = NULL;
132698 +found:
132699 + if (mapping)
132700 + list_del(&mapping->list);
132701 + spin_unlock(&mem_lock);
132702 + if (!mapping)
132703 + return -ENODEV;
132704 + if (mapping->user.type == usdpaa_portal_qman) {
132705 + init_qm_portal(mapping->qportal,
132706 + &mapping->qman_portal_low);
132707 +
132708 + /* Tear down any FQs this portal is referencing */
132709 + channel = mapping->qportal->public_cfg.channel;
132710 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
132711 + &channel,
132712 + check_portal_channel);
132713 + qm_put_unused_portal(mapping->qportal);
132714 + } else if (mapping->user.type == usdpaa_portal_bman) {
132715 + init_bm_portal(mapping->bportal,
132716 + &mapping->bman_portal_low);
132717 + bm_put_unused_portal(mapping->bportal);
132718 + }
132719 + kfree(mapping);
132720 + return 0;
132721 +}
132722 +
132723 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
132724 +{
132725 + struct ctx *ctx = fp->private_data;
132726 + void __user *a = (void __user *)arg;
132727 + switch (cmd) {
132728 + case USDPAA_IOCTL_ID_ALLOC:
132729 + return ioctl_id_alloc(ctx, a);
132730 + case USDPAA_IOCTL_ID_RELEASE:
132731 + return ioctl_id_release(ctx, a);
132732 + case USDPAA_IOCTL_ID_RESERVE:
132733 + return ioctl_id_reserve(ctx, a);
132734 + case USDPAA_IOCTL_DMA_MAP:
132735 + {
132736 + struct usdpaa_ioctl_dma_map input;
132737 + int ret;
132738 + if (copy_from_user(&input, a, sizeof(input)))
132739 + return -EFAULT;
132740 + ret = ioctl_dma_map(fp, ctx, &input);
132741 + if (copy_to_user(a, &input, sizeof(input)))
132742 + return -EFAULT;
132743 + return ret;
132744 + }
132745 + case USDPAA_IOCTL_DMA_UNMAP:
132746 + return ioctl_dma_unmap(ctx, a);
132747 + case USDPAA_IOCTL_DMA_LOCK:
132748 + return ioctl_dma_lock(ctx, a);
132749 + case USDPAA_IOCTL_DMA_UNLOCK:
132750 + return ioctl_dma_unlock(ctx, a);
132751 + case USDPAA_IOCTL_PORTAL_MAP:
132752 + {
132753 + struct usdpaa_ioctl_portal_map input;
132754 + int ret;
132755 + if (copy_from_user(&input, a, sizeof(input)))
132756 + return -EFAULT;
132757 + ret = ioctl_portal_map(fp, ctx, &input);
132758 + if (copy_to_user(a, &input, sizeof(input)))
132759 + return -EFAULT;
132760 + return ret;
132761 + }
132762 + case USDPAA_IOCTL_PORTAL_UNMAP:
132763 + {
132764 + struct usdpaa_portal_map input;
132765 + if (copy_from_user(&input, a, sizeof(input)))
132766 + return -EFAULT;
132767 + return ioctl_portal_unmap(ctx, &input);
132768 + }
132769 + case USDPAA_IOCTL_DMA_USED:
132770 + return ioctl_dma_stats(ctx, a);
132771 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
132772 + {
132773 + struct usdpaa_ioctl_raw_portal input;
132774 + int ret;
132775 + if (copy_from_user(&input, a, sizeof(input)))
132776 + return -EFAULT;
132777 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
132778 + if (copy_to_user(a, &input, sizeof(input)))
132779 + return -EFAULT;
132780 + return ret;
132781 + }
132782 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
132783 + {
132784 + struct usdpaa_ioctl_raw_portal input;
132785 + if (copy_from_user(&input, a, sizeof(input)))
132786 + return -EFAULT;
132787 + return ioctl_free_raw_portal(fp, ctx, &input);
132788 + }
132789 + }
132790 + return -EINVAL;
132791 +}
132792 +
132793 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
132794 + unsigned long arg)
132795 +{
132796 +#ifdef CONFIG_COMPAT
132797 + struct ctx *ctx = fp->private_data;
132798 + void __user *a = (void __user *)arg;
132799 +#endif
132800 + switch (cmd) {
132801 +#ifdef CONFIG_COMPAT
132802 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
132803 + {
132804 + int ret;
132805 + struct usdpaa_ioctl_dma_map_compat input;
132806 + struct usdpaa_ioctl_dma_map converted;
132807 +
132808 + if (copy_from_user(&input, a, sizeof(input)))
132809 + return -EFAULT;
132810 +
132811 + converted.ptr = compat_ptr(input.ptr);
132812 + converted.phys_addr = input.phys_addr;
132813 + converted.len = input.len;
132814 + converted.flags = input.flags;
132815 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
132816 + converted.has_locking = input.has_locking;
132817 + converted.did_create = input.did_create;
132818 +
132819 + ret = ioctl_dma_map(fp, ctx, &converted);
132820 + input.ptr = ptr_to_compat(converted.ptr);
132821 + input.phys_addr = converted.phys_addr;
132822 + input.len = converted.len;
132823 + input.flags = converted.flags;
132824 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
132825 + input.has_locking = converted.has_locking;
132826 + input.did_create = converted.did_create;
132827 + if (copy_to_user(a, &input, sizeof(input)))
132828 + return -EFAULT;
132829 + return ret;
132830 + }
132831 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
132832 + {
132833 + int ret;
132834 + struct compat_usdpaa_ioctl_portal_map input;
132835 + struct usdpaa_ioctl_portal_map converted;
132836 + if (copy_from_user(&input, a, sizeof(input)))
132837 + return -EFAULT;
132838 + converted.type = input.type;
132839 + converted.index = input.index;
132840 + ret = ioctl_portal_map(fp, ctx, &converted);
132841 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
132842 + input.addr.cena = ptr_to_compat(converted.addr.cena);
132843 + input.channel = converted.channel;
132844 + input.pools = converted.pools;
132845 + input.index = converted.index;
132846 + if (copy_to_user(a, &input, sizeof(input)))
132847 + return -EFAULT;
132848 + return ret;
132849 + }
132850 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
132851 + {
132852 + struct usdpaa_portal_map_compat input;
132853 + struct usdpaa_portal_map converted;
132854 +
132855 + if (copy_from_user(&input, a, sizeof(input)))
132856 + return -EFAULT;
132857 + converted.cinh = compat_ptr(input.cinh);
132858 + converted.cena = compat_ptr(input.cena);
132859 + return ioctl_portal_unmap(ctx, &converted);
132860 + }
132861 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
132862 + {
132863 + int ret;
132864 + struct usdpaa_ioctl_raw_portal converted;
132865 + struct compat_ioctl_raw_portal input;
132866 + if (copy_from_user(&input, a, sizeof(input)))
132867 + return -EFAULT;
132868 + converted.type = input.type;
132869 + converted.index = input.index;
132870 + converted.enable_stash = input.enable_stash;
132871 + converted.cpu = input.cpu;
132872 + converted.cache = input.cache;
132873 + converted.window = input.window;
132874 + converted.sdest = input.sdest;
132875 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
132876 +
132877 + input.cinh = converted.cinh;
132878 + input.cena = converted.cena;
132879 + input.index = converted.index;
132880 +
132881 + if (copy_to_user(a, &input, sizeof(input)))
132882 + return -EFAULT;
132883 + return ret;
132884 + }
132885 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
132886 + {
132887 + struct usdpaa_ioctl_raw_portal converted;
132888 + struct compat_ioctl_raw_portal input;
132889 + if (copy_from_user(&input, a, sizeof(input)))
132890 + return -EFAULT;
132891 + converted.type = input.type;
132892 + converted.index = input.index;
132893 + converted.cinh = input.cinh;
132894 + converted.cena = input.cena;
132895 + return ioctl_free_raw_portal(fp, ctx, &converted);
132896 + }
132897 +#endif
132898 + default:
132899 + return usdpaa_ioctl(fp, cmd, arg);
132900 + }
132901 + return -EINVAL;
132902 +}
132903 +
132904 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
132905 + enum usdpaa_portal_type ptype, unsigned int *irq,
132906 + void **iir_reg)
132907 +{
132908 + /* Walk the list of portals for filp and return the config
132909 + for the portal that matches the hint */
132910 + struct ctx *context;
132911 + struct portal_mapping *portal;
132912 +
132913 + /* First sanitize the filp */
132914 + if (filp->f_op->open != usdpaa_open)
132915 + return -ENODEV;
132916 + context = filp->private_data;
132917 + spin_lock(&context->lock);
132918 + list_for_each_entry(portal, &context->portals, list) {
132919 + if (portal->user.type == ptype &&
132920 + portal->user.addr.cinh == cinh) {
132921 + if (ptype == usdpaa_portal_qman) {
132922 + *irq = portal->qportal->public_cfg.irq;
132923 + *iir_reg = portal->qportal->addr_virt[1] +
132924 + QM_REG_IIR;
132925 + } else {
132926 + *irq = portal->bportal->public_cfg.irq;
132927 + *iir_reg = portal->bportal->addr_virt[1] +
132928 + BM_REG_IIR;
132929 + }
132930 + spin_unlock(&context->lock);
132931 + return 0;
132932 + }
132933 + }
132934 + spin_unlock(&context->lock);
132935 + return -EINVAL;
132936 +}
132937 +
132938 +static const struct file_operations usdpaa_fops = {
132939 + .open = usdpaa_open,
132940 + .release = usdpaa_release,
132941 + .mmap = usdpaa_mmap,
132942 + .get_unmapped_area = usdpaa_get_unmapped_area,
132943 + .unlocked_ioctl = usdpaa_ioctl,
132944 + .compat_ioctl = usdpaa_ioctl_compat
132945 +};
132946 +
132947 +static struct miscdevice usdpaa_miscdev = {
132948 + .name = "fsl-usdpaa",
132949 + .fops = &usdpaa_fops,
132950 + .minor = MISC_DYNAMIC_MINOR,
132951 +};
132952 +
132953 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
132954 + * indicate how much memory (if any) to allocate during early boot. If the
132955 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
132956 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
132957 + * than there are TLB1 entries, fault-handling will occur. */
132958 +
132959 +static __init int usdpaa_mem(char *arg)
132960 +{
132961 + pr_warn("uspdaa_mem argument is depracated\n");
132962 + arg_phys_size = memparse(arg, &arg);
132963 + num_tlb = 1;
132964 + if (*arg == ',') {
132965 + unsigned long ul;
132966 + int err = kstrtoul(arg + 1, 0, &ul);
132967 + if (err < 0) {
132968 + num_tlb = 1;
132969 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
132970 + } else
132971 + num_tlb = (unsigned int)ul;
132972 + }
132973 + return 0;
132974 +}
132975 +early_param("usdpaa_mem", usdpaa_mem);
132976 +
132977 +static int usdpaa_mem_init(struct reserved_mem *rmem)
132978 +{
132979 + phys_start = rmem->base;
132980 + phys_size = rmem->size;
132981 +
132982 + WARN_ON(!(phys_start && phys_size));
132983 +
132984 + return 0;
132985 +}
132986 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
132987 +
132988 +__init int fsl_usdpaa_init_early(void)
132989 +{
132990 + if (!phys_size || !phys_start) {
132991 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
132992 + return 0;
132993 + }
132994 + if (phys_size % PAGE_SIZE) {
132995 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
132996 + phys_size = 0;
132997 + return 0;
132998 + }
132999 + if (arg_phys_size && phys_size != arg_phys_size) {
133000 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
133001 + arg_phys_size, phys_size);
133002 + phys_size = 0;
133003 + return 0;
133004 + }
133005 + pfn_start = phys_start >> PAGE_SHIFT;
133006 + pfn_size = phys_size >> PAGE_SHIFT;
133007 +#ifdef CONFIG_PPC
133008 + first_tlb = current_tlb = tlbcam_index;
133009 + tlbcam_index += num_tlb;
133010 +#endif
133011 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
133012 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
133013 + return 0;
133014 +}
133015 +subsys_initcall(fsl_usdpaa_init_early);
133016 +
133017 +
133018 +static int __init usdpaa_init(void)
133019 +{
133020 + struct mem_fragment *frag;
133021 + int ret;
133022 + u64 tmp_size = phys_size;
133023 + u64 tmp_start = phys_start;
133024 + u64 tmp_pfn_size = pfn_size;
133025 + u64 tmp_pfn_start = pfn_start;
133026 +
133027 + pr_info("Freescale USDPAA process driver\n");
133028 + if (!phys_start) {
133029 + pr_warn("fsl-usdpaa: no region found\n");
133030 + return 0;
133031 + }
133032 +
133033 + while (tmp_size != 0) {
133034 + u32 frag_size = largest_page_size(tmp_size);
133035 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
133036 + if (!frag) {
133037 + pr_err("Failed to setup USDPAA memory accounting\n");
133038 + return -ENOMEM;
133039 + }
133040 + frag->base = tmp_start;
133041 + frag->len = frag->root_len = frag_size;
133042 + frag->root_pfn = tmp_pfn_start;
133043 + frag->pfn_base = tmp_pfn_start;
133044 + frag->pfn_len = frag_size / PAGE_SIZE;
133045 + frag->refs = 0;
133046 + init_waitqueue_head(&frag->wq);
133047 + frag->owner = NULL;
133048 + list_add(&frag->list, &mem_list);
133049 +
133050 + /* Adjust for this frag */
133051 + tmp_start += frag_size;
133052 + tmp_size -= frag_size;
133053 + tmp_pfn_start += frag_size / PAGE_SIZE;
133054 + tmp_pfn_size -= frag_size / PAGE_SIZE;
133055 + }
133056 + ret = misc_register(&usdpaa_miscdev);
133057 + if (ret)
133058 + pr_err("fsl-usdpaa: failed to register misc device\n");
133059 + return ret;
133060 +}
133061 +
133062 +static void __exit usdpaa_exit(void)
133063 +{
133064 + misc_deregister(&usdpaa_miscdev);
133065 +}
133066 +
133067 +module_init(usdpaa_init);
133068 +module_exit(usdpaa_exit);
133069 +
133070 +MODULE_LICENSE("GPL");
133071 +MODULE_AUTHOR("Freescale Semiconductor");
133072 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
133073 --- /dev/null
133074 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
133075 @@ -0,0 +1,289 @@
133076 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
133077 + * All rights reserved.
133078 + *
133079 + * Redistribution and use in source and binary forms, with or without
133080 + * modification, are permitted provided that the following conditions are met:
133081 + * * Redistributions of source code must retain the above copyright
133082 + * notice, this list of conditions and the following disclaimer.
133083 + * * Redistributions in binary form must reproduce the above copyright
133084 + * notice, this list of conditions and the following disclaimer in the
133085 + * documentation and/or other materials provided with the distribution.
133086 + * * Neither the name of Freescale Semiconductor nor the
133087 + * names of its contributors may be used to endorse or promote products
133088 + * derived from this software without specific prior written permission.
133089 + *
133090 + *
133091 + * ALTERNATIVELY, this software may be distributed under the terms of the
133092 + * GNU General Public License ("GPL") as published by the Free Software
133093 + * Foundation, either version 2 of that License or (at your option) any
133094 + * later version.
133095 + *
133096 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133097 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133098 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133099 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133100 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133101 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133103 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133104 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133105 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133106 + */
133107 +
133108 +/* define a device that allows USPDAA processes to open a file
133109 + descriptor and specify which IRQ it wants to montior using an ioctl()
133110 + When an IRQ is received, the device becomes readable so that a process
133111 + can use read() or select() type calls to monitor for IRQs */
133112 +
133113 +#include <linux/miscdevice.h>
133114 +#include <linux/fs.h>
133115 +#include <linux/cdev.h>
133116 +#include <linux/slab.h>
133117 +#include <linux/interrupt.h>
133118 +#include <linux/poll.h>
133119 +#include <linux/uaccess.h>
133120 +#include <linux/fsl_usdpaa.h>
133121 +#include <linux/module.h>
133122 +#include <linux/fdtable.h>
133123 +#include <linux/file.h>
133124 +
133125 +#include "qman_low.h"
133126 +#include "bman_low.h"
133127 +
133128 +struct usdpaa_irq_ctx {
133129 + int irq_set; /* Set to true once the irq is set via ioctl */
133130 + unsigned int irq_num;
133131 + u32 last_irq_count; /* Last value returned from read */
133132 + u32 irq_count; /* Number of irqs since last read */
133133 + wait_queue_head_t wait_queue; /* Waiting processes */
133134 + spinlock_t lock;
133135 + void *inhibit_addr; /* inhibit register address */
133136 + struct file *usdpaa_filp;
133137 + char irq_name[128];
133138 +};
133139 +
133140 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
133141 +{
133142 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
133143 + if (!ctx)
133144 + return -ENOMEM;
133145 + ctx->irq_set = 0;
133146 + ctx->irq_count = 0;
133147 + ctx->last_irq_count = 0;
133148 + init_waitqueue_head(&ctx->wait_queue);
133149 + spin_lock_init(&ctx->lock);
133150 + filp->private_data = ctx;
133151 + return 0;
133152 +}
133153 +
133154 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
133155 +{
133156 + struct usdpaa_irq_ctx *ctx = filp->private_data;
133157 + if (ctx->irq_set) {
133158 + /* Inhibit the IRQ */
133159 + out_be32(ctx->inhibit_addr, 0x1);
133160 + irq_set_affinity_hint(ctx->irq_num, NULL);
133161 + free_irq(ctx->irq_num, ctx);
133162 + ctx->irq_set = 0;
133163 + fput(ctx->usdpaa_filp);
133164 + }
133165 + kfree(filp->private_data);
133166 + return 0;
133167 +}
133168 +
133169 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
133170 +{
133171 + unsigned long flags;
133172 + struct usdpaa_irq_ctx *ctx = _ctx;
133173 + spin_lock_irqsave(&ctx->lock, flags);
133174 + ++ctx->irq_count;
133175 + spin_unlock_irqrestore(&ctx->lock, flags);
133176 + wake_up_all(&ctx->wait_queue);
133177 + /* Set the inhibit register. This will be reenabled
133178 + once the USDPAA code handles the IRQ */
133179 + out_be32(ctx->inhibit_addr, 0x1);
133180 + pr_debug("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
133181 + return IRQ_HANDLED;
133182 +}
133183 +
133184 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
133185 +{
133186 + struct usdpaa_irq_ctx *ctx = fp->private_data;
133187 + int ret;
133188 +
133189 + if (ctx->irq_set) {
133190 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
133191 + return -EBUSY;
133192 + }
133193 +
133194 + ctx->usdpaa_filp = fget(irq_map->fd);
133195 + if (!ctx->usdpaa_filp) {
133196 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
133197 + return -EINVAL;
133198 + }
133199 +
133200 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
133201 + irq_map->type, &ctx->irq_num,
133202 + &ctx->inhibit_addr);
133203 + if (ret) {
133204 + pr_debug("USDPAA IRQ couldn't identify portal\n");
133205 + fput(ctx->usdpaa_filp);
133206 + return ret;
133207 + }
133208 +
133209 + ctx->irq_set = 1;
133210 +
133211 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
133212 + "usdpaa_irq %d", ctx->irq_num);
133213 +
133214 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
133215 + ctx->irq_name, ctx);
133216 + if (ret) {
133217 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
133218 + ctx->irq_num, ret);
133219 + ctx->irq_set = 0;
133220 + fput(ctx->usdpaa_filp);
133221 + return ret;
133222 + }
133223 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
133224 + if (ret)
133225 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
133226 +
133227 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
133228 + if (ret)
133229 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
133230 +
133231 + return 0;
133232 +}
133233 +
133234 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
133235 + unsigned long arg)
133236 +{
133237 + int ret;
133238 + struct usdpaa_ioctl_irq_map irq_map;
133239 +
133240 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
133241 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
133242 + return -EINVAL;
133243 + }
133244 +
133245 + ret = copy_from_user(&irq_map, (void __user *)arg,
133246 + sizeof(irq_map));
133247 + if (ret)
133248 + return ret;
133249 + return map_irq(fp, &irq_map);
133250 +}
133251 +
133252 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
133253 + size_t count, loff_t *offp)
133254 +{
133255 + struct usdpaa_irq_ctx *ctx = filp->private_data;
133256 + int ret;
133257 +
133258 + if (!ctx->irq_set) {
133259 + pr_debug("Reading USDPAA IRQ before it was set\n");
133260 + return -EINVAL;
133261 + }
133262 +
133263 + if (count < sizeof(ctx->irq_count)) {
133264 + pr_debug("USDPAA IRQ Read too small\n");
133265 + return -EINVAL;
133266 + }
133267 + if (ctx->irq_count == ctx->last_irq_count) {
133268 + if (filp->f_flags & O_NONBLOCK)
133269 + return -EAGAIN;
133270 +
133271 + ret = wait_event_interruptible(ctx->wait_queue,
133272 + ctx->irq_count != ctx->last_irq_count);
133273 + if (ret == -ERESTARTSYS)
133274 + return ret;
133275 + }
133276 +
133277 + ctx->last_irq_count = ctx->irq_count;
133278 +
133279 + if (copy_to_user(buff, &ctx->last_irq_count,
133280 + sizeof(ctx->last_irq_count)))
133281 + return -EFAULT;
133282 + return sizeof(ctx->irq_count);
133283 +}
133284 +
133285 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
133286 +{
133287 + struct usdpaa_irq_ctx *ctx = filp->private_data;
133288 + unsigned int ret = 0;
133289 + unsigned long flags;
133290 +
133291 + if (!ctx->irq_set)
133292 + return POLLHUP;
133293 +
133294 + poll_wait(filp, &ctx->wait_queue, wait);
133295 +
133296 + spin_lock_irqsave(&ctx->lock, flags);
133297 + if (ctx->irq_count != ctx->last_irq_count)
133298 + ret |= POLLIN | POLLRDNORM;
133299 + spin_unlock_irqrestore(&ctx->lock, flags);
133300 + return ret;
133301 +}
133302 +
133303 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
133304 + unsigned long arg)
133305 +{
133306 +#ifdef CONFIG_COMPAT
133307 + void __user *a = (void __user *)arg;
133308 +#endif
133309 + switch (cmd) {
133310 +#ifdef CONFIG_COMPAT
133311 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
133312 + {
133313 + struct compat_ioctl_irq_map input;
133314 + struct usdpaa_ioctl_irq_map converted;
133315 + if (copy_from_user(&input, a, sizeof(input)))
133316 + return -EFAULT;
133317 + converted.type = input.type;
133318 + converted.fd = input.fd;
133319 + converted.portal_cinh = compat_ptr(input.portal_cinh);
133320 + return map_irq(fp, &converted);
133321 + }
133322 +#endif
133323 + default:
133324 + return usdpaa_irq_ioctl(fp, cmd, arg);
133325 + }
133326 +}
133327 +
133328 +static const struct file_operations usdpaa_irq_fops = {
133329 + .open = usdpaa_irq_open,
133330 + .release = usdpaa_irq_release,
133331 + .unlocked_ioctl = usdpaa_irq_ioctl,
133332 + .compat_ioctl = usdpaa_irq_ioctl_compat,
133333 + .read = usdpaa_irq_read,
133334 + .poll = usdpaa_irq_poll
133335 +};
133336 +
133337 +static struct miscdevice usdpaa_miscdev = {
133338 + .name = "fsl-usdpaa-irq",
133339 + .fops = &usdpaa_irq_fops,
133340 + .minor = MISC_DYNAMIC_MINOR,
133341 +};
133342 +
133343 +static int __init usdpaa_irq_init(void)
133344 +{
133345 + int ret;
133346 +
133347 + pr_info("Freescale USDPAA process IRQ driver\n");
133348 + ret = misc_register(&usdpaa_miscdev);
133349 + if (ret)
133350 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
133351 + return ret;
133352 +}
133353 +
133354 +static void __exit usdpaa_irq_exit(void)
133355 +{
133356 + misc_deregister(&usdpaa_miscdev);
133357 +}
133358 +
133359 +module_init(usdpaa_irq_init);
133360 +module_exit(usdpaa_irq_exit);
133361 +
133362 +MODULE_LICENSE("GPL");
133363 +MODULE_AUTHOR("Freescale Semiconductor");
133364 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
133365 --- /dev/null
133366 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
133367 @@ -0,0 +1,88 @@
133368 +/* Copyright 2013 Freescale Semiconductor, Inc.
133369 + *
133370 + * Redistribution and use in source and binary forms, with or without
133371 + * modification, are permitted provided that the following conditions are met:
133372 + * * Redistributions of source code must retain the above copyright
133373 + * notice, this list of conditions and the following disclaimer.
133374 + * * Redistributions in binary form must reproduce the above copyright
133375 + * notice, this list of conditions and the following disclaimer in the
133376 + * documentation and/or other materials provided with the distribution.
133377 + * * Neither the name of Freescale Semiconductor nor the
133378 + * names of its contributors may be used to endorse or promote products
133379 + * derived from this software without specific prior written permission.
133380 + *
133381 + *
133382 + * ALTERNATIVELY, this software may be distributed under the terms of the
133383 + * GNU General Public License ("GPL") as published by the Free Software
133384 + * Foundation, either version 2 of that License or (at your option) any
133385 + * later version.
133386 + *
133387 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133388 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133389 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133390 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133391 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133392 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133393 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133394 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133395 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133396 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133397 + */
133398 +
133399 +#include <linux/time.h>
133400 +#include "qman_private.h"
133401 +#include "bman_private.h"
133402 +__init void qman_init_early(void);
133403 +__init void bman_init_early(void);
133404 +
133405 +static __init int qbman_init(void)
133406 +{
133407 + struct device_node *dn;
133408 + u32 is_portal_available;
133409 +
133410 + bman_init();
133411 + qman_init();
133412 +
133413 + is_portal_available = 0;
133414 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
133415 + if (!of_device_is_available(dn))
133416 + continue;
133417 + else
133418 + is_portal_available = 1;
133419 + }
133420 +
133421 + if (!qman_have_ccsr() && is_portal_available) {
133422 + struct qman_fq fq = {
133423 + .fqid = 1
133424 + };
133425 + struct qm_mcr_queryfq_np np;
133426 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
133427 + struct timespec nowts, diffts, startts = current_kernel_time();
133428 + /* Loop while querying given fqid succeeds or time out */
133429 + while (1) {
133430 + err = qman_query_fq_np(&fq, &np);
133431 + if (!err) {
133432 + /* success, control-plane has configured QMan */
133433 + break;
133434 + } else if (err != -ERANGE) {
133435 + pr_err("QMan: I/O error, continuing anyway\n");
133436 + break;
133437 + }
133438 + nowts = current_kernel_time();
133439 + diffts = timespec_sub(nowts, startts);
133440 + if (diffts.tv_sec > 0) {
133441 + if (!retry--) {
133442 + pr_err("QMan: time out, control-plane"
133443 + " dead?\n");
133444 + break;
133445 + }
133446 + pr_warn("QMan: polling for the control-plane"
133447 + " (%d)\n", retry);
133448 + }
133449 + }
133450 + }
133451 + bman_resource_init();
133452 + qman_resource_init();
133453 + return 0;
133454 +}
133455 +subsys_initcall(qbman_init);
133456 --- /dev/null
133457 +++ b/drivers/staging/fsl_qbman/qman_config.c
133458 @@ -0,0 +1,1224 @@
133459 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
133460 + *
133461 + * Redistribution and use in source and binary forms, with or without
133462 + * modification, are permitted provided that the following conditions are met:
133463 + * * Redistributions of source code must retain the above copyright
133464 + * notice, this list of conditions and the following disclaimer.
133465 + * * Redistributions in binary form must reproduce the above copyright
133466 + * notice, this list of conditions and the following disclaimer in the
133467 + * documentation and/or other materials provided with the distribution.
133468 + * * Neither the name of Freescale Semiconductor nor the
133469 + * names of its contributors may be used to endorse or promote products
133470 + * derived from this software without specific prior written permission.
133471 + *
133472 + *
133473 + * ALTERNATIVELY, this software may be distributed under the terms of the
133474 + * GNU General Public License ("GPL") as published by the Free Software
133475 + * Foundation, either version 2 of that License or (at your option) any
133476 + * later version.
133477 + *
133478 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133479 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133480 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133481 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133482 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133483 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133484 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133485 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133486 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133487 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133488 + */
133489 +
133490 +#include <asm/cacheflush.h>
133491 +#include "qman_private.h"
133492 +#include <linux/highmem.h>
133493 +#include <linux/of_reserved_mem.h>
133494 +
133495 +/* Last updated for v00.800 of the BG */
133496 +
133497 +/* Register offsets */
133498 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
133499 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
133500 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
133501 +#define REG_DD_CFG 0x0200
133502 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
133503 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
133504 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
133505 +#define REG_PFDR_FPC 0x0400
133506 +#define REG_PFDR_FP_HEAD 0x0404
133507 +#define REG_PFDR_FP_TAIL 0x0408
133508 +#define REG_PFDR_FP_LWIT 0x0410
133509 +#define REG_PFDR_CFG 0x0414
133510 +#define REG_SFDR_CFG 0x0500
133511 +#define REG_SFDR_IN_USE 0x0504
133512 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
133513 +#define REG_WQ_DEF_ENC_WQID 0x0630
133514 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
133515 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
133516 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
133517 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
133518 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
133519 +#define REG_CM_CFG 0x0800
133520 +#define REG_ECSR 0x0a00
133521 +#define REG_ECIR 0x0a04
133522 +#define REG_EADR 0x0a08
133523 +#define REG_ECIR2 0x0a0c
133524 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
133525 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
133526 +#define REG_MCR 0x0b00
133527 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
133528 +#define REG_MISC_CFG 0x0be0
133529 +#define REG_HID_CFG 0x0bf0
133530 +#define REG_IDLE_STAT 0x0bf4
133531 +#define REG_IP_REV_1 0x0bf8
133532 +#define REG_IP_REV_2 0x0bfc
133533 +#define REG_FQD_BARE 0x0c00
133534 +#define REG_PFDR_BARE 0x0c20
133535 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
133536 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
133537 +#define REG_QCSP_BARE 0x0c80
133538 +#define REG_QCSP_BAR 0x0c84
133539 +#define REG_CI_SCHED_CFG 0x0d00
133540 +#define REG_SRCIDR 0x0d04
133541 +#define REG_LIODNR 0x0d08
133542 +#define REG_CI_RLM_AVG 0x0d14
133543 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
133544 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
133545 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
133546 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
133547 +#define REG_CEETM_CFG_IDX 0x900
133548 +#define REG_CEETM_CFG_PRES 0x904
133549 +#define REG_CEETM_XSFDR_IN_USE 0x908
133550 +
133551 +/* Assists for QMAN_MCR */
133552 +#define MCR_INIT_PFDR 0x01000000
133553 +#define MCR_get_rslt(v) (u8)((v) >> 24)
133554 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
133555 +#define MCR_rslt_ok(r) (rslt == 0xf0)
133556 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
133557 +#define MCR_rslt_inval(r) (rslt == 0xff)
133558 +
133559 +struct qman;
133560 +
133561 +/* Follows WQ_CS_CFG0-5 */
133562 +enum qm_wq_class {
133563 + qm_wq_portal = 0,
133564 + qm_wq_pool = 1,
133565 + qm_wq_fman0 = 2,
133566 + qm_wq_fman1 = 3,
133567 + qm_wq_caam = 4,
133568 + qm_wq_pme = 5,
133569 + qm_wq_first = qm_wq_portal,
133570 + qm_wq_last = qm_wq_pme
133571 +};
133572 +
133573 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
133574 +enum qm_memory {
133575 + qm_memory_fqd,
133576 + qm_memory_pfdr
133577 +};
133578 +
133579 +/* Used by all error interrupt registers except 'inhibit' */
133580 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
133581 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
133582 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
133583 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
133584 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
133585 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
133586 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
133587 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
133588 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
133589 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
133590 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
133591 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
133592 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
133593 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
133594 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
133595 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
133596 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
133597 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
133598 +
133599 +/* QMAN_ECIR valid error bit */
133600 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
133601 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
133602 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
133603 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
133604 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
133605 + QM_EIRQ_IFSI)
133606 +
133607 +union qman_ecir {
133608 + u32 ecir_raw;
133609 + struct {
133610 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
133611 + u32 __reserved:2;
133612 + u32 portal_type:1;
133613 + u32 portal_num:5;
133614 + u32 fqid:24;
133615 +#else
133616 + u32 fqid:24;
133617 + u32 portal_num:5;
133618 + u32 portal_type:1;
133619 + u32 __reserved:2;
133620 +#endif
133621 + } __packed info;
133622 +};
133623 +
133624 +union qman_ecir2 {
133625 + u32 ecir2_raw;
133626 + struct {
133627 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
133628 + u32 portal_type:1;
133629 + u32 __reserved:21;
133630 + u32 portal_num:10;
133631 +#else
133632 + u32 portal_num:10;
133633 + u32 __reserved:21;
133634 + u32 portal_type:1;
133635 +#endif
133636 + } __packed info;
133637 +};
133638 +
133639 +union qman_eadr {
133640 + u32 eadr_raw;
133641 + struct {
133642 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
133643 + u32 __reserved1:4;
133644 + u32 memid:4;
133645 + u32 __reserved2:12;
133646 + u32 eadr:12;
133647 +#else
133648 + u32 eadr:12;
133649 + u32 __reserved2:12;
133650 + u32 memid:4;
133651 + u32 __reserved1:4;
133652 +#endif
133653 + } __packed info;
133654 + struct {
133655 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
133656 + u32 __reserved1:3;
133657 + u32 memid:5;
133658 + u32 __reserved:8;
133659 + u32 eadr:16;
133660 +#else
133661 + u32 eadr:16;
133662 + u32 __reserved:8;
133663 + u32 memid:5;
133664 + u32 __reserved1:3;
133665 +#endif
133666 + } __packed info_rev3;
133667 +};
133668 +
133669 +struct qman_hwerr_txt {
133670 + u32 mask;
133671 + const char *txt;
133672 +};
133673 +
133674 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
133675 +
133676 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
133677 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
133678 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
133679 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
133680 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
133681 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
133682 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
133683 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
133684 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
133685 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
133686 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
133687 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
133688 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
133689 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
133690 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
133691 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
133692 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
133693 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
133694 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
133695 +};
133696 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
133697 +
133698 +struct qman_error_info_mdata {
133699 + u16 addr_mask;
133700 + u16 bits;
133701 + const char *txt;
133702 +};
133703 +
133704 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
133705 +static const struct qman_error_info_mdata error_mdata[] = {
133706 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
133707 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
133708 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
133709 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
133710 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
133711 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
133712 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
133713 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
133714 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
133715 + QMAN_ERR_MDATA(0x7FFF, 256, "SW portal ring memory"),
133716 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
133717 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
133718 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
133719 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
133720 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
133721 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
133722 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
133723 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
133724 +};
133725 +#define QMAN_ERR_MDATA_COUNT \
133726 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
133727 +
133728 +/* Add this in Kconfig */
133729 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
133730 +
133731 +/**
133732 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
133733 + * @v: for accessors that write values, this is the 32-bit value
133734 + *
133735 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
133736 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
133737 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
133738 + * "write the enable register" rather than "enable the write register"!
133739 + */
133740 +#define qm_err_isr_status_read(qm) \
133741 + __qm_err_isr_read(qm, qm_isr_status)
133742 +#define qm_err_isr_status_clear(qm, m) \
133743 + __qm_err_isr_write(qm, qm_isr_status, m)
133744 +#define qm_err_isr_enable_read(qm) \
133745 + __qm_err_isr_read(qm, qm_isr_enable)
133746 +#define qm_err_isr_enable_write(qm, v) \
133747 + __qm_err_isr_write(qm, qm_isr_enable, v)
133748 +#define qm_err_isr_disable_read(qm) \
133749 + __qm_err_isr_read(qm, qm_isr_disable)
133750 +#define qm_err_isr_disable_write(qm, v) \
133751 + __qm_err_isr_write(qm, qm_isr_disable, v)
133752 +#define qm_err_isr_inhibit(qm) \
133753 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
133754 +#define qm_err_isr_uninhibit(qm) \
133755 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
133756 +
133757 +/*
133758 + * TODO: unimplemented registers
133759 + *
133760 + * Keeping a list here of Qman registers I have not yet covered;
133761 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
133762 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
133763 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
133764 + */
133765 +
133766 +/* Encapsulate "struct qman *" as a cast of the register space address. */
133767 +
133768 +static struct qman *qm_create(void *regs)
133769 +{
133770 + return (struct qman *)regs;
133771 +}
133772 +
133773 +static inline u32 __qm_in(struct qman *qm, u32 offset)
133774 +{
133775 + return in_be32((void *)qm + offset);
133776 +}
133777 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
133778 +{
133779 + out_be32((void *)qm + offset, val);
133780 +}
133781 +#define qm_in(reg) __qm_in(qm, REG_##reg)
133782 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
133783 +
133784 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
133785 +{
133786 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
133787 +}
133788 +
133789 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
133790 +{
133791 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
133792 +}
133793 +
133794 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
133795 + int ed, u8 sernd)
133796 +{
133797 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
133798 + (portal == qm_dc_portal_fman1));
133799 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
133800 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
133801 + else
133802 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
133803 +}
133804 +
133805 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
133806 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
133807 + u8 csw6, u8 csw7)
133808 +{
133809 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
133810 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
133811 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
133812 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
133813 +}
133814 +
133815 +static void qm_set_hid(struct qman *qm)
133816 +{
133817 + qm_out(HID_CFG, 0);
133818 +}
133819 +
133820 +static void qm_set_corenet_initiator(struct qman *qm)
133821 +{
133822 + qm_out(CI_SCHED_CFG,
133823 + 0x80000000 | /* write srcciv enable */
133824 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
133825 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
133826 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
133827 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
133828 +}
133829 +
133830 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
133831 + u8 *cfg)
133832 +{
133833 + u32 v = qm_in(IP_REV_1);
133834 + u32 v2 = qm_in(IP_REV_2);
133835 + *id = (v >> 16);
133836 + *major = (v >> 8) & 0xff;
133837 + *minor = v & 0xff;
133838 + *cfg = v2 & 0xff;
133839 +}
133840 +
133841 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
133842 + int enable, int prio, int stash, u32 size)
133843 +{
133844 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
133845 + u32 exp = ilog2(size);
133846 + /* choke if size isn't within range */
133847 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
133848 + is_power_of_2(size));
133849 + /* choke if 'ba' has lower-alignment than 'size' */
133850 + DPA_ASSERT(!(ba & (size - 1)));
133851 + __qm_out(qm, offset, upper_32_bits(ba));
133852 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
133853 + __qm_out(qm, offset + REG_offset_AR,
133854 + (enable ? 0x80000000 : 0) |
133855 + (prio ? 0x40000000 : 0) |
133856 + (stash ? 0x20000000 : 0) |
133857 + (exp - 1));
133858 +}
133859 +
133860 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
133861 +{
133862 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
133863 + qm_out(PFDR_CFG, k);
133864 +}
133865 +
133866 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
133867 +{
133868 + qm_out(SFDR_CFG, th & 0x3ff);
133869 +}
133870 +
133871 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
133872 +{
133873 + u8 rslt = MCR_get_rslt(qm_in(MCR));
133874 +
133875 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
133876 + /* Make sure the command interface is 'idle' */
133877 + if (!MCR_rslt_idle(rslt))
133878 + panic("QMAN_MCR isn't idle");
133879 +
133880 + /* Write the MCR command params then the verb */
133881 + qm_out(MCP(0), pfdr_start);
133882 + /* TODO: remove this - it's a workaround for a model bug that is
133883 + * corrected in more recent versions. We use the workaround until
133884 + * everyone has upgraded. */
133885 + qm_out(MCP(1), (pfdr_start + num - 16));
133886 + lwsync();
133887 + qm_out(MCR, MCR_INIT_PFDR);
133888 + /* Poll for the result */
133889 + do {
133890 + rslt = MCR_get_rslt(qm_in(MCR));
133891 + } while (!MCR_rslt_idle(rslt));
133892 + if (MCR_rslt_ok(rslt))
133893 + return 0;
133894 + if (MCR_rslt_eaccess(rslt))
133895 + return -EACCES;
133896 + if (MCR_rslt_inval(rslt))
133897 + return -EINVAL;
133898 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
133899 + return -ENOSYS;
133900 +}
133901 +
133902 +/*****************/
133903 +/* Config driver */
133904 +/*****************/
133905 +
133906 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
133907 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
133908 +
133909 +/* We support only one of these */
133910 +static struct qman *qm;
133911 +static struct device_node *qm_node;
133912 +
133913 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
133914 + * during qman_init_ccsr(). */
133915 +static dma_addr_t fqd_a, pfdr_a;
133916 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
133917 +
133918 +static int qman_fqd(struct reserved_mem *rmem)
133919 +{
133920 + fqd_a = rmem->base;
133921 + fqd_sz = rmem->size;
133922 +
133923 + WARN_ON(!(fqd_a && fqd_sz));
133924 +
133925 + return 0;
133926 +}
133927 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
133928 +
133929 +static int qman_pfdr(struct reserved_mem *rmem)
133930 +{
133931 + pfdr_a = rmem->base;
133932 + pfdr_sz = rmem->size;
133933 +
133934 + WARN_ON(!(pfdr_a && pfdr_sz));
133935 +
133936 + return 0;
133937 +}
133938 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
133939 +
133940 +size_t get_qman_fqd_size()
133941 +{
133942 + return fqd_sz;
133943 +}
133944 +
133945 +/* Parse the <name> property to extract the memory location and size and
133946 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
133947 + * size. Also flush this memory range from data cache so that QMAN originated
133948 + * transactions for this memory region could be marked non-coherent.
133949 + */
133950 +static __init int parse_mem_property(struct device_node *node, const char *name,
133951 + dma_addr_t *addr, size_t *sz, int zero)
133952 +{
133953 + int ret;
133954 +
133955 + /* If using a "zero-pma", don't try to zero it, even if you asked */
133956 + if (zero && of_find_property(node, "zero-pma", &ret)) {
133957 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
133958 + zero = 0;
133959 + }
133960 +
133961 + if (zero) {
133962 + /* map as cacheable, non-guarded */
133963 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
133964 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
133965 +#else
133966 + void __iomem *tmpp = ioremap(*addr, *sz);
133967 +#endif
133968 +
133969 + if (!tmpp)
133970 + return -ENOMEM;
133971 + memset_io(tmpp, 0, *sz);
133972 + flush_dcache_range((unsigned long)tmpp,
133973 + (unsigned long)tmpp + *sz);
133974 + iounmap(tmpp);
133975 + }
133976 +
133977 + return 0;
133978 +}
133979 +
133980 +/* TODO:
133981 + * - there is obviously no handling of errors,
133982 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
133983 + * both memory resources to zero.
133984 + */
133985 +static int __init fsl_qman_init(struct device_node *node)
133986 +{
133987 + struct resource res;
133988 + resource_size_t len;
133989 + u32 __iomem *regs;
133990 + const char *s;
133991 + int ret, standby = 0;
133992 + u16 id;
133993 + u8 major, minor, cfg;
133994 + ret = of_address_to_resource(node, 0, &res);
133995 + if (ret) {
133996 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
133997 + return ret;
133998 + }
133999 + s = of_get_property(node, "fsl,hv-claimable", &ret);
134000 + if (s && !strcmp(s, "standby"))
134001 + standby = 1;
134002 + if (!standby) {
134003 + ret = parse_mem_property(node, "fsl,qman-fqd",
134004 + &fqd_a, &fqd_sz, 1);
134005 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
134006 + BUG_ON(ret);
134007 + ret = parse_mem_property(node, "fsl,qman-pfdr",
134008 + &pfdr_a, &pfdr_sz, 0);
134009 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
134010 + BUG_ON(ret);
134011 + }
134012 + /* Global configuration */
134013 + len = resource_size(&res);
134014 + if (len != (unsigned long)len)
134015 + return -EINVAL;
134016 + regs = ioremap(res.start, (unsigned long)len);
134017 + qm = qm_create(regs);
134018 + qm_node = node;
134019 + qm_get_version(qm, &id, &major, &minor, &cfg);
134020 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
134021 + if (!qman_ip_rev) {
134022 + if ((major == 1) && (minor == 0)) {
134023 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
134024 + iounmap(regs);
134025 + return -ENODEV;
134026 + } else if ((major == 1) && (minor == 1))
134027 + qman_ip_rev = QMAN_REV11;
134028 + else if ((major == 1) && (minor == 2))
134029 + qman_ip_rev = QMAN_REV12;
134030 + else if ((major == 2) && (minor == 0))
134031 + qman_ip_rev = QMAN_REV20;
134032 + else if ((major == 3) && (minor == 0))
134033 + qman_ip_rev = QMAN_REV30;
134034 + else if ((major == 3) && (minor == 1))
134035 + qman_ip_rev = QMAN_REV31;
134036 + else if ((major == 3) && (minor == 2))
134037 + qman_ip_rev = QMAN_REV32;
134038 + else {
134039 + pr_warn("unknown Qman version, default to rev1.1\n");
134040 + qman_ip_rev = QMAN_REV11;
134041 + }
134042 + qman_ip_cfg = cfg;
134043 + }
134044 +
134045 + if (standby) {
134046 + pr_info(" -> in standby mode\n");
134047 + return 0;
134048 + }
134049 + return 0;
134050 +}
134051 +
134052 +int qman_have_ccsr(void)
134053 +{
134054 + return qm ? 1 : 0;
134055 +}
134056 +
134057 +__init int qman_init_early(void)
134058 +{
134059 + struct device_node *dn;
134060 + int ret;
134061 +
134062 + for_each_compatible_node(dn, NULL, "fsl,qman") {
134063 + if (qm)
134064 + pr_err("%s: only one 'fsl,qman' allowed\n",
134065 + dn->full_name);
134066 + else {
134067 + if (!of_device_is_available(dn))
134068 + continue;
134069 +
134070 + ret = fsl_qman_init(dn);
134071 + BUG_ON(ret);
134072 + }
134073 + }
134074 + return 0;
134075 +}
134076 +postcore_initcall_sync(qman_init_early);
134077 +
134078 +static void log_edata_bits(u32 bit_count)
134079 +{
134080 + u32 i, j, mask = 0xffffffff;
134081 +
134082 + pr_warn("Qman ErrInt, EDATA:\n");
134083 + i = bit_count/32;
134084 + if (bit_count%32) {
134085 + i++;
134086 + mask = ~(mask << bit_count%32);
134087 + }
134088 + j = 16-i;
134089 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
134090 + j++;
134091 + for (; j < 16; j++)
134092 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
134093 +}
134094 +
134095 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
134096 +{
134097 + union qman_ecir ecir_val;
134098 + union qman_eadr eadr_val;
134099 +
134100 + ecir_val.ecir_raw = qm_in(ECIR);
134101 + /* Is portal info valid */
134102 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
134103 + union qman_ecir2 ecir2_val;
134104 + ecir2_val.ecir2_raw = qm_in(ECIR2);
134105 + if (ecsr_val & PORTAL_ECSR_ERR) {
134106 + pr_warn("Qman ErrInt: %s id %d\n",
134107 + (ecir2_val.info.portal_type) ?
134108 + "DCP" : "SWP", ecir2_val.info.portal_num);
134109 + }
134110 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
134111 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
134112 + ecir_val.info.fqid);
134113 + }
134114 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
134115 + eadr_val.eadr_raw = qm_in(EADR);
134116 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
134117 + error_mdata[eadr_val.info_rev3.memid].txt,
134118 + error_mdata[eadr_val.info_rev3.memid].addr_mask
134119 + & eadr_val.info_rev3.eadr);
134120 + log_edata_bits(
134121 + error_mdata[eadr_val.info_rev3.memid].bits);
134122 + }
134123 + } else {
134124 + if (ecsr_val & PORTAL_ECSR_ERR) {
134125 + pr_warn("Qman ErrInt: %s id %d\n",
134126 + (ecir_val.info.portal_type) ?
134127 + "DCP" : "SWP", ecir_val.info.portal_num);
134128 + }
134129 + if (ecsr_val & FQID_ECSR_ERR) {
134130 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
134131 + ecir_val.info.fqid);
134132 + }
134133 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
134134 + eadr_val.eadr_raw = qm_in(EADR);
134135 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
134136 + error_mdata[eadr_val.info.memid].txt,
134137 + error_mdata[eadr_val.info.memid].addr_mask
134138 + & eadr_val.info.eadr);
134139 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
134140 + }
134141 + }
134142 +}
134143 +
134144 +/* Qman interrupt handler */
134145 +static irqreturn_t qman_isr(int irq, void *ptr)
134146 +{
134147 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
134148 +
134149 + ier_val = qm_err_isr_enable_read(qm);
134150 + isr_val = qm_err_isr_status_read(qm);
134151 + ecsr_val = qm_in(ECSR);
134152 + isr_mask = isr_val & ier_val;
134153 +
134154 + if (!isr_mask)
134155 + return IRQ_NONE;
134156 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
134157 + if (qman_hwerr_txts[i].mask & isr_mask) {
134158 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
134159 + if (qman_hwerr_txts[i].mask & ecsr_val) {
134160 + log_additional_error_info(isr_mask, ecsr_val);
134161 + /* Re-arm error capture registers */
134162 + qm_out(ECSR, ecsr_val);
134163 + }
134164 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
134165 + pr_devel("Qman un-enabling error 0x%x\n",
134166 + qman_hwerr_txts[i].mask);
134167 + ier_val &= ~qman_hwerr_txts[i].mask;
134168 + qm_err_isr_enable_write(qm, ier_val);
134169 + }
134170 + }
134171 + }
134172 + qm_err_isr_status_clear(qm, isr_val);
134173 + return IRQ_HANDLED;
134174 +}
134175 +
134176 +static int __bind_irq(void)
134177 +{
134178 + int ret, err_irq;
134179 +
134180 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
134181 + if (err_irq == 0) {
134182 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
134183 + "interrupts");
134184 + return -ENODEV;
134185 + }
134186 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
134187 + if (ret) {
134188 + pr_err("request_irq() failed %d for '%s'\n", ret,
134189 + qm_node->full_name);
134190 + return -ENODEV;
134191 + }
134192 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
134193 + * to resource allocation during driver init). */
134194 + qm_err_isr_status_clear(qm, 0xffffffff);
134195 + /* Enable Error Interrupts */
134196 + qm_err_isr_enable_write(qm, 0xffffffff);
134197 + return 0;
134198 +}
134199 +
134200 +int qman_init_ccsr(struct device_node *node)
134201 +{
134202 + int ret;
134203 + if (!qman_have_ccsr())
134204 + return 0;
134205 + if (node != qm_node)
134206 + return -EINVAL;
134207 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
134208 + /* TEMP for LS1043 : should be done in uboot */
134209 + qm_out(QCSP_BARE, 0x5);
134210 + qm_out(QCSP_BAR, 0x0);
134211 +#endif
134212 + /* FQD memory */
134213 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
134214 + /* PFDR memory */
134215 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
134216 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
134217 + /* thresholds */
134218 + qm_set_pfdr_threshold(qm, 512, 64);
134219 + qm_set_sfdr_threshold(qm, 128);
134220 + /* clear stale PEBI bit from interrupt status register */
134221 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
134222 + /* corenet initiator settings */
134223 + qm_set_corenet_initiator(qm);
134224 + /* HID settings */
134225 + qm_set_hid(qm);
134226 + /* Set scheduling weights to defaults */
134227 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
134228 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
134229 + /* We are not prepared to accept ERNs for hardware enqueues */
134230 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
134231 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
134232 + /* Initialise Error Interrupt Handler */
134233 + ret = __bind_irq();
134234 + if (ret)
134235 + return ret;
134236 + return 0;
134237 +}
134238 +
134239 +#define LIO_CFG_LIODN_MASK 0x0fff0000
134240 +void qman_liodn_fixup(u16 channel)
134241 +{
134242 + static int done;
134243 + static u32 liodn_offset;
134244 + u32 before, after;
134245 + int idx = channel - QM_CHANNEL_SWPORTAL0;
134246 +
134247 + if (!qman_have_ccsr())
134248 + return;
134249 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
134250 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
134251 + else
134252 + before = qm_in(QCSP_LIO_CFG(idx));
134253 + if (!done) {
134254 + liodn_offset = before & LIO_CFG_LIODN_MASK;
134255 + done = 1;
134256 + return;
134257 + }
134258 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
134259 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
134260 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
134261 + else
134262 + qm_out(QCSP_LIO_CFG(idx), after);
134263 +}
134264 +
134265 +#define IO_CFG_SDEST_MASK 0x00ff0000
134266 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
134267 +{
134268 + int idx = channel - QM_CHANNEL_SWPORTAL0;
134269 + u32 before, after;
134270 +
134271 + if (!qman_have_ccsr())
134272 + return -ENODEV;
134273 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
134274 + /* LS1043A - only one L2 cache */
134275 + cpu_idx = 0;
134276 + }
134277 +
134278 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
134279 + before = qm_in(REV3_QCSP_IO_CFG(idx));
134280 + /* Each pair of vcpu share the same SRQ(SDEST) */
134281 + cpu_idx /= 2;
134282 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
134283 + qm_out(REV3_QCSP_IO_CFG(idx), after);
134284 + } else {
134285 + before = qm_in(QCSP_IO_CFG(idx));
134286 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
134287 + qm_out(QCSP_IO_CFG(idx), after);
134288 + }
134289 + return 0;
134290 +}
134291 +
134292 +#define MISC_CFG_WPM_MASK 0x00000002
134293 +int qm_set_wpm(int wpm)
134294 +{
134295 + u32 before;
134296 + u32 after;
134297 +
134298 + if (!qman_have_ccsr())
134299 + return -ENODEV;
134300 +
134301 + before = qm_in(MISC_CFG);
134302 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
134303 + qm_out(MISC_CFG, after);
134304 + return 0;
134305 +}
134306 +
134307 +int qm_get_wpm(int *wpm)
134308 +{
134309 + u32 before;
134310 +
134311 + if (!qman_have_ccsr())
134312 + return -ENODEV;
134313 +
134314 + before = qm_in(MISC_CFG);
134315 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
134316 + return 0;
134317 +}
134318 +
134319 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
134320 + * PRES = (2^22 / credit update reference period) * QMan clock period
134321 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
134322 + */
134323 +
134324 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
134325 +{
134326 + u64 temp;
134327 + u16 pres;
134328 +
134329 + if (!qman_have_ccsr())
134330 + return -ENODEV;
134331 +
134332 + temp = 0x400000 * 100;
134333 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
134334 + temp *= 10000000;
134335 + do_div(temp, qman_clk);
134336 + pres = (u16) temp;
134337 + qm_out(CEETM_CFG_IDX, portal);
134338 + qm_out(CEETM_CFG_PRES, pres);
134339 + return 0;
134340 +}
134341 +
134342 +int qman_ceetm_get_prescaler(u16 *pres)
134343 +{
134344 + if (!qman_have_ccsr())
134345 + return -ENODEV;
134346 + *pres = (u16)qm_in(CEETM_CFG_PRES);
134347 + return 0;
134348 +}
134349 +
134350 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
134351 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
134352 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
134353 +{
134354 + u32 dcp_cfg;
134355 +
134356 + if (!qman_have_ccsr())
134357 + return -ENODEV;
134358 +
134359 + dcp_cfg = qm_in(DCP_CFG(portal));
134360 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
134361 + qm_out(DCP_CFG(portal), dcp_cfg);
134362 + return 0;
134363 +}
134364 +
134365 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
134366 +{
134367 + u32 dcp_cfg;
134368 +
134369 + if (!qman_have_ccsr())
134370 + return -ENODEV;
134371 + dcp_cfg = qm_in(DCP_CFG(portal));
134372 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
134373 + qm_out(DCP_CFG(portal), dcp_cfg);
134374 + return 0;
134375 +}
134376 +
134377 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
134378 +{
134379 + if (!qman_have_ccsr())
134380 + return -ENODEV;
134381 + *num = qm_in(CEETM_XSFDR_IN_USE);
134382 + return 0;
134383 +}
134384 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
134385 +
134386 +#ifdef CONFIG_SYSFS
134387 +
134388 +#define DRV_NAME "fsl-qman"
134389 +#define DCP_MAX_ID 3
134390 +#define DCP_MIN_ID 0
134391 +
134392 +static ssize_t show_pfdr_fpc(struct device *dev,
134393 + struct device_attribute *dev_attr, char *buf)
134394 +{
134395 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
134396 +};
134397 +
134398 +static ssize_t show_dlm_avg(struct device *dev,
134399 + struct device_attribute *dev_attr, char *buf)
134400 +{
134401 + u32 data;
134402 + int i;
134403 +
134404 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
134405 + return -EINVAL;
134406 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
134407 + return -EINVAL;
134408 + data = qm_in(DCP_DLM_AVG(i));
134409 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
134410 + (data & 0x000000ff)*390625);
134411 +};
134412 +
134413 +static ssize_t set_dlm_avg(struct device *dev,
134414 + struct device_attribute *dev_attr, const char *buf, size_t count)
134415 +{
134416 + unsigned long val;
134417 + int i;
134418 +
134419 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
134420 + return -EINVAL;
134421 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
134422 + return -EINVAL;
134423 + if (kstrtoul(buf, 0, &val)) {
134424 + dev_dbg(dev, "invalid input %s\n", buf);
134425 + return -EINVAL;
134426 + }
134427 + qm_out(DCP_DLM_AVG(i), val);
134428 + return count;
134429 +};
134430 +
134431 +static ssize_t show_pfdr_cfg(struct device *dev,
134432 + struct device_attribute *dev_attr, char *buf)
134433 +{
134434 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
134435 +};
134436 +
134437 +static ssize_t set_pfdr_cfg(struct device *dev,
134438 + struct device_attribute *dev_attr, const char *buf, size_t count)
134439 +{
134440 + unsigned long val;
134441 +
134442 + if (kstrtoul(buf, 0, &val)) {
134443 + dev_dbg(dev, "invalid input %s\n", buf);
134444 + return -EINVAL;
134445 + }
134446 + qm_out(PFDR_CFG, val);
134447 + return count;
134448 +};
134449 +
134450 +static ssize_t show_sfdr_in_use(struct device *dev,
134451 + struct device_attribute *dev_attr, char *buf)
134452 +{
134453 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
134454 +};
134455 +
134456 +static ssize_t show_idle_stat(struct device *dev,
134457 + struct device_attribute *dev_attr, char *buf)
134458 +{
134459 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
134460 +};
134461 +
134462 +static ssize_t show_ci_rlm_avg(struct device *dev,
134463 + struct device_attribute *dev_attr, char *buf)
134464 +{
134465 + u32 data = qm_in(CI_RLM_AVG);
134466 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
134467 + (data & 0x000000ff)*390625);
134468 +};
134469 +
134470 +static ssize_t set_ci_rlm_avg(struct device *dev,
134471 + struct device_attribute *dev_attr, const char *buf, size_t count)
134472 +{
134473 + unsigned long val;
134474 +
134475 + if (kstrtoul(buf, 0, &val)) {
134476 + dev_dbg(dev, "invalid input %s\n", buf);
134477 + return -EINVAL;
134478 + }
134479 + qm_out(CI_RLM_AVG, val);
134480 + return count;
134481 +};
134482 +
134483 +static ssize_t show_err_isr(struct device *dev,
134484 + struct device_attribute *dev_attr, char *buf)
134485 +{
134486 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
134487 +};
134488 +
134489 +#define SBEC_MAX_ID 14
134490 +#define SBEC_MIN_ID 0
134491 +
134492 +static ssize_t show_sbec(struct device *dev,
134493 + struct device_attribute *dev_attr, char *buf)
134494 +{
134495 + int i;
134496 +
134497 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
134498 + return -EINVAL;
134499 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
134500 + return -EINVAL;
134501 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
134502 +};
134503 +
134504 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
134505 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
134506 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
134507 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
134508 + show_ci_rlm_avg, set_ci_rlm_avg);
134509 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
134510 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
134511 +
134512 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134513 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134514 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134515 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134516 +
134517 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
134518 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
134519 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
134520 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
134521 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
134522 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
134523 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
134524 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
134525 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
134526 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
134527 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
134528 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
134529 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
134530 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
134531 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
134532 +
134533 +static struct attribute *qman_dev_attributes[] = {
134534 + &dev_attr_pfdr_fpc.attr,
134535 + &dev_attr_pfdr_cfg.attr,
134536 + &dev_attr_idle_stat.attr,
134537 + &dev_attr_ci_rlm_avg.attr,
134538 + &dev_attr_err_isr.attr,
134539 + &dev_attr_dcp0_dlm_avg.attr,
134540 + &dev_attr_dcp1_dlm_avg.attr,
134541 + &dev_attr_dcp2_dlm_avg.attr,
134542 + &dev_attr_dcp3_dlm_avg.attr,
134543 + /* sfdr_in_use will be added if necessary */
134544 + NULL
134545 +};
134546 +
134547 +static struct attribute *qman_dev_ecr_attributes[] = {
134548 + &dev_attr_sbec_0.attr,
134549 + &dev_attr_sbec_1.attr,
134550 + &dev_attr_sbec_2.attr,
134551 + &dev_attr_sbec_3.attr,
134552 + &dev_attr_sbec_4.attr,
134553 + &dev_attr_sbec_5.attr,
134554 + &dev_attr_sbec_6.attr,
134555 + &dev_attr_sbec_7.attr,
134556 + &dev_attr_sbec_8.attr,
134557 + &dev_attr_sbec_9.attr,
134558 + &dev_attr_sbec_10.attr,
134559 + &dev_attr_sbec_11.attr,
134560 + &dev_attr_sbec_12.attr,
134561 + &dev_attr_sbec_13.attr,
134562 + &dev_attr_sbec_14.attr,
134563 + NULL
134564 +};
134565 +
134566 +/* root level */
134567 +static const struct attribute_group qman_dev_attr_grp = {
134568 + .name = NULL,
134569 + .attrs = qman_dev_attributes
134570 +};
134571 +static const struct attribute_group qman_dev_ecr_grp = {
134572 + .name = "error_capture",
134573 + .attrs = qman_dev_ecr_attributes
134574 +};
134575 +
134576 +static int of_fsl_qman_remove(struct platform_device *ofdev)
134577 +{
134578 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
134579 + return 0;
134580 +};
134581 +
134582 +static int of_fsl_qman_probe(struct platform_device *ofdev)
134583 +{
134584 + int ret;
134585 +
134586 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
134587 + if (ret)
134588 + goto done;
134589 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
134590 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
134591 + if (ret)
134592 + goto del_group_0;
134593 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
134594 + if (ret)
134595 + goto del_group_0;
134596 +
134597 + goto done;
134598 +
134599 +del_group_0:
134600 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
134601 +done:
134602 + if (ret)
134603 + dev_err(&ofdev->dev,
134604 + "Cannot create dev attributes ret=%d\n", ret);
134605 + return ret;
134606 +};
134607 +
134608 +static struct of_device_id of_fsl_qman_ids[] = {
134609 + {
134610 + .compatible = "fsl,qman",
134611 + },
134612 + {}
134613 +};
134614 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
134615 +
134616 +#ifdef CONFIG_SUSPEND
134617 +
134618 +static u32 saved_isdr;
134619 +static int qman_pm_suspend_noirq(struct device *dev)
134620 +{
134621 + uint32_t idle_state;
134622 +
134623 + suspend_unused_qportal();
134624 + /* save isdr, disable all, clear isr */
134625 + saved_isdr = qm_err_isr_disable_read(qm);
134626 + qm_err_isr_disable_write(qm, 0xffffffff);
134627 + qm_err_isr_status_clear(qm, 0xffffffff);
134628 + idle_state = qm_in(IDLE_STAT);
134629 + if (!(idle_state & 0x1)) {
134630 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
134631 + qm_err_isr_disable_write(qm, saved_isdr);
134632 + resume_unused_qportal();
134633 + return -EBUSY;
134634 + }
134635 +#ifdef CONFIG_PM_DEBUG
134636 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
134637 +#endif
134638 + return 0;
134639 +}
134640 +
134641 +static int qman_pm_resume_noirq(struct device *dev)
134642 +{
134643 + /* restore isdr */
134644 + qm_err_isr_disable_write(qm, saved_isdr);
134645 + resume_unused_qportal();
134646 + return 0;
134647 +}
134648 +#else
134649 +#define qman_pm_suspend_noirq NULL
134650 +#define qman_pm_resume_noirq NULL
134651 +#endif
134652 +
134653 +static const struct dev_pm_ops qman_pm_ops = {
134654 + .suspend_noirq = qman_pm_suspend_noirq,
134655 + .resume_noirq = qman_pm_resume_noirq,
134656 +};
134657 +
134658 +static struct platform_driver of_fsl_qman_driver = {
134659 + .driver = {
134660 + .owner = THIS_MODULE,
134661 + .name = DRV_NAME,
134662 + .of_match_table = of_fsl_qman_ids,
134663 + .pm = &qman_pm_ops,
134664 + },
134665 + .probe = of_fsl_qman_probe,
134666 + .remove = of_fsl_qman_remove,
134667 +};
134668 +
134669 +static int qman_ctrl_init(void)
134670 +{
134671 + return platform_driver_register(&of_fsl_qman_driver);
134672 +}
134673 +
134674 +static void qman_ctrl_exit(void)
134675 +{
134676 + platform_driver_unregister(&of_fsl_qman_driver);
134677 +}
134678 +
134679 +module_init(qman_ctrl_init);
134680 +module_exit(qman_ctrl_exit);
134681 +
134682 +#endif /* CONFIG_SYSFS */
134683 --- /dev/null
134684 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
134685 @@ -0,0 +1,1594 @@
134686 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
134687 + *
134688 + * Redistribution and use in source and binary forms, with or without
134689 + * modification, are permitted provided that the following conditions are met:
134690 + * * Redistributions of source code must retain the above copyright
134691 + * notice, this list of conditions and the following disclaimer.
134692 + * * Redistributions in binary form must reproduce the above copyright
134693 + * notice, this list of conditions and the following disclaimer in the
134694 + * documentation and/or other materials provided with the distribution.
134695 + * * Neither the name of Freescale Semiconductor nor the
134696 + * names of its contributors may be used to endorse or promote products
134697 + * derived from this software without specific prior written permission.
134698 + *
134699 + *
134700 + * ALTERNATIVELY, this software may be distributed under the terms of the
134701 + * GNU General Public License ("GPL") as published by the Free Software
134702 + * Foundation, either version 2 of that License or (at your option) any
134703 + * later version.
134704 + *
134705 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
134706 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
134707 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
134708 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
134709 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
134710 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
134711 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
134712 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
134713 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
134714 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
134715 + */
134716 +#include "qman_private.h"
134717 +
134718 +#define MAX_FQID (0x00ffffff)
134719 +#define QM_FQD_BLOCK_SIZE 64
134720 +#define QM_FQD_AR (0xC10)
134721 +
134722 +static u32 fqid_max;
134723 +static u64 qman_ccsr_start;
134724 +static u64 qman_ccsr_size;
134725 +
134726 +static const char * const state_txt[] = {
134727 + "Out of Service",
134728 + "Retired",
134729 + "Tentatively Scheduled",
134730 + "Truly Scheduled",
134731 + "Parked",
134732 + "Active, Active Held or Held Suspended",
134733 + "Unknown State 6",
134734 + "Unknown State 7",
134735 + NULL,
134736 +};
134737 +
134738 +static const u8 fqd_states[] = {
134739 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
134740 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
134741 + QM_MCR_NP_STATE_ACTIVE};
134742 +
134743 +struct mask_to_text {
134744 + u16 mask;
134745 + const char *txt;
134746 +};
134747 +
134748 +struct mask_filter_s {
134749 + u16 mask;
134750 + u8 filter;
134751 +};
134752 +
134753 +static const struct mask_filter_s mask_filter[] = {
134754 + {QM_FQCTRL_PREFERINCACHE, 0},
134755 + {QM_FQCTRL_PREFERINCACHE, 1},
134756 + {QM_FQCTRL_HOLDACTIVE, 0},
134757 + {QM_FQCTRL_HOLDACTIVE, 1},
134758 + {QM_FQCTRL_AVOIDBLOCK, 0},
134759 + {QM_FQCTRL_AVOIDBLOCK, 1},
134760 + {QM_FQCTRL_FORCESFDR, 0},
134761 + {QM_FQCTRL_FORCESFDR, 1},
134762 + {QM_FQCTRL_CPCSTASH, 0},
134763 + {QM_FQCTRL_CPCSTASH, 1},
134764 + {QM_FQCTRL_CTXASTASHING, 0},
134765 + {QM_FQCTRL_CTXASTASHING, 1},
134766 + {QM_FQCTRL_ORP, 0},
134767 + {QM_FQCTRL_ORP, 1},
134768 + {QM_FQCTRL_TDE, 0},
134769 + {QM_FQCTRL_TDE, 1},
134770 + {QM_FQCTRL_CGE, 0},
134771 + {QM_FQCTRL_CGE, 1}
134772 +};
134773 +
134774 +static const struct mask_to_text fq_ctrl_text_list[] = {
134775 + {
134776 + .mask = QM_FQCTRL_PREFERINCACHE,
134777 + .txt = "Prefer in cache",
134778 + },
134779 + {
134780 + .mask = QM_FQCTRL_HOLDACTIVE,
134781 + .txt = "Hold active in portal",
134782 + },
134783 + {
134784 + .mask = QM_FQCTRL_AVOIDBLOCK,
134785 + .txt = "Avoid Blocking",
134786 + },
134787 + {
134788 + .mask = QM_FQCTRL_FORCESFDR,
134789 + .txt = "High-priority SFDRs",
134790 + },
134791 + {
134792 + .mask = QM_FQCTRL_CPCSTASH,
134793 + .txt = "CPC Stash Enable",
134794 + },
134795 + {
134796 + .mask = QM_FQCTRL_CTXASTASHING,
134797 + .txt = "Context-A stashing",
134798 + },
134799 + {
134800 + .mask = QM_FQCTRL_ORP,
134801 + .txt = "ORP Enable",
134802 + },
134803 + {
134804 + .mask = QM_FQCTRL_TDE,
134805 + .txt = "Tail-Drop Enable",
134806 + },
134807 + {
134808 + .mask = QM_FQCTRL_CGE,
134809 + .txt = "Congestion Group Enable",
134810 + },
134811 + {
134812 + .mask = 0,
134813 + .txt = NULL,
134814 + }
134815 +};
134816 +
134817 +static const char *get_fqd_ctrl_text(u16 mask)
134818 +{
134819 + int i = 0;
134820 +
134821 + while (fq_ctrl_text_list[i].txt != NULL) {
134822 + if (fq_ctrl_text_list[i].mask == mask)
134823 + return fq_ctrl_text_list[i].txt;
134824 + i++;
134825 + }
134826 + return NULL;
134827 +}
134828 +
134829 +static const struct mask_to_text stashing_text_list[] = {
134830 + {
134831 + .mask = QM_STASHING_EXCL_CTX,
134832 + .txt = "FQ Ctx Stash"
134833 + },
134834 + {
134835 + .mask = QM_STASHING_EXCL_DATA,
134836 + .txt = "Frame Data Stash",
134837 + },
134838 + {
134839 + .mask = QM_STASHING_EXCL_ANNOTATION,
134840 + .txt = "Frame Annotation Stash",
134841 + },
134842 + {
134843 + .mask = 0,
134844 + .txt = NULL,
134845 + },
134846 +};
134847 +
134848 +static int user_input_convert(const char __user *user_buf, size_t count,
134849 + unsigned long *val)
134850 +{
134851 + char buf[12];
134852 +
134853 + if (count > sizeof(buf) - 1)
134854 + return -EINVAL;
134855 + if (copy_from_user(buf, user_buf, count))
134856 + return -EFAULT;
134857 + buf[count] = '\0';
134858 + if (kstrtoul(buf, 0, val))
134859 + return -EINVAL;
134860 + return 0;
134861 +}
134862 +
134863 +struct line_buffer_fq {
134864 + u32 buf[8];
134865 + u32 buf_cnt;
134866 + int line_cnt;
134867 +};
134868 +
134869 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
134870 + struct seq_file *file)
134871 +{
134872 + line_buf->buf[line_buf->buf_cnt] = fqid;
134873 + line_buf->buf_cnt++;
134874 + if (line_buf->buf_cnt == 8) {
134875 + /* Buffer is full, flush it */
134876 + if (line_buf->line_cnt != 0)
134877 + seq_puts(file, ",\n");
134878 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
134879 + "0x%06x,0x%06x,0x%06x",
134880 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
134881 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
134882 + line_buf->buf[6], line_buf->buf[7]);
134883 + line_buf->buf_cnt = 0;
134884 + line_buf->line_cnt++;
134885 + }
134886 +}
134887 +
134888 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
134889 + struct seq_file *file)
134890 +{
134891 + if (line_buf->buf_cnt) {
134892 + int y = 0;
134893 + if (line_buf->line_cnt != 0)
134894 + seq_puts(file, ",\n");
134895 + while (y != line_buf->buf_cnt) {
134896 + if (y+1 == line_buf->buf_cnt)
134897 + seq_printf(file, "0x%06x", line_buf->buf[y]);
134898 + else
134899 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
134900 + y++;
134901 + }
134902 + line_buf->line_cnt++;
134903 + }
134904 + if (line_buf->line_cnt)
134905 + seq_putc(file, '\n');
134906 +}
134907 +
134908 +static struct dentry *dfs_root; /* debugfs root directory */
134909 +
134910 +/*******************************************************************************
134911 + * Query Frame Queue Non Programmable Fields
134912 + ******************************************************************************/
134913 +struct query_fq_np_fields_data_s {
134914 + u32 fqid;
134915 +};
134916 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
134917 + .fqid = 1,
134918 +};
134919 +
134920 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
134921 +{
134922 + int ret;
134923 + struct qm_mcr_queryfq_np np;
134924 + struct qman_fq fq;
134925 +
134926 + fq.fqid = query_fq_np_fields_data.fqid;
134927 + ret = qman_query_fq_np(&fq, &np);
134928 + if (ret)
134929 + return ret;
134930 + /* Print state */
134931 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
134932 + fq.fqid);
134933 + seq_printf(file, " force eligible pending: %s\n",
134934 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
134935 + seq_printf(file, " retirement pending: %s\n",
134936 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
134937 + seq_printf(file, " state: %s\n",
134938 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
134939 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
134940 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
134941 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
134942 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
134943 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
134944 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
134945 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
134946 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
134947 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
134948 + seq_printf(file, " is: ics_surp contains a %s\n",
134949 + (np.is) ? "deficit" : "surplus");
134950 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
134951 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
134952 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
134953 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
134954 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
134955 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
134956 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
134957 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
134958 + return 0;
134959 +}
134960 +
134961 +static int query_fq_np_fields_open(struct inode *inode,
134962 + struct file *file)
134963 +{
134964 + return single_open(file, query_fq_np_fields_show, NULL);
134965 +}
134966 +
134967 +static ssize_t query_fq_np_fields_write(struct file *f,
134968 + const char __user *buf, size_t count, loff_t *off)
134969 +{
134970 + int ret;
134971 + unsigned long val;
134972 +
134973 + ret = user_input_convert(buf, count, &val);
134974 + if (ret)
134975 + return ret;
134976 + if (val > MAX_FQID)
134977 + return -EINVAL;
134978 + query_fq_np_fields_data.fqid = (u32)val;
134979 + return count;
134980 +}
134981 +
134982 +static const struct file_operations query_fq_np_fields_fops = {
134983 + .owner = THIS_MODULE,
134984 + .open = query_fq_np_fields_open,
134985 + .read = seq_read,
134986 + .write = query_fq_np_fields_write,
134987 + .release = single_release,
134988 +};
134989 +
134990 +/*******************************************************************************
134991 + * Frame Queue Programmable Fields
134992 + ******************************************************************************/
134993 +struct query_fq_fields_data_s {
134994 + u32 fqid;
134995 +};
134996 +
134997 +static struct query_fq_fields_data_s query_fq_fields_data = {
134998 + .fqid = 1,
134999 +};
135000 +
135001 +static int query_fq_fields_show(struct seq_file *file, void *offset)
135002 +{
135003 + int ret;
135004 + struct qm_fqd fqd;
135005 + struct qman_fq fq;
135006 + int i = 0;
135007 +
135008 + memset(&fqd, 0, sizeof(struct qm_fqd));
135009 + fq.fqid = query_fq_fields_data.fqid;
135010 + ret = qman_query_fq(&fq, &fqd);
135011 + if (ret)
135012 + return ret;
135013 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
135014 + fq.fqid);
135015 + seq_printf(file, " orprws: %u\n", fqd.orprws);
135016 + seq_printf(file, " oa: %u\n", fqd.oa);
135017 + seq_printf(file, " olws: %u\n", fqd.olws);
135018 +
135019 + seq_printf(file, " cgid: %u\n", fqd.cgid);
135020 +
135021 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
135022 + seq_puts(file, " fq_ctrl: None\n");
135023 + else {
135024 + i = 0;
135025 + seq_puts(file, " fq_ctrl:\n");
135026 + while (fq_ctrl_text_list[i].txt != NULL) {
135027 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
135028 + fq_ctrl_text_list[i].mask)
135029 + seq_printf(file, " %s\n",
135030 + fq_ctrl_text_list[i].txt);
135031 + i++;
135032 + }
135033 + }
135034 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
135035 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
135036 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
135037 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
135038 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
135039 +
135040 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
135041 +
135042 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
135043 + /* Any stashing configured */
135044 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
135045 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
135046 + else {
135047 + seq_puts(file, " ctx_a_stash_exclusive:\n");
135048 + i = 0;
135049 + while (stashing_text_list[i].txt != NULL) {
135050 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
135051 + seq_printf(file, " %s\n",
135052 + stashing_text_list[i].txt);
135053 + i++;
135054 + }
135055 + }
135056 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
135057 + fqd.context_a.stashing.annotation_cl);
135058 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
135059 + fqd.context_a.stashing.data_cl);
135060 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
135061 + fqd.context_a.stashing.context_cl);
135062 + return 0;
135063 +}
135064 +
135065 +static int query_fq_fields_open(struct inode *inode,
135066 + struct file *file)
135067 +{
135068 + return single_open(file, query_fq_fields_show, NULL);
135069 +}
135070 +
135071 +static ssize_t query_fq_fields_write(struct file *f,
135072 + const char __user *buf, size_t count, loff_t *off)
135073 +{
135074 + int ret;
135075 + unsigned long val;
135076 +
135077 + ret = user_input_convert(buf, count, &val);
135078 + if (ret)
135079 + return ret;
135080 + if (val > MAX_FQID)
135081 + return -EINVAL;
135082 + query_fq_fields_data.fqid = (u32)val;
135083 + return count;
135084 +}
135085 +
135086 +static const struct file_operations query_fq_fields_fops = {
135087 + .owner = THIS_MODULE,
135088 + .open = query_fq_fields_open,
135089 + .read = seq_read,
135090 + .write = query_fq_fields_write,
135091 + .release = single_release,
135092 +};
135093 +
135094 +/*******************************************************************************
135095 + * Query WQ lengths
135096 + ******************************************************************************/
135097 +struct query_wq_lengths_data_s {
135098 + union {
135099 + u16 channel_wq; /* ignores wq (3 lsbits) */
135100 + struct {
135101 + u16 id:13; /* qm_channel */
135102 + u16 __reserved:3;
135103 + } __packed channel;
135104 + };
135105 +};
135106 +static struct query_wq_lengths_data_s query_wq_lengths_data;
135107 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
135108 +{
135109 + int ret;
135110 + struct qm_mcr_querywq wq;
135111 + int i;
135112 +
135113 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
135114 + wq.channel.id = query_wq_lengths_data.channel.id;
135115 + ret = qman_query_wq(0, &wq);
135116 + if (ret)
135117 + return ret;
135118 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
135119 + for (i = 0; i < 8; i++)
135120 + /* mask out upper 4 bits since they are not part of length */
135121 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
135122 + return 0;
135123 +}
135124 +
135125 +static int query_wq_lengths_open(struct inode *inode,
135126 + struct file *file)
135127 +{
135128 + return single_open(file, query_wq_lengths_show, NULL);
135129 +}
135130 +
135131 +static ssize_t query_wq_lengths_write(struct file *f,
135132 + const char __user *buf, size_t count, loff_t *off)
135133 +{
135134 + int ret;
135135 + unsigned long val;
135136 +
135137 + ret = user_input_convert(buf, count, &val);
135138 + if (ret)
135139 + return ret;
135140 + if (val > 0xfff8)
135141 + return -EINVAL;
135142 + query_wq_lengths_data.channel.id = (u16)val;
135143 + return count;
135144 +}
135145 +
135146 +static const struct file_operations query_wq_lengths_fops = {
135147 + .owner = THIS_MODULE,
135148 + .open = query_wq_lengths_open,
135149 + .read = seq_read,
135150 + .write = query_wq_lengths_write,
135151 + .release = single_release,
135152 +};
135153 +
135154 +/*******************************************************************************
135155 + * Query CGR
135156 + ******************************************************************************/
135157 +struct query_cgr_s {
135158 + u8 cgid;
135159 +};
135160 +static struct query_cgr_s query_cgr_data;
135161 +
135162 +static int query_cgr_show(struct seq_file *file, void *offset)
135163 +{
135164 + int ret;
135165 + struct qm_mcr_querycgr cgrd;
135166 + struct qman_cgr cgr;
135167 + int i, j;
135168 + u32 mask;
135169 +
135170 + memset(&cgr, 0, sizeof(cgr));
135171 + memset(&cgrd, 0, sizeof(cgrd));
135172 + cgr.cgrid = query_cgr_data.cgid;
135173 + ret = qman_query_cgr(&cgr, &cgrd);
135174 + if (ret)
135175 + return ret;
135176 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
135177 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135178 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
135179 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
135180 + cgrd.cgr.wr_parm_g.Pn);
135181 +
135182 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135183 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
135184 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
135185 + cgrd.cgr.wr_parm_y.Pn);
135186 +
135187 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135188 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
135189 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
135190 + cgrd.cgr.wr_parm_r.Pn);
135191 +
135192 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
135193 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
135194 +
135195 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
135196 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
135197 + seq_puts(file, " cscn_targ_dcp:\n");
135198 + mask = 0x80000000;
135199 + for (i = 0; i < 32; i++) {
135200 + if (cgrd.cgr.cscn_targ & mask)
135201 + seq_printf(file, " send CSCN to dcp %u\n",
135202 + (31 - i));
135203 + mask >>= 1;
135204 + }
135205 +
135206 + seq_puts(file, " cscn_targ_swp:\n");
135207 + for (i = 0; i < 4; i++) {
135208 + mask = 0x80000000;
135209 + for (j = 0; j < 32; j++) {
135210 + if (cgrd.cscn_targ_swp[i] & mask)
135211 + seq_printf(file, " send CSCN to swp"
135212 + " %u\n", (127 - (i * 32) - j));
135213 + mask >>= 1;
135214 + }
135215 + }
135216 + } else {
135217 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
135218 + }
135219 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
135220 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
135221 +
135222 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
135223 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
135224 +
135225 + seq_printf(file, " mode: %s\n",
135226 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
135227 + "frame count" : "byte count");
135228 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
135229 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
135230 +
135231 + return 0;
135232 +}
135233 +
135234 +static int query_cgr_open(struct inode *inode, struct file *file)
135235 +{
135236 + return single_open(file, query_cgr_show, NULL);
135237 +}
135238 +
135239 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
135240 + size_t count, loff_t *off)
135241 +{
135242 + int ret;
135243 + unsigned long val;
135244 +
135245 + ret = user_input_convert(buf, count, &val);
135246 + if (ret)
135247 + return ret;
135248 + if (val > 0xff)
135249 + return -EINVAL;
135250 + query_cgr_data.cgid = (u8)val;
135251 + return count;
135252 +}
135253 +
135254 +static const struct file_operations query_cgr_fops = {
135255 + .owner = THIS_MODULE,
135256 + .open = query_cgr_open,
135257 + .read = seq_read,
135258 + .write = query_cgr_write,
135259 + .release = single_release,
135260 +};
135261 +
135262 +/*******************************************************************************
135263 + * Test Write CGR
135264 + ******************************************************************************/
135265 +struct test_write_cgr_s {
135266 + u64 i_bcnt;
135267 + u8 cgid;
135268 +};
135269 +static struct test_write_cgr_s test_write_cgr_data;
135270 +
135271 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
135272 +{
135273 + int ret;
135274 + struct qm_mcr_cgrtestwrite result;
135275 + struct qman_cgr cgr;
135276 + u64 i_bcnt;
135277 +
135278 + memset(&cgr, 0, sizeof(struct qman_cgr));
135279 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
135280 + cgr.cgrid = test_write_cgr_data.cgid;
135281 + i_bcnt = test_write_cgr_data.i_bcnt;
135282 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
135283 + if (ret)
135284 + return ret;
135285 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
135286 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135287 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
135288 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
135289 + result.cgr.wr_parm_g.Pn);
135290 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135291 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
135292 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
135293 + result.cgr.wr_parm_y.Pn);
135294 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135295 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
135296 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
135297 + result.cgr.wr_parm_r.Pn);
135298 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
135299 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
135300 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
135301 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
135302 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
135303 + seq_printf(file, " cs: %u\n", result.cgr.cs);
135304 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
135305 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
135306 +
135307 + /* Add Mode for Si 2 */
135308 + seq_printf(file, " mode: %s\n",
135309 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
135310 + "frame count" : "byte count");
135311 +
135312 + seq_printf(file, " i_bcnt: %llu\n",
135313 + qm_mcr_cgrtestwrite_i_get64(&result));
135314 + seq_printf(file, " a_bcnt: %llu\n",
135315 + qm_mcr_cgrtestwrite_a_get64(&result));
135316 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
135317 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
135318 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
135319 + return 0;
135320 +}
135321 +
135322 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
135323 +{
135324 + return single_open(file, testwrite_cgr_show, NULL);
135325 +}
135326 +
135327 +static const struct file_operations testwrite_cgr_fops = {
135328 + .owner = THIS_MODULE,
135329 + .open = testwrite_cgr_open,
135330 + .read = seq_read,
135331 + .release = single_release,
135332 +};
135333 +
135334 +
135335 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
135336 +{
135337 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
135338 + return 0;
135339 +}
135340 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
135341 +{
135342 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
135343 +}
135344 +
135345 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
135346 + size_t count, loff_t *off)
135347 +{
135348 + int ret;
135349 + unsigned long val;
135350 +
135351 + ret = user_input_convert(buf, count, &val);
135352 + if (ret)
135353 + return ret;
135354 + test_write_cgr_data.i_bcnt = val;
135355 + return count;
135356 +}
135357 +
135358 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
135359 + .owner = THIS_MODULE,
135360 + .open = testwrite_cgr_ibcnt_open,
135361 + .read = seq_read,
135362 + .write = testwrite_cgr_ibcnt_write,
135363 + .release = single_release,
135364 +};
135365 +
135366 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
135367 +{
135368 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
135369 + return 0;
135370 +}
135371 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
135372 +{
135373 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
135374 +}
135375 +
135376 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
135377 + size_t count, loff_t *off)
135378 +{
135379 + int ret;
135380 + unsigned long val;
135381 +
135382 + ret = user_input_convert(buf, count, &val);
135383 + if (ret)
135384 + return ret;
135385 + if (val > 0xff)
135386 + return -EINVAL;
135387 + test_write_cgr_data.cgid = (u8)val;
135388 + return count;
135389 +}
135390 +
135391 +static const struct file_operations teswrite_cgr_cgrid_fops = {
135392 + .owner = THIS_MODULE,
135393 + .open = testwrite_cgr_cgrid_open,
135394 + .read = seq_read,
135395 + .write = testwrite_cgr_cgrid_write,
135396 + .release = single_release,
135397 +};
135398 +
135399 +/*******************************************************************************
135400 + * Query Congestion State
135401 + ******************************************************************************/
135402 +static int query_congestion_show(struct seq_file *file, void *offset)
135403 +{
135404 + int ret;
135405 + struct qm_mcr_querycongestion cs;
135406 + int i, j, in_cong = 0;
135407 + u32 mask;
135408 +
135409 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
135410 + ret = qman_query_congestion(&cs);
135411 + if (ret)
135412 + return ret;
135413 + seq_puts(file, "Query Congestion Result\n");
135414 + for (i = 0; i < 8; i++) {
135415 + mask = 0x80000000;
135416 + for (j = 0; j < 32; j++) {
135417 + if (cs.state.__state[i] & mask) {
135418 + in_cong = 1;
135419 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
135420 + "in congestion");
135421 + }
135422 + mask >>= 1;
135423 + }
135424 + }
135425 + if (!in_cong)
135426 + seq_puts(file, " All congestion groups not congested.\n");
135427 + return 0;
135428 +}
135429 +
135430 +static int query_congestion_open(struct inode *inode, struct file *file)
135431 +{
135432 + return single_open(file, query_congestion_show, NULL);
135433 +}
135434 +
135435 +static const struct file_operations query_congestion_fops = {
135436 + .owner = THIS_MODULE,
135437 + .open = query_congestion_open,
135438 + .read = seq_read,
135439 + .release = single_release,
135440 +};
135441 +
135442 +/*******************************************************************************
135443 + * Query CCGR
135444 + ******************************************************************************/
135445 +struct query_ccgr_s {
135446 + u32 ccgid;
135447 +};
135448 +static struct query_ccgr_s query_ccgr_data;
135449 +
135450 +static int query_ccgr_show(struct seq_file *file, void *offset)
135451 +{
135452 + int ret;
135453 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
135454 + struct qm_mcc_ceetm_ccgr_query query_opts;
135455 + int i, j;
135456 + u32 mask;
135457 +
135458 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
135459 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
135460 +
135461 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
135462 + return -EINVAL;
135463 +
135464 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
135465 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
135466 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
135467 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
135468 + if (ret)
135469 + return ret;
135470 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
135471 + query_opts.dcpid);
135472 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135473 + ccgr_query.cm_query.wr_parm_g.MA,
135474 + ccgr_query.cm_query.wr_parm_g.Mn,
135475 + ccgr_query.cm_query.wr_parm_g.SA,
135476 + ccgr_query.cm_query.wr_parm_g.Sn,
135477 + ccgr_query.cm_query.wr_parm_g.Pn);
135478 +
135479 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135480 + ccgr_query.cm_query.wr_parm_y.MA,
135481 + ccgr_query.cm_query.wr_parm_y.Mn,
135482 + ccgr_query.cm_query.wr_parm_y.SA,
135483 + ccgr_query.cm_query.wr_parm_y.Sn,
135484 + ccgr_query.cm_query.wr_parm_y.Pn);
135485 +
135486 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135487 + ccgr_query.cm_query.wr_parm_r.MA,
135488 + ccgr_query.cm_query.wr_parm_r.Mn,
135489 + ccgr_query.cm_query.wr_parm_r.SA,
135490 + ccgr_query.cm_query.wr_parm_r.Sn,
135491 + ccgr_query.cm_query.wr_parm_r.Pn);
135492 +
135493 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
135494 + ccgr_query.cm_query.ctl_wr_en_g,
135495 + ccgr_query.cm_query.ctl_wr_en_y,
135496 + ccgr_query.cm_query.ctl_wr_en_r);
135497 +
135498 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
135499 + seq_puts(file, " cscn_targ_dcp:\n");
135500 + mask = 0x80000000;
135501 + for (i = 0; i < 32; i++) {
135502 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
135503 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
135504 + mask >>= 1;
135505 + }
135506 +
135507 + seq_puts(file, " cscn_targ_swp:\n");
135508 + for (i = 0; i < 4; i++) {
135509 + mask = 0x80000000;
135510 + for (j = 0; j < 32; j++) {
135511 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
135512 + seq_printf(file, " send CSCN to swp"
135513 + "%u\n", (127 - (i * 32) - j));
135514 + mask >>= 1;
135515 + }
135516 + }
135517 +
135518 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
135519 +
135520 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
135521 + ccgr_query.cm_query.cs_thres.TA,
135522 + ccgr_query.cm_query.cs_thres.Tn);
135523 +
135524 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
135525 + ccgr_query.cm_query.cs_thres_x.TA,
135526 + ccgr_query.cm_query.cs_thres_x.Tn);
135527 +
135528 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
135529 + ccgr_query.cm_query.td_thres.TA,
135530 + ccgr_query.cm_query.td_thres.Tn);
135531 +
135532 + seq_printf(file, " mode: %s\n",
135533 + (ccgr_query.cm_query.ctl_mode &
135534 + QMAN_CGR_MODE_FRAME) ?
135535 + "frame count" : "byte count");
135536 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
135537 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
135538 +
135539 + return 0;
135540 +}
135541 +
135542 +static int query_ccgr_open(struct inode *inode, struct file *file)
135543 +{
135544 + return single_open(file, query_ccgr_show, NULL);
135545 +}
135546 +
135547 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
135548 + size_t count, loff_t *off)
135549 +{
135550 + int ret;
135551 + unsigned long val;
135552 +
135553 + ret = user_input_convert(buf, count, &val);
135554 + if (ret)
135555 + return ret;
135556 + query_ccgr_data.ccgid = val;
135557 + return count;
135558 +}
135559 +
135560 +static const struct file_operations query_ccgr_fops = {
135561 + .owner = THIS_MODULE,
135562 + .open = query_ccgr_open,
135563 + .read = seq_read,
135564 + .write = query_ccgr_write,
135565 + .release = single_release,
135566 +};
135567 +/*******************************************************************************
135568 + * QMan register
135569 + ******************************************************************************/
135570 +struct qman_register_s {
135571 + u32 val;
135572 +};
135573 +static struct qman_register_s qman_register_data;
135574 +
135575 +static void init_ccsrmempeek(void)
135576 +{
135577 + struct device_node *dn;
135578 + const u32 *regaddr_p;
135579 +
135580 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
135581 + if (!dn) {
135582 + pr_info("No fsl,qman node\n");
135583 + return;
135584 + }
135585 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
135586 + if (!regaddr_p) {
135587 + of_node_put(dn);
135588 + return;
135589 + }
135590 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
135591 + of_node_put(dn);
135592 +}
135593 +/* This function provides access to QMan ccsr memory map */
135594 +static int qman_ccsrmempeek(u32 *val, u32 offset)
135595 +{
135596 + void __iomem *addr;
135597 + u64 phys_addr;
135598 +
135599 + if (!qman_ccsr_start)
135600 + return -EINVAL;
135601 +
135602 + if (offset > (qman_ccsr_size - sizeof(u32)))
135603 + return -EINVAL;
135604 +
135605 + phys_addr = qman_ccsr_start + offset;
135606 + addr = ioremap(phys_addr, sizeof(u32));
135607 + if (!addr) {
135608 + pr_err("ccsrmempeek, ioremap failed\n");
135609 + return -EINVAL;
135610 + }
135611 + *val = in_be32(addr);
135612 + iounmap(addr);
135613 + return 0;
135614 +}
135615 +
135616 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
135617 +{
135618 + u32 b;
135619 +
135620 + qman_ccsrmempeek(&b, qman_register_data.val);
135621 + seq_printf(file, "QMan register offset = 0x%x\n",
135622 + qman_register_data.val);
135623 + seq_printf(file, "value = 0x%08x\n", b);
135624 +
135625 + return 0;
135626 +}
135627 +
135628 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
135629 +{
135630 + return single_open(file, qman_ccsrmempeek_show, NULL);
135631 +}
135632 +
135633 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
135634 + size_t count, loff_t *off)
135635 +{
135636 + int ret;
135637 + unsigned long val;
135638 +
135639 + ret = user_input_convert(buf, count, &val);
135640 + if (ret)
135641 + return ret;
135642 + /* multiple of 4 */
135643 + if (val > (qman_ccsr_size - sizeof(u32))) {
135644 + pr_info("Input 0x%lx > 0x%llx\n",
135645 + val, (qman_ccsr_size - sizeof(u32)));
135646 + return -EINVAL;
135647 + }
135648 + if (val & 0x3) {
135649 + pr_info("Input 0x%lx not multiple of 4\n", val);
135650 + return -EINVAL;
135651 + }
135652 + qman_register_data.val = val;
135653 + return count;
135654 +}
135655 +
135656 +static const struct file_operations qman_ccsrmempeek_fops = {
135657 + .owner = THIS_MODULE,
135658 + .open = qman_ccsrmempeek_open,
135659 + .read = seq_read,
135660 + .write = qman_ccsrmempeek_write,
135661 +};
135662 +
135663 +/*******************************************************************************
135664 + * QMan state
135665 + ******************************************************************************/
135666 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
135667 +{
135668 + struct qm_mcr_queryfq_np np;
135669 + struct qman_fq fq;
135670 + struct line_buffer_fq line_buf;
135671 + int ret, i;
135672 + u8 *state = file->private;
135673 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
135674 +
135675 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
135676 + memset(&line_buf, 0, sizeof(line_buf));
135677 +
135678 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
135679 +
135680 + for (i = 1; i < fqid_max; i++) {
135681 + fq.fqid = i;
135682 + ret = qman_query_fq_np(&fq, &np);
135683 + if (ret)
135684 + return ret;
135685 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
135686 + add_to_line_buffer(&line_buf, fq.fqid, file);
135687 + /* Keep a summary count of all states */
135688 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
135689 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
135690 + }
135691 + flush_line_buffer(&line_buf, file);
135692 +
135693 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
135694 + seq_printf(file, "%s count = %u\n", state_txt[i],
135695 + qm_fq_state_cnt[i]);
135696 + }
135697 + return 0;
135698 +}
135699 +
135700 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
135701 +{
135702 + return single_open(file, qman_fqd_state_show, inode->i_private);
135703 +}
135704 +
135705 +static const struct file_operations qman_fqd_state_fops = {
135706 + .owner = THIS_MODULE,
135707 + .open = qman_fqd_state_open,
135708 + .read = seq_read,
135709 +};
135710 +
135711 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
135712 +{
135713 + struct qm_fqd fqd;
135714 + struct qman_fq fq;
135715 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
135716 + int ret, i;
135717 + struct mask_filter_s *data = file->private;
135718 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
135719 + struct line_buffer_fq line_buf;
135720 +
135721 + memset(&line_buf, 0, sizeof(line_buf));
135722 + seq_printf(file, "List of fq ids with: %s :%s\n",
135723 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
135724 + for (i = 1; i < fqid_max; i++) {
135725 + fq.fqid = i;
135726 + memset(&fqd, 0, sizeof(struct qm_fqd));
135727 + ret = qman_query_fq(&fq, &fqd);
135728 + if (ret)
135729 + return ret;
135730 + if (data->filter) {
135731 + if (fqd.fq_ctrl & data->mask)
135732 + add_to_line_buffer(&line_buf, fq.fqid, file);
135733 + } else {
135734 + if (!(fqd.fq_ctrl & data->mask))
135735 + add_to_line_buffer(&line_buf, fq.fqid, file);
135736 + }
135737 + if (fqd.fq_ctrl & data->mask)
135738 + fq_en_cnt++;
135739 + else
135740 + fq_di_cnt++;
135741 + }
135742 + flush_line_buffer(&line_buf, file);
135743 +
135744 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
135745 + ctrl_txt, fq_en_cnt);
135746 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
135747 + ctrl_txt, fq_di_cnt);
135748 + return 0;
135749 +}
135750 +
135751 +/*******************************************************************************
135752 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
135753 + ******************************************************************************/
135754 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
135755 +{
135756 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
135757 +}
135758 +
135759 +static const struct file_operations qman_fqd_ctrl_fops = {
135760 + .owner = THIS_MODULE,
135761 + .open = qman_fqd_ctrl_open,
135762 + .read = seq_read,
135763 +};
135764 +
135765 +/*******************************************************************************
135766 + * QMan ctrl summary
135767 + ******************************************************************************/
135768 +/*******************************************************************************
135769 + * QMan summary state
135770 + ******************************************************************************/
135771 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
135772 +{
135773 + struct qm_mcr_queryfq_np np;
135774 + struct qman_fq fq;
135775 + int ret, i;
135776 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
135777 +
135778 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
135779 +
135780 + for (i = 1; i < fqid_max; i++) {
135781 + fq.fqid = i;
135782 + ret = qman_query_fq_np(&fq, &np);
135783 + if (ret)
135784 + return ret;
135785 + /* Keep a summary count of all states */
135786 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
135787 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
135788 + }
135789 +
135790 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
135791 + seq_printf(file, "%s count = %u\n", state_txt[i],
135792 + qm_fq_state_cnt[i]);
135793 + }
135794 + return 0;
135795 +}
135796 +
135797 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
135798 +{
135799 + struct qm_fqd fqd;
135800 + struct qman_fq fq;
135801 + int ret, i , j;
135802 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
135803 +
135804 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
135805 +
135806 + for (i = 1; i < fqid_max; i++) {
135807 + memset(&fqd, 0, sizeof(struct qm_fqd));
135808 + fq.fqid = i;
135809 + ret = qman_query_fq(&fq, &fqd);
135810 + if (ret)
135811 + return ret;
135812 + /* Keep a summary count of all states */
135813 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
135814 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
135815 + mask_filter[j].mask)
135816 + qm_prog_cnt[j/2]++;
135817 + }
135818 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
135819 + seq_printf(file, "%s count = %u\n",
135820 + get_fqd_ctrl_text(mask_filter[i*2].mask),
135821 + qm_prog_cnt[i]);
135822 + }
135823 + return 0;
135824 +}
135825 +
135826 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
135827 +{
135828 + int ret;
135829 +
135830 + /* Display summary of non programmable fields */
135831 + ret = qman_fqd_non_prog_summary_show(file, offset);
135832 + if (ret)
135833 + return ret;
135834 + seq_puts(file, "-----------------------------------------\n");
135835 + /* Display programmable fields */
135836 + ret = qman_fqd_prog_summary_show(file, offset);
135837 + if (ret)
135838 + return ret;
135839 + return 0;
135840 +}
135841 +
135842 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
135843 +{
135844 + return single_open(file, qman_fqd_summary_show, NULL);
135845 +}
135846 +
135847 +static const struct file_operations qman_fqd_summary_fops = {
135848 + .owner = THIS_MODULE,
135849 + .open = qman_fqd_summary_open,
135850 + .read = seq_read,
135851 +};
135852 +
135853 +/*******************************************************************************
135854 + * QMan destination work queue
135855 + ******************************************************************************/
135856 +struct qman_dest_wq_s {
135857 + u16 wq_id;
135858 +};
135859 +static struct qman_dest_wq_s qman_dest_wq_data = {
135860 + .wq_id = 0,
135861 +};
135862 +
135863 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
135864 +{
135865 + struct qm_fqd fqd;
135866 + struct qman_fq fq;
135867 + int ret, i;
135868 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
135869 + struct line_buffer_fq line_buf;
135870 +
135871 + memset(&line_buf, 0, sizeof(line_buf));
135872 + /* use vmalloc : need to allocate large memory region and don't
135873 + * require the memory to be physically contiguous. */
135874 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
135875 + if (!wq)
135876 + return -ENOMEM;
135877 +
135878 + seq_printf(file, "List of fq ids with destination work queue id"
135879 + " = 0x%x\n", wq_id);
135880 +
135881 + for (i = 1; i < fqid_max; i++) {
135882 + fq.fqid = i;
135883 + memset(&fqd, 0, sizeof(struct qm_fqd));
135884 + ret = qman_query_fq(&fq, &fqd);
135885 + if (ret) {
135886 + vfree(wq);
135887 + return ret;
135888 + }
135889 + if (wq_id == fqd.dest_wq)
135890 + add_to_line_buffer(&line_buf, fq.fqid, file);
135891 + wq[fqd.dest_wq]++;
135892 + }
135893 + flush_line_buffer(&line_buf, file);
135894 +
135895 + seq_puts(file, "Summary of all FQD destination work queue values\n");
135896 + for (i = 0; i < 0xFFFF; i++) {
135897 + if (wq[i])
135898 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
135899 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
135900 + }
135901 + vfree(wq);
135902 + return 0;
135903 +}
135904 +
135905 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
135906 + size_t count, loff_t *off)
135907 +{
135908 + int ret;
135909 + unsigned long val;
135910 +
135911 + ret = user_input_convert(buf, count, &val);
135912 + if (ret)
135913 + return ret;
135914 + if (val > 0xFFFF)
135915 + return -EINVAL;
135916 + qman_dest_wq_data.wq_id = val;
135917 + return count;
135918 +}
135919 +
135920 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
135921 +{
135922 + return single_open(file, qman_fqd_dest_wq_show, NULL);
135923 +}
135924 +
135925 +static const struct file_operations qman_fqd_dest_wq_fops = {
135926 + .owner = THIS_MODULE,
135927 + .open = qman_fqd_dest_wq_open,
135928 + .read = seq_read,
135929 + .write = qman_fqd_dest_wq_write,
135930 +};
135931 +
135932 +/*******************************************************************************
135933 + * QMan Intra-Class Scheduling Credit
135934 + ******************************************************************************/
135935 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
135936 +{
135937 + struct qm_fqd fqd;
135938 + struct qman_fq fq;
135939 + int ret, i;
135940 + u32 fq_cnt = 0;
135941 + struct line_buffer_fq line_buf;
135942 +
135943 + memset(&line_buf, 0, sizeof(line_buf));
135944 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
135945 + "\n");
135946 +
135947 + for (i = 1; i < fqid_max; i++) {
135948 + fq.fqid = i;
135949 + memset(&fqd, 0, sizeof(struct qm_fqd));
135950 + ret = qman_query_fq(&fq, &fqd);
135951 + if (ret)
135952 + return ret;
135953 + if (fqd.ics_cred > 0) {
135954 + add_to_line_buffer(&line_buf, fq.fqid, file);
135955 + fq_cnt++;
135956 + }
135957 + }
135958 + flush_line_buffer(&line_buf, file);
135959 +
135960 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
135961 + return 0;
135962 +}
135963 +
135964 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
135965 +{
135966 + return single_open(file, qman_fqd_cred_show, NULL);
135967 +}
135968 +
135969 +static const struct file_operations qman_fqd_cred_fops = {
135970 + .owner = THIS_MODULE,
135971 + .open = qman_fqd_cred_open,
135972 + .read = seq_read,
135973 +};
135974 +
135975 +/*******************************************************************************
135976 + * Class Queue Fields
135977 + ******************************************************************************/
135978 +struct query_cq_fields_data_s {
135979 + u32 cqid;
135980 +};
135981 +
135982 +static struct query_cq_fields_data_s query_cq_fields_data = {
135983 + .cqid = 1,
135984 +};
135985 +
135986 +static int query_cq_fields_show(struct seq_file *file, void *offset)
135987 +{
135988 + int ret;
135989 + struct qm_mcr_ceetm_cq_query query_result;
135990 + unsigned int cqid;
135991 + unsigned int portal;
135992 +
135993 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
135994 + return -EINVAL;
135995 +
135996 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
135997 + portal = query_cq_fields_data.cqid >> 24;
135998 + if (portal > qm_dc_portal_fman1)
135999 + return -EINVAL;
136000 +
136001 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
136002 + if (ret)
136003 + return ret;
136004 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
136005 + cqid, portal);
136006 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
136007 + seq_printf(file, " state: %u\n", query_result.state);
136008 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
136009 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
136010 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
136011 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
136012 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
136013 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
136014 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
136015 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
136016 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
136017 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
136018 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
136019 +
136020 + return 0;
136021 +}
136022 +
136023 +static int query_cq_fields_open(struct inode *inode,
136024 + struct file *file)
136025 +{
136026 + return single_open(file, query_cq_fields_show, NULL);
136027 +}
136028 +
136029 +static ssize_t query_cq_fields_write(struct file *f,
136030 + const char __user *buf, size_t count, loff_t *off)
136031 +{
136032 + int ret;
136033 + unsigned long val;
136034 +
136035 + ret = user_input_convert(buf, count, &val);
136036 + if (ret)
136037 + return ret;
136038 + query_cq_fields_data.cqid = (u32)val;
136039 + return count;
136040 +}
136041 +
136042 +static const struct file_operations query_cq_fields_fops = {
136043 + .owner = THIS_MODULE,
136044 + .open = query_cq_fields_open,
136045 + .read = seq_read,
136046 + .write = query_cq_fields_write,
136047 + .release = single_release,
136048 +};
136049 +
136050 +/*******************************************************************************
136051 + * READ CEETM_XSFDR_IN_USE
136052 + ******************************************************************************/
136053 +struct query_ceetm_xsfdr_data_s {
136054 + enum qm_dc_portal dcp_portal;
136055 +};
136056 +
136057 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
136058 +
136059 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
136060 +{
136061 + int ret;
136062 + unsigned int xsfdr_in_use;
136063 + enum qm_dc_portal portal;
136064 +
136065 +
136066 + if (qman_ip_rev < QMAN_REV31)
136067 + return -EINVAL;
136068 +
136069 + portal = query_ceetm_xsfdr_data.dcp_portal;
136070 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
136071 + if (ret) {
136072 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
136073 + portal);
136074 + return ret;
136075 + }
136076 +
136077 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
136078 + (xsfdr_in_use & 0x1FFF));
136079 + return 0;
136080 +}
136081 +
136082 +static int query_ceetm_xsfdr_open(struct inode *inode,
136083 + struct file *file)
136084 +{
136085 + return single_open(file, query_ceetm_xsfdr_show, NULL);
136086 +}
136087 +
136088 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
136089 + const char __user *buf, size_t count, loff_t *off)
136090 +{
136091 + int ret;
136092 + unsigned long val;
136093 +
136094 + ret = user_input_convert(buf, count, &val);
136095 + if (ret)
136096 + return ret;
136097 + if (val > qm_dc_portal_fman1)
136098 + return -EINVAL;
136099 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
136100 + return count;
136101 +}
136102 +
136103 +static const struct file_operations query_ceetm_xsfdr_fops = {
136104 + .owner = THIS_MODULE,
136105 + .open = query_ceetm_xsfdr_open,
136106 + .read = seq_read,
136107 + .write = query_ceetm_xsfdr_write,
136108 + .release = single_release,
136109 +};
136110 +
136111 +/* helper macros used in qman_debugfs_module_init */
136112 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
136113 + do { \
136114 + d = debugfs_create_file(name, \
136115 + mode, parent, \
136116 + data, \
136117 + fops); \
136118 + if (d == NULL) { \
136119 + ret = -ENOMEM; \
136120 + goto _return; \
136121 + } \
136122 + } while (0)
136123 +
136124 +/* dfs_root as parent */
136125 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
136126 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
136127 +
136128 +/* fqd_root as parent */
136129 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
136130 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
136131 +
136132 +/* fqd state */
136133 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
136134 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
136135 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
136136 +
136137 +static int __init qman_debugfs_module_init(void)
136138 +{
136139 + int ret = 0;
136140 + struct dentry *d, *fqd_root;
136141 + u32 reg;
136142 +
136143 + fqid_max = 0;
136144 + init_ccsrmempeek();
136145 + if (qman_ccsr_start) {
136146 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
136147 + /* extract the size of the FQD window */
136148 + reg = reg & 0x3f;
136149 + /* calculate valid frame queue descriptor range */
136150 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
136151 + }
136152 + }
136153 + dfs_root = debugfs_create_dir("qman", NULL);
136154 + fqd_root = debugfs_create_dir("fqd", dfs_root);
136155 + if (dfs_root == NULL || fqd_root == NULL) {
136156 + ret = -ENOMEM;
136157 + pr_err("Cannot create qman/fqd debugfs dir\n");
136158 + goto _return;
136159 + }
136160 + if (fqid_max) {
136161 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
136162 + NULL, &qman_ccsrmempeek_fops);
136163 + }
136164 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
136165 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
136166 +
136167 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
136168 + &query_fq_fields_data, &query_fq_fields_fops);
136169 +
136170 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
136171 + &query_wq_lengths_data, &query_wq_lengths_fops);
136172 +
136173 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
136174 + &query_cgr_data, &query_cgr_fops);
136175 +
136176 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
136177 + NULL, &query_congestion_fops);
136178 +
136179 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
136180 + NULL, &testwrite_cgr_fops);
136181 +
136182 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
136183 + NULL, &teswrite_cgr_cgrid_fops);
136184 +
136185 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
136186 + NULL, &teswrite_cgr_ibcnt_fops);
136187 +
136188 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
136189 + &query_ccgr_data, &query_ccgr_fops);
136190 + /* Create files with fqd_root as parent */
136191 +
136192 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
136193 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
136194 +
136195 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
136196 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
136197 + &qman_fqd_state_fops);
136198 +
136199 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
136200 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
136201 + &qman_fqd_state_fops);
136202 +
136203 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
136204 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
136205 + &qman_fqd_state_fops);
136206 +
136207 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
136208 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
136209 + &qman_fqd_state_fops);
136210 +
136211 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
136212 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
136213 + &qman_fqd_state_fops);
136214 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
136215 + &query_cq_fields_data, &query_cq_fields_fops);
136216 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
136217 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
136218 +
136219 +
136220 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
136221 +
136222 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
136223 +
136224 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
136225 +
136226 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
136227 +
136228 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
136229 +
136230 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
136231 +
136232 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
136233 +
136234 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
136235 +
136236 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
136237 +
136238 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
136239 +
136240 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
136241 +
136242 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
136243 +
136244 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
136245 +
136246 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
136247 +
136248 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
136249 +
136250 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
136251 +
136252 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
136253 +
136254 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
136255 +
136256 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
136257 + NULL, &qman_fqd_summary_fops);
136258 +
136259 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
136260 + NULL, &qman_fqd_dest_wq_fops);
136261 +
136262 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
136263 + NULL, &qman_fqd_cred_fops);
136264 +
136265 + return 0;
136266 +
136267 +_return:
136268 + debugfs_remove_recursive(dfs_root);
136269 + return ret;
136270 +}
136271 +
136272 +static void __exit qman_debugfs_module_exit(void)
136273 +{
136274 + debugfs_remove_recursive(dfs_root);
136275 +}
136276 +
136277 +module_init(qman_debugfs_module_init);
136278 +module_exit(qman_debugfs_module_exit);
136279 +MODULE_LICENSE("Dual BSD/GPL");
136280 --- /dev/null
136281 +++ b/drivers/staging/fsl_qbman/qman_driver.c
136282 @@ -0,0 +1,961 @@
136283 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
136284 + *
136285 + * Redistribution and use in source and binary forms, with or without
136286 + * modification, are permitted provided that the following conditions are met:
136287 + * * Redistributions of source code must retain the above copyright
136288 + * notice, this list of conditions and the following disclaimer.
136289 + * * Redistributions in binary form must reproduce the above copyright
136290 + * notice, this list of conditions and the following disclaimer in the
136291 + * documentation and/or other materials provided with the distribution.
136292 + * * Neither the name of Freescale Semiconductor nor the
136293 + * names of its contributors may be used to endorse or promote products
136294 + * derived from this software without specific prior written permission.
136295 + *
136296 + *
136297 + * ALTERNATIVELY, this software may be distributed under the terms of the
136298 + * GNU General Public License ("GPL") as published by the Free Software
136299 + * Foundation, either version 2 of that License or (at your option) any
136300 + * later version.
136301 + *
136302 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
136303 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
136304 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
136305 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
136306 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
136307 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
136308 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
136309 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
136310 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
136311 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
136312 + */
136313 +
136314 +#include "qman_private.h"
136315 +
136316 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
136317 +#ifdef CONFIG_HOTPLUG_CPU
136318 +#include <linux/cpu.h>
136319 +#endif
136320 +
136321 +/* Global variable containing revision id (even on non-control plane systems
136322 + * where CCSR isn't available) */
136323 +u16 qman_ip_rev;
136324 +EXPORT_SYMBOL(qman_ip_rev);
136325 +u8 qman_ip_cfg;
136326 +EXPORT_SYMBOL(qman_ip_cfg);
136327 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
136328 +EXPORT_SYMBOL(qm_channel_pool1);
136329 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
136330 +EXPORT_SYMBOL(qm_channel_caam);
136331 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
136332 +EXPORT_SYMBOL(qm_channel_pme);
136333 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
136334 +EXPORT_SYMBOL(qm_channel_dce);
136335 +u16 qman_portal_max;
136336 +EXPORT_SYMBOL(qman_portal_max);
136337 +
136338 +u32 qman_clk;
136339 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
136340 +/* the qman ceetm instances on the given SoC */
136341 +u8 num_ceetms;
136342 +
136343 +/* For these variables, and the portal-initialisation logic, the
136344 + * comments in bman_driver.c apply here so won't be repeated. */
136345 +static struct qman_portal *shared_portals[NR_CPUS];
136346 +static int num_shared_portals;
136347 +static int shared_portals_idx;
136348 +static LIST_HEAD(unused_pcfgs);
136349 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
136350 +
136351 +/* A SDQCR mask comprising all the available/visible pool channels */
136352 +static u32 pools_sdqcr;
136353 +
136354 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
136355 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
136356 +#define STR_FQID_RANGE "fsl,fqid-range"
136357 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
136358 +#define STR_CGRID_RANGE "fsl,cgrid-range"
136359 +
136360 +/* A "fsl,fqid-range" node; release the given range to the allocator */
136361 +static __init int fsl_fqid_range_init(struct device_node *node)
136362 +{
136363 + int ret;
136364 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
136365 + if (!range) {
136366 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
136367 + return -EINVAL;
136368 + }
136369 + if (ret != 8) {
136370 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
136371 + return -EINVAL;
136372 + }
136373 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136374 + pr_info("Qman: FQID allocator includes range %d:%d\n",
136375 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136376 + return 0;
136377 +}
136378 +
136379 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
136380 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
136381 +{
136382 + int ret;
136383 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
136384 + if (!chanid) {
136385 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
136386 + return -EINVAL;
136387 + }
136388 + if (ret != 8) {
136389 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
136390 + return -EINVAL;
136391 + }
136392 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
136393 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
136394 + return 0;
136395 +}
136396 +
136397 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
136398 +static __init int fsl_pool_channel_range_init(struct device_node *node)
136399 +{
136400 + int ret;
136401 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
136402 + if (!chanid) {
136403 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
136404 + return -EINVAL;
136405 + }
136406 + if (ret != 8) {
136407 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
136408 + return -EINVAL;
136409 + }
136410 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
136411 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
136412 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
136413 + return 0;
136414 +}
136415 +
136416 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
136417 +static __init int fsl_cgrid_range_init(struct device_node *node)
136418 +{
136419 + struct qman_cgr cgr;
136420 + int ret, errors = 0;
136421 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
136422 + if (!range) {
136423 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
136424 + return -EINVAL;
136425 + }
136426 + if (ret != 8) {
136427 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
136428 + return -EINVAL;
136429 + }
136430 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136431 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
136432 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136433 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
136434 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
136435 + if (ret)
136436 + errors++;
136437 + }
136438 + if (errors)
136439 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
136440 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
136441 + return 0;
136442 +}
136443 +
136444 +static __init int fsl_ceetm_init(struct device_node *node)
136445 +{
136446 + enum qm_dc_portal dcp_portal;
136447 + struct qm_ceetm_sp *sp;
136448 + struct qm_ceetm_lni *lni;
136449 + int ret, i;
136450 + const u32 *range;
136451 +
136452 + /* Find LFQID range */
136453 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
136454 + if (!range) {
136455 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
136456 + node->full_name);
136457 + return -EINVAL;
136458 + }
136459 + if (ret != 8) {
136460 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
136461 + " %s\n", node->full_name);
136462 + return -EINVAL;
136463 + }
136464 +
136465 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
136466 + if (dcp_portal > qm_dc_portal_fman1) {
136467 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
136468 + return -EINVAL;
136469 + }
136470 +
136471 + if (dcp_portal == qm_dc_portal_fman0)
136472 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136473 + if (dcp_portal == qm_dc_portal_fman1)
136474 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136475 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
136476 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136477 +
136478 + qman_ceetms[dcp_portal].idx = dcp_portal;
136479 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
136480 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
136481 +
136482 + /* Find Sub-portal range */
136483 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
136484 + if (!range) {
136485 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
136486 + return -EINVAL;
136487 + }
136488 + if (ret != 8) {
136489 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
136490 + node->full_name);
136491 + return -EINVAL;
136492 + }
136493 +
136494 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
136495 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
136496 + if (!sp) {
136497 + pr_err("Can't alloc memory for sub-portal %d\n",
136498 + range[0] + i);
136499 + return -ENOMEM;
136500 + }
136501 + sp->idx = be32_to_cpu(range[0]) + i;
136502 + sp->dcp_idx = dcp_portal;
136503 + sp->is_claimed = 0;
136504 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
136505 + sp++;
136506 + }
136507 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
136508 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
136509 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
136510 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
136511 +
136512 + /* Find LNI range */
136513 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
136514 + if (!range) {
136515 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
136516 + return -EINVAL;
136517 + }
136518 + if (ret != 8) {
136519 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
136520 + node->full_name);
136521 + return -EINVAL;
136522 + }
136523 +
136524 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
136525 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
136526 + if (!lni) {
136527 + pr_err("Can't alloc memory for LNI %d\n",
136528 + range[0] + i);
136529 + return -ENOMEM;
136530 + }
136531 + lni->idx = be32_to_cpu(range[0]) + i;
136532 + lni->dcp_idx = dcp_portal;
136533 + lni->is_claimed = 0;
136534 + INIT_LIST_HEAD(&lni->channels);
136535 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
136536 + lni++;
136537 + }
136538 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
136539 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
136540 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
136541 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
136542 +
136543 + /* Find CEETM channel range */
136544 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
136545 + if (!range) {
136546 + pr_err("No fsl,ceetm-channel-range in node %s\n",
136547 + node->full_name);
136548 + return -EINVAL;
136549 + }
136550 + if (ret != 8) {
136551 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
136552 + "%s\n", node->full_name);
136553 + return -EINVAL;
136554 + }
136555 +
136556 + if (dcp_portal == qm_dc_portal_fman0)
136557 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136558 + if (dcp_portal == qm_dc_portal_fman1)
136559 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136560 + pr_debug("Qman: The channel allocator of CEETM %d includes"
136561 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136562 +
136563 + /* Set CEETM PRES register */
136564 + ret = qman_ceetm_set_prescaler(dcp_portal);
136565 + if (ret)
136566 + return ret;
136567 + return 0;
136568 +}
136569 +
136570 +static void qman_get_ip_revision(struct device_node *dn)
136571 +{
136572 + u16 ip_rev = 0;
136573 + u8 ip_cfg = QMAN_REV_CFG_0;
136574 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
136575 + if (!of_device_is_available(dn))
136576 + continue;
136577 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
136578 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
136579 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
136580 + BUG_ON(1);
136581 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
136582 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
136583 + ip_rev = QMAN_REV11;
136584 + qman_portal_max = 10;
136585 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
136586 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
136587 + ip_rev = QMAN_REV12;
136588 + qman_portal_max = 10;
136589 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
136590 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
136591 + ip_rev = QMAN_REV20;
136592 + qman_portal_max = 3;
136593 + } else if (of_device_is_compatible(dn,
136594 + "fsl,qman-portal-3.0.0")) {
136595 + ip_rev = QMAN_REV30;
136596 + qman_portal_max = 50;
136597 + } else if (of_device_is_compatible(dn,
136598 + "fsl,qman-portal-3.0.1")) {
136599 + ip_rev = QMAN_REV30;
136600 + qman_portal_max = 25;
136601 + ip_cfg = QMAN_REV_CFG_1;
136602 + } else if (of_device_is_compatible(dn,
136603 + "fsl,qman-portal-3.1.0")) {
136604 + ip_rev = QMAN_REV31;
136605 + qman_portal_max = 50;
136606 + } else if (of_device_is_compatible(dn,
136607 + "fsl,qman-portal-3.1.1")) {
136608 + ip_rev = QMAN_REV31;
136609 + qman_portal_max = 25;
136610 + ip_cfg = QMAN_REV_CFG_1;
136611 + } else if (of_device_is_compatible(dn,
136612 + "fsl,qman-portal-3.1.2")) {
136613 + ip_rev = QMAN_REV31;
136614 + qman_portal_max = 18;
136615 + ip_cfg = QMAN_REV_CFG_2;
136616 + } else if (of_device_is_compatible(dn,
136617 + "fsl,qman-portal-3.1.3")) {
136618 + ip_rev = QMAN_REV31;
136619 + qman_portal_max = 10;
136620 + ip_cfg = QMAN_REV_CFG_3;
136621 + } else if (of_device_is_compatible(dn,
136622 + "fsl,qman-portal-3.2.0")) {
136623 + ip_rev = QMAN_REV32;
136624 + qman_portal_max = 10;
136625 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
136626 + } else if (of_device_is_compatible(dn,
136627 + "fsl,qman-portal-3.2.1")) {
136628 + ip_rev = QMAN_REV32;
136629 + qman_portal_max = 10;
136630 + ip_cfg = QMAN_REV_CFG_3;
136631 + } else {
136632 + pr_warn("unknown QMan version in portal node,"
136633 + "default to rev1.1\n");
136634 + ip_rev = QMAN_REV11;
136635 + qman_portal_max = 10;
136636 + }
136637 +
136638 + if (!qman_ip_rev) {
136639 + if (ip_rev) {
136640 + qman_ip_rev = ip_rev;
136641 + qman_ip_cfg = ip_cfg;
136642 + } else {
136643 + pr_warn("unknown Qman version,"
136644 + " default to rev1.1\n");
136645 + qman_ip_rev = QMAN_REV11;
136646 + qman_ip_cfg = QMAN_REV_CFG_0;
136647 + }
136648 + } else if (ip_rev && (qman_ip_rev != ip_rev))
136649 + pr_warn("Revision=0x%04x, but portal '%s' has"
136650 + " 0x%04x\n",
136651 + qman_ip_rev, dn->full_name, ip_rev);
136652 + if (qman_ip_rev == ip_rev)
136653 + break;
136654 + }
136655 +}
136656 +
136657 +/* Parse a portal node, perform generic mapping duties and return the config. It
136658 + * is not known at this stage for what purpose (or even if) the portal will be
136659 + * used. */
136660 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
136661 +{
136662 + struct qm_portal_config *pcfg;
136663 + const u32 *index_p;
136664 + u32 index, channel;
136665 + int irq, ret;
136666 + resource_size_t len;
136667 +
136668 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
136669 + if (!pcfg) {
136670 + pr_err("can't allocate portal config");
136671 + return NULL;
136672 + }
136673 +
136674 + /*
136675 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
136676 + * 'struct device' in order to get the PAMU stashing setup and the QMan
136677 + * portal [driver] won't function at all without ring stashing
136678 + *
136679 + * Making the QMan portal driver nice and proper is part of the
136680 + * upstreaming effort
136681 + */
136682 + pcfg->dev.bus = &platform_bus_type;
136683 + pcfg->dev.of_node = node;
136684 +#ifdef CONFIG_FSL_PAMU
136685 + pcfg->dev.archdata.iommu_domain = NULL;
136686 +#endif
136687 +
136688 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
136689 + &pcfg->addr_phys[DPA_PORTAL_CE]);
136690 + if (ret) {
136691 + pr_err("Can't get %s property '%s'\n", node->full_name,
136692 + "reg::CE");
136693 + goto err;
136694 + }
136695 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
136696 + &pcfg->addr_phys[DPA_PORTAL_CI]);
136697 + if (ret) {
136698 + pr_err("Can't get %s property '%s'\n", node->full_name,
136699 + "reg::CI");
136700 + goto err;
136701 + }
136702 + index_p = of_get_property(node, "cell-index", &ret);
136703 + if (!index_p || (ret != 4)) {
136704 + pr_err("Can't get %s property '%s'\n", node->full_name,
136705 + "cell-index");
136706 + goto err;
136707 + }
136708 + index = be32_to_cpu(*index_p);
136709 + if (index >= qman_portal_max) {
136710 + pr_err("QMan portal index %d is beyond max (%d)\n",
136711 + index, qman_portal_max);
136712 + goto err;
136713 + }
136714 +
136715 + channel = index + QM_CHANNEL_SWPORTAL0;
136716 + pcfg->public_cfg.channel = channel;
136717 + pcfg->public_cfg.cpu = -1;
136718 + irq = irq_of_parse_and_map(node, 0);
136719 + if (irq == 0) {
136720 + pr_err("Can't get %s property '%s'\n", node->full_name,
136721 + "interrupts");
136722 + goto err;
136723 + }
136724 + pcfg->public_cfg.irq = irq;
136725 + pcfg->public_cfg.index = index;
136726 +#ifdef CONFIG_FSL_QMAN_CONFIG
136727 + /* We need the same LIODN offset for all portals */
136728 + qman_liodn_fixup(pcfg->public_cfg.channel);
136729 +#endif
136730 +
136731 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
136732 + if (len != (unsigned long)len)
136733 + goto err;
136734 +
136735 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136736 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
136737 + pcfg->addr_phys[DPA_PORTAL_CE].start,
136738 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
136739 +
136740 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
136741 + pcfg->addr_phys[DPA_PORTAL_CI].start,
136742 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
136743 +#else
136744 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
136745 + pcfg->addr_phys[DPA_PORTAL_CE].start,
136746 + (unsigned long)len,
136747 + 0);
136748 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
136749 + pcfg->addr_phys[DPA_PORTAL_CI].start,
136750 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
136751 + _PAGE_GUARDED | _PAGE_NO_CACHE);
136752 +#endif
136753 + return pcfg;
136754 +err:
136755 + kfree(pcfg);
136756 + return NULL;
136757 +}
136758 +
136759 +static struct qm_portal_config *get_pcfg(struct list_head *list)
136760 +{
136761 + struct qm_portal_config *pcfg;
136762 + if (list_empty(list))
136763 + return NULL;
136764 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
136765 + list_del(&pcfg->list);
136766 + return pcfg;
136767 +}
136768 +
136769 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
136770 +{
136771 + struct qm_portal_config *pcfg;
136772 + if (list_empty(list))
136773 + return NULL;
136774 + list_for_each_entry(pcfg, list, list) {
136775 + if (pcfg->public_cfg.index == idx) {
136776 + list_del(&pcfg->list);
136777 + return pcfg;
136778 + }
136779 + }
136780 + return NULL;
136781 +}
136782 +
136783 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
136784 +{
136785 +#ifdef CONFIG_FSL_PAMU
136786 + int ret;
136787 + int window_count = 1;
136788 + struct iommu_domain_geometry geom_attr;
136789 + struct pamu_stash_attribute stash_attr;
136790 +
136791 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
136792 + if (!pcfg->iommu_domain) {
136793 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
136794 + __func__);
136795 + goto _no_iommu;
136796 + }
136797 + geom_attr.aperture_start = 0;
136798 + geom_attr.aperture_end =
136799 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
136800 + geom_attr.force_aperture = true;
136801 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
136802 + &geom_attr);
136803 + if (ret < 0) {
136804 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
136805 + __func__, ret);
136806 + goto _iommu_domain_free;
136807 + }
136808 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
136809 + &window_count);
136810 + if (ret < 0) {
136811 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
136812 + __func__, ret);
136813 + goto _iommu_domain_free;
136814 + }
136815 + stash_attr.cpu = cpu;
136816 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
136817 + /* set stash information for the window */
136818 + stash_attr.window = 0;
136819 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
136820 + DOMAIN_ATTR_FSL_PAMU_STASH,
136821 + &stash_attr);
136822 + if (ret < 0) {
136823 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
136824 + __func__, ret);
136825 + goto _iommu_domain_free;
136826 + }
136827 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
136828 + IOMMU_READ | IOMMU_WRITE);
136829 + if (ret < 0) {
136830 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
136831 + __func__, ret);
136832 + goto _iommu_domain_free;
136833 + }
136834 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
136835 + if (ret < 0) {
136836 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
136837 + __func__, ret);
136838 + goto _iommu_domain_free;
136839 + }
136840 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
136841 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
136842 + &window_count);
136843 + if (ret < 0) {
136844 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
136845 + __func__, ret);
136846 + goto _iommu_detach_device;
136847 + }
136848 +
136849 +_no_iommu:
136850 +#endif
136851 +#ifdef CONFIG_FSL_QMAN_CONFIG
136852 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
136853 +#endif
136854 + pr_warn("Failed to set QMan portal's stash request queue\n");
136855 +
136856 + return;
136857 +
136858 +#ifdef CONFIG_FSL_PAMU
136859 +_iommu_detach_device:
136860 + iommu_detach_device(pcfg->iommu_domain, NULL);
136861 +_iommu_domain_free:
136862 + iommu_domain_free(pcfg->iommu_domain);
136863 +#endif
136864 +}
136865 +
136866 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
136867 +{
136868 + struct qm_portal_config *ret;
136869 + spin_lock(&unused_pcfgs_lock);
136870 + if (idx == QBMAN_ANY_PORTAL_IDX)
136871 + ret = get_pcfg(&unused_pcfgs);
136872 + else
136873 + ret = get_pcfg_idx(&unused_pcfgs, idx);
136874 + spin_unlock(&unused_pcfgs_lock);
136875 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
136876 + * set the portal to use the stashing request queue corresonding to the
136877 + * cpu as well. The user-space driver assumption is that the pthread has
136878 + * to already be affine to one cpu only before opening a portal. If that
136879 + * check is circumvented, the only risk is a performance degradation -
136880 + * stashing will go to whatever cpu they happened to be running on when
136881 + * opening the device file, and if that isn't the cpu they subsequently
136882 + * bind to and do their polling on, tough. */
136883 + if (ret)
136884 + portal_set_cpu(ret, hard_smp_processor_id());
136885 + return ret;
136886 +}
136887 +
136888 +struct qm_portal_config *qm_get_unused_portal(void)
136889 +{
136890 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
136891 +}
136892 +
136893 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
136894 +{
136895 + spin_lock(&unused_pcfgs_lock);
136896 + list_add(&pcfg->list, &unused_pcfgs);
136897 + spin_unlock(&unused_pcfgs_lock);
136898 +}
136899 +
136900 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
136901 +{
136902 + struct qman_portal *p;
136903 +
136904 + pcfg->iommu_domain = NULL;
136905 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
136906 + p = qman_create_affine_portal(pcfg, NULL);
136907 + if (p) {
136908 + u32 irq_sources = 0;
136909 + /* Determine what should be interrupt-vs-poll driven */
136910 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
136911 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
136912 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
136913 +#endif
136914 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
136915 + irq_sources |= QM_PIRQ_DQRI;
136916 +#endif
136917 + qman_p_irqsource_add(p, irq_sources);
136918 + pr_info("Qman portal %sinitialised, cpu %d\n",
136919 + pcfg->public_cfg.is_shared ? "(shared) " : "",
136920 + pcfg->public_cfg.cpu);
136921 + } else
136922 + pr_crit("Qman portal failure on cpu %d\n",
136923 + pcfg->public_cfg.cpu);
136924 + return p;
136925 +}
136926 +
136927 +static void init_slave(int cpu)
136928 +{
136929 + struct qman_portal *p;
136930 + struct cpumask oldmask = current->cpus_allowed;
136931 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
136932 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
136933 + if (!p)
136934 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
136935 + else
136936 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
136937 + set_cpus_allowed_ptr(current, &oldmask);
136938 + if (shared_portals_idx >= num_shared_portals)
136939 + shared_portals_idx = 0;
136940 +}
136941 +
136942 +static struct cpumask want_unshared __initdata;
136943 +static struct cpumask want_shared __initdata;
136944 +
136945 +static int __init parse_qportals(char *str)
136946 +{
136947 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
136948 + "qportals");
136949 +}
136950 +__setup("qportals=", parse_qportals);
136951 +
136952 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
136953 + unsigned int cpu)
136954 +{
136955 +#ifdef CONFIG_FSL_PAMU
136956 + struct pamu_stash_attribute stash_attr;
136957 + int ret;
136958 +
136959 + if (pcfg->iommu_domain) {
136960 + stash_attr.cpu = cpu;
136961 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
136962 + /* set stash information for the window */
136963 + stash_attr.window = 0;
136964 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
136965 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
136966 + if (ret < 0) {
136967 + pr_err("Failed to update pamu stash setting\n");
136968 + return;
136969 + }
136970 + }
136971 +#endif
136972 +#ifdef CONFIG_FSL_QMAN_CONFIG
136973 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
136974 + pr_warn("Failed to update portal's stash request queue\n");
136975 +#endif
136976 +}
136977 +
136978 +static int qman_offline_cpu(unsigned int cpu)
136979 +{
136980 + struct qman_portal *p;
136981 + const struct qm_portal_config *pcfg;
136982 + p = (struct qman_portal *)affine_portals[cpu];
136983 + if (p) {
136984 + pcfg = qman_get_qm_portal_config(p);
136985 + if (pcfg) {
136986 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
136987 + qman_portal_update_sdest(pcfg, 0);
136988 + }
136989 + }
136990 + return 0;
136991 +}
136992 +
136993 +#ifdef CONFIG_HOTPLUG_CPU
136994 +static int qman_online_cpu(unsigned int cpu)
136995 +{
136996 + struct qman_portal *p;
136997 + const struct qm_portal_config *pcfg;
136998 + p = (struct qman_portal *)affine_portals[cpu];
136999 + if (p) {
137000 + pcfg = qman_get_qm_portal_config(p);
137001 + if (pcfg) {
137002 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
137003 + qman_portal_update_sdest(pcfg, cpu);
137004 + }
137005 + }
137006 + return 0;
137007 +}
137008 +
137009 +#endif /* CONFIG_HOTPLUG_CPU */
137010 +
137011 +__init int qman_init(void)
137012 +{
137013 + struct cpumask slave_cpus;
137014 + struct cpumask unshared_cpus = *cpu_none_mask;
137015 + struct cpumask shared_cpus = *cpu_none_mask;
137016 + LIST_HEAD(unshared_pcfgs);
137017 + LIST_HEAD(shared_pcfgs);
137018 + struct device_node *dn;
137019 + struct qm_portal_config *pcfg;
137020 + struct qman_portal *p;
137021 + int cpu, ret;
137022 + const u32 *clk;
137023 + struct cpumask offline_cpus;
137024 +
137025 + /* Initialise the Qman (CCSR) device */
137026 + for_each_compatible_node(dn, NULL, "fsl,qman") {
137027 + if (!qman_init_ccsr(dn))
137028 + pr_info("Qman err interrupt handler present\n");
137029 + else
137030 + pr_err("Qman CCSR setup failed\n");
137031 +
137032 + clk = of_get_property(dn, "clock-frequency", NULL);
137033 + if (!clk)
137034 + pr_warn("Can't find Qman clock frequency\n");
137035 + else
137036 + qman_clk = be32_to_cpu(*clk);
137037 + }
137038 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137039 + /* Setup lookup table for FQ demux */
137040 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
137041 + if (ret)
137042 + return ret;
137043 +#endif
137044 +
137045 + /* Get qman ip revision */
137046 + qman_get_ip_revision(dn);
137047 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
137048 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
137049 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
137050 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
137051 + }
137052 +
137053 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
137054 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
137055 +
137056 + /*
137057 + * Parse the ceetm node to get how many ceetm instances are supported
137058 + * on the current silicon. num_ceetms must be confirmed before portals
137059 + * are intiailized.
137060 + */
137061 + num_ceetms = 0;
137062 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
137063 + num_ceetms++;
137064 +
137065 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
137066 + * are initialised.) */
137067 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
137068 + ret = fsl_pool_channel_range_sdqcr(dn);
137069 + if (ret)
137070 + return ret;
137071 + }
137072 +
137073 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
137074 + /* Initialise portals. See bman_driver.c for comments */
137075 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
137076 + if (!of_device_is_available(dn))
137077 + continue;
137078 + pcfg = parse_pcfg(dn);
137079 + if (pcfg) {
137080 + pcfg->public_cfg.pools = pools_sdqcr;
137081 + list_add_tail(&pcfg->list, &unused_pcfgs);
137082 + }
137083 + }
137084 + for_each_possible_cpu(cpu) {
137085 + if (cpumask_test_cpu(cpu, &want_shared)) {
137086 + pcfg = get_pcfg(&unused_pcfgs);
137087 + if (!pcfg)
137088 + break;
137089 + pcfg->public_cfg.cpu = cpu;
137090 + list_add_tail(&pcfg->list, &shared_pcfgs);
137091 + cpumask_set_cpu(cpu, &shared_cpus);
137092 + }
137093 + if (cpumask_test_cpu(cpu, &want_unshared)) {
137094 + if (cpumask_test_cpu(cpu, &shared_cpus))
137095 + continue;
137096 + pcfg = get_pcfg(&unused_pcfgs);
137097 + if (!pcfg)
137098 + break;
137099 + pcfg->public_cfg.cpu = cpu;
137100 + list_add_tail(&pcfg->list, &unshared_pcfgs);
137101 + cpumask_set_cpu(cpu, &unshared_cpus);
137102 + }
137103 + }
137104 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
137105 + for_each_online_cpu(cpu) {
137106 + pcfg = get_pcfg(&unused_pcfgs);
137107 + if (!pcfg)
137108 + break;
137109 + pcfg->public_cfg.cpu = cpu;
137110 + list_add_tail(&pcfg->list, &unshared_pcfgs);
137111 + cpumask_set_cpu(cpu, &unshared_cpus);
137112 + }
137113 + }
137114 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
137115 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
137116 + if (cpumask_empty(&slave_cpus)) {
137117 + if (!list_empty(&shared_pcfgs)) {
137118 + cpumask_or(&unshared_cpus, &unshared_cpus,
137119 + &shared_cpus);
137120 + cpumask_clear(&shared_cpus);
137121 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
137122 + INIT_LIST_HEAD(&shared_pcfgs);
137123 + }
137124 + } else {
137125 + if (list_empty(&shared_pcfgs)) {
137126 + pcfg = get_pcfg(&unshared_pcfgs);
137127 + if (!pcfg) {
137128 + pr_crit("No QMan portals available!\n");
137129 + return 0;
137130 + }
137131 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
137132 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
137133 + list_add_tail(&pcfg->list, &shared_pcfgs);
137134 + }
137135 + }
137136 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
137137 + pcfg->public_cfg.is_shared = 0;
137138 + p = init_pcfg(pcfg);
137139 + if (!p) {
137140 + pr_crit("Unable to configure portals\n");
137141 + return 0;
137142 + }
137143 + }
137144 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
137145 + pcfg->public_cfg.is_shared = 1;
137146 + p = init_pcfg(pcfg);
137147 + if (p)
137148 + shared_portals[num_shared_portals++] = p;
137149 + }
137150 + if (!cpumask_empty(&slave_cpus))
137151 + for_each_cpu(cpu, &slave_cpus)
137152 + init_slave(cpu);
137153 + pr_info("Qman portals initialised\n");
137154 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
137155 + for_each_cpu(cpu, &offline_cpus)
137156 + qman_offline_cpu(cpu);
137157 +#ifdef CONFIG_HOTPLUG_CPU
137158 + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
137159 + "soc/qman_portal:online",
137160 + qman_online_cpu, qman_offline_cpu);
137161 + if (ret < 0) {
137162 + pr_err("qman: failed to register hotplug callbacks.\n");
137163 + return ret;
137164 + }
137165 +#endif
137166 + return 0;
137167 +}
137168 +
137169 +__init int qman_resource_init(void)
137170 +{
137171 + struct device_node *dn;
137172 + int ret;
137173 +
137174 + /* Initialise FQID allocation ranges */
137175 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
137176 + ret = fsl_fqid_range_init(dn);
137177 + if (ret)
137178 + return ret;
137179 + }
137180 + /* Initialise CGRID allocation ranges */
137181 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
137182 + ret = fsl_cgrid_range_init(dn);
137183 + if (ret)
137184 + return ret;
137185 + }
137186 + /* Parse pool channels into the allocator. (Must happen after portals
137187 + * are initialised.) */
137188 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
137189 + ret = fsl_pool_channel_range_init(dn);
137190 + if (ret)
137191 + return ret;
137192 + }
137193 +
137194 + /* Parse CEETM */
137195 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
137196 + ret = fsl_ceetm_init(dn);
137197 + if (ret)
137198 + return ret;
137199 + }
137200 + return 0;
137201 +}
137202 +
137203 +#ifdef CONFIG_SUSPEND
137204 +void suspend_unused_qportal(void)
137205 +{
137206 + struct qm_portal_config *pcfg;
137207 +
137208 + if (list_empty(&unused_pcfgs))
137209 + return;
137210 +
137211 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
137212 +#ifdef CONFIG_PM_DEBUG
137213 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
137214 +#endif
137215 + /* save isdr, disable all via isdr, clear isr */
137216 + pcfg->saved_isdr =
137217 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
137218 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
137219 + 0xe08);
137220 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
137221 + 0xe00);
137222 + }
137223 + return;
137224 +}
137225 +
137226 +void resume_unused_qportal(void)
137227 +{
137228 + struct qm_portal_config *pcfg;
137229 +
137230 + if (list_empty(&unused_pcfgs))
137231 + return;
137232 +
137233 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
137234 +#ifdef CONFIG_PM_DEBUG
137235 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
137236 +#endif
137237 + /* restore isdr */
137238 + __raw_writel(pcfg->saved_isdr,
137239 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
137240 + }
137241 + return;
137242 +}
137243 +#endif
137244 --- /dev/null
137245 +++ b/drivers/staging/fsl_qbman/qman_high.c
137246 @@ -0,0 +1,5652 @@
137247 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
137248 + *
137249 + * Redistribution and use in source and binary forms, with or without
137250 + * modification, are permitted provided that the following conditions are met:
137251 + * * Redistributions of source code must retain the above copyright
137252 + * notice, this list of conditions and the following disclaimer.
137253 + * * Redistributions in binary form must reproduce the above copyright
137254 + * notice, this list of conditions and the following disclaimer in the
137255 + * documentation and/or other materials provided with the distribution.
137256 + * * Neither the name of Freescale Semiconductor nor the
137257 + * names of its contributors may be used to endorse or promote products
137258 + * derived from this software without specific prior written permission.
137259 + *
137260 + *
137261 + * ALTERNATIVELY, this software may be distributed under the terms of the
137262 + * GNU General Public License ("GPL") as published by the Free Software
137263 + * Foundation, either version 2 of that License or (at your option) any
137264 + * later version.
137265 + *
137266 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
137267 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
137268 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
137269 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
137270 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
137271 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
137272 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
137273 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
137274 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
137275 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
137276 + */
137277 +
137278 +#include "qman_low.h"
137279 +
137280 +/* Compilation constants */
137281 +#define DQRR_MAXFILL 15
137282 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
137283 +#define IRQNAME "QMan portal %d"
137284 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
137285 +
137286 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
137287 + * positive, and rounding to the closest value if it's zero. NB, this macro
137288 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
137289 + * that are compatible with this. NB, these arguments should not be expressions
137290 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
137291 + * in "some_value++" as a parameter to the macro! */
137292 +#define ROUNDING(n, d, r) \
137293 + (((r) < 0) ? div64_u64((n), (d)) : \
137294 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
137295 + div64_u64(((n) + ((d) / 2)), (d))))
137296 +
137297 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
137298 + * inter-processor locking only. Note, FQLOCK() is always called either under a
137299 + * local_irq_save() or from interrupt context - hence there's no need for irq
137300 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
137301 + * the "irq en/disable" machinery isn't recursive...). */
137302 +#define FQLOCK(fq) \
137303 + do { \
137304 + struct qman_fq *__fq478 = (fq); \
137305 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
137306 + spin_lock(&__fq478->fqlock); \
137307 + } while (0)
137308 +#define FQUNLOCK(fq) \
137309 + do { \
137310 + struct qman_fq *__fq478 = (fq); \
137311 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
137312 + spin_unlock(&__fq478->fqlock); \
137313 + } while (0)
137314 +
137315 +static inline void fq_set(struct qman_fq *fq, u32 mask)
137316 +{
137317 + set_bits(mask, &fq->flags);
137318 +}
137319 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
137320 +{
137321 + clear_bits(mask, &fq->flags);
137322 +}
137323 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
137324 +{
137325 + return fq->flags & mask;
137326 +}
137327 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
137328 +{
137329 + return !(fq->flags & mask);
137330 +}
137331 +
137332 +struct qman_portal {
137333 + struct qm_portal p;
137334 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
137335 + unsigned long irq_sources;
137336 + u32 use_eqcr_ci_stashing;
137337 + u32 slowpoll; /* only used when interrupts are off */
137338 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
137339 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137340 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
137341 +#endif
137342 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137343 + raw_spinlock_t sharing_lock; /* only used if is_shared */
137344 + int is_shared;
137345 + struct qman_portal *sharing_redirect;
137346 +#endif
137347 + u32 sdqcr;
137348 + int dqrr_disable_ref;
137349 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
137350 + * handler is called instead. */
137351 + qman_cb_dc_ern cb_dc_ern;
137352 + /* When the cpu-affine portal is activated, this is non-NULL */
137353 + const struct qm_portal_config *config;
137354 + /* This is needed for providing a non-NULL device to dma_map_***() */
137355 + struct platform_device *pdev;
137356 + struct dpa_rbtree retire_table;
137357 + char irqname[MAX_IRQNAME];
137358 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
137359 + struct qman_cgrs *cgrs;
137360 + /* linked-list of CSCN handlers. */
137361 + struct list_head cgr_cbs;
137362 + /* list lock */
137363 + spinlock_t cgr_lock;
137364 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
137365 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
137366 + /* 256-element array, each is a linked-list of CCSCN handlers. */
137367 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
137368 + /* list lock */
137369 + spinlock_t ccgr_lock;
137370 + /* track if memory was allocated by the driver */
137371 + u8 alloced;
137372 + /* power management data */
137373 + u32 save_isdr;
137374 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137375 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
137376 + * do byte swaps of DQRR read only memory. First entry must be aligned
137377 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
137378 + * address (6 bits for address shift + 4 bits for the DQRR size).
137379 + */
137380 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
137381 +#endif
137382 +};
137383 +
137384 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137385 +#define PORTAL_IRQ_LOCK(p, irqflags) \
137386 + do { \
137387 + if ((p)->is_shared) \
137388 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
137389 + else \
137390 + local_irq_save(irqflags); \
137391 + } while (0)
137392 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
137393 + do { \
137394 + if ((p)->is_shared) \
137395 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
137396 + irqflags); \
137397 + else \
137398 + local_irq_restore(irqflags); \
137399 + } while (0)
137400 +#else
137401 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
137402 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
137403 +#endif
137404 +
137405 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
137406 + * not have a portal-specific handler. */
137407 +static qman_cb_dc_ern cb_dc_ern;
137408 +
137409 +static cpumask_t affine_mask;
137410 +static DEFINE_SPINLOCK(affine_mask_lock);
137411 +static u16 affine_channels[NR_CPUS];
137412 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
137413 +void *affine_portals[NR_CPUS];
137414 +
137415 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
137416 +static inline struct qman_portal *get_raw_affine_portal(void)
137417 +{
137418 + return &get_cpu_var(qman_affine_portal);
137419 +}
137420 +/* For ops that can redirect, this obtains the portal to use */
137421 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137422 +static inline struct qman_portal *get_affine_portal(void)
137423 +{
137424 + struct qman_portal *p = get_raw_affine_portal();
137425 + if (p->sharing_redirect)
137426 + return p->sharing_redirect;
137427 + return p;
137428 +}
137429 +#else
137430 +#define get_affine_portal() get_raw_affine_portal()
137431 +#endif
137432 +/* For every "get", there must be a "put" */
137433 +static inline void put_affine_portal(void)
137434 +{
137435 + put_cpu_var(qman_affine_portal);
137436 +}
137437 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
137438 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
137439 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
137440 + * context to remain as non-atomic during poll-triggered callbacks as it was
137441 + * when the poll API was first called (eg. NAPI), so we go out of our way in
137442 + * this case to not disable pre-emption. */
137443 +static inline struct qman_portal *get_poll_portal(void)
137444 +{
137445 + return &get_cpu_var(qman_affine_portal);
137446 +}
137447 +#define put_poll_portal()
137448 +
137449 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
137450 + * retirement notifications (the fact they are sometimes h/w-consumed means that
137451 + * contextB isn't always a s/w demux - and as we can't know which case it is
137452 + * when looking at the notification, we have to use the slow lookup for all of
137453 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
137454 + * (though at most one of them should be the consumer), so this table isn't for
137455 + * all FQs - FQs are added when retirement commands are issued, and removed when
137456 + * they complete, which also massively reduces the size of this table. */
137457 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
137458 +
137459 +/* This is what everything can wait on, even if it migrates to a different cpu
137460 + * to the one whose affine portal it is waiting on. */
137461 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
137462 +
137463 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
137464 +{
137465 + int ret = fqtree_push(&p->retire_table, fq);
137466 + if (ret)
137467 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
137468 + return ret;
137469 +}
137470 +
137471 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
137472 +{
137473 + fqtree_del(&p->retire_table, fq);
137474 +}
137475 +
137476 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
137477 +{
137478 + return fqtree_find(&p->retire_table, fqid);
137479 +}
137480 +
137481 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137482 +static void **qman_fq_lookup_table;
137483 +static size_t qman_fq_lookup_table_size;
137484 +
137485 +int qman_setup_fq_lookup_table(size_t num_entries)
137486 +{
137487 + num_entries++;
137488 + /* Allocate 1 more entry since the first entry is not used */
137489 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
137490 + if (!qman_fq_lookup_table) {
137491 + pr_err("QMan: Could not allocate fq lookup table\n");
137492 + return -ENOMEM;
137493 + }
137494 + qman_fq_lookup_table_size = num_entries;
137495 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
137496 + qman_fq_lookup_table,
137497 + (unsigned long)qman_fq_lookup_table_size);
137498 + return 0;
137499 +}
137500 +
137501 +/* global structure that maintains fq object mapping */
137502 +static DEFINE_SPINLOCK(fq_hash_table_lock);
137503 +
137504 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
137505 +{
137506 + u32 i;
137507 +
137508 + spin_lock(&fq_hash_table_lock);
137509 + /* Can't use index zero because this has special meaning
137510 + * in context_b field. */
137511 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
137512 + if (qman_fq_lookup_table[i] == NULL) {
137513 + *entry = i;
137514 + qman_fq_lookup_table[i] = fq;
137515 + spin_unlock(&fq_hash_table_lock);
137516 + return 0;
137517 + }
137518 + }
137519 + spin_unlock(&fq_hash_table_lock);
137520 + return -ENOMEM;
137521 +}
137522 +
137523 +static void clear_fq_table_entry(u32 entry)
137524 +{
137525 + spin_lock(&fq_hash_table_lock);
137526 + BUG_ON(entry >= qman_fq_lookup_table_size);
137527 + qman_fq_lookup_table[entry] = NULL;
137528 + spin_unlock(&fq_hash_table_lock);
137529 +}
137530 +
137531 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
137532 +{
137533 + BUG_ON(entry >= qman_fq_lookup_table_size);
137534 + return qman_fq_lookup_table[entry];
137535 +}
137536 +#endif
137537 +
137538 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
137539 +{
137540 + /* Byteswap the FQD to HW format */
137541 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
137542 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
137543 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
137544 + fqd->context_b = cpu_to_be32(fqd->context_b);
137545 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
137546 +}
137547 +
137548 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
137549 +{
137550 + /* Byteswap the FQD to CPU format */
137551 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
137552 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
137553 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
137554 + fqd->context_b = be32_to_cpu(fqd->context_b);
137555 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
137556 +}
137557 +
137558 +/* Swap a 40 bit address */
137559 +static inline u64 cpu_to_be40(u64 in)
137560 +{
137561 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137562 + return in;
137563 +#else
137564 + u64 out = 0;
137565 + u8 *p = (u8 *) &out;
137566 + p[0] = in >> 32;
137567 + p[1] = in >> 24;
137568 + p[2] = in >> 16;
137569 + p[3] = in >> 8;
137570 + p[4] = in >> 0;
137571 + return out;
137572 +#endif
137573 +}
137574 +static inline u64 be40_to_cpu(u64 in)
137575 +{
137576 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137577 + return in;
137578 +#else
137579 + u64 out = 0;
137580 + u8 *pout = (u8 *) &out;
137581 + u8 *pin = (u8 *) &in;
137582 + pout[0] = pin[4];
137583 + pout[1] = pin[3];
137584 + pout[2] = pin[2];
137585 + pout[3] = pin[1];
137586 + pout[4] = pin[0];
137587 + return out;
137588 +#endif
137589 +}
137590 +
137591 +/* Swap a 24 bit value */
137592 +static inline u32 cpu_to_be24(u32 in)
137593 +{
137594 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137595 + return in;
137596 +#else
137597 + u32 out = 0;
137598 + u8 *p = (u8 *) &out;
137599 + p[0] = in >> 16;
137600 + p[1] = in >> 8;
137601 + p[2] = in >> 0;
137602 + return out;
137603 +#endif
137604 +}
137605 +
137606 +static inline u32 be24_to_cpu(u32 in)
137607 +{
137608 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137609 + return in;
137610 +#else
137611 + u32 out = 0;
137612 + u8 *pout = (u8 *) &out;
137613 + u8 *pin = (u8 *) &in;
137614 + pout[0] = pin[2];
137615 + pout[1] = pin[1];
137616 + pout[2] = pin[0];
137617 + return out;
137618 +#endif
137619 +}
137620 +
137621 +static inline u64 be48_to_cpu(u64 in)
137622 +{
137623 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137624 + return in;
137625 +#else
137626 + u64 out = 0;
137627 + u8 *pout = (u8 *) &out;
137628 + u8 *pin = (u8 *) &in;
137629 +
137630 + pout[0] = pin[5];
137631 + pout[1] = pin[4];
137632 + pout[2] = pin[3];
137633 + pout[3] = pin[2];
137634 + pout[4] = pin[1];
137635 + pout[5] = pin[0];
137636 + return out;
137637 +#endif
137638 +}
137639 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
137640 +{
137641 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
137642 + fd->status = cpu_to_be32(fd->status);
137643 + fd->opaque = cpu_to_be32(fd->opaque);
137644 +}
137645 +
137646 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
137647 +{
137648 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
137649 + fd->status = be32_to_cpu(fd->status);
137650 + fd->opaque = be32_to_cpu(fd->opaque);
137651 +}
137652 +
137653 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
137654 +{
137655 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
137656 + cq_query->state = be16_to_cpu(cq_query->state);
137657 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
137658 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
137659 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
137660 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
137661 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
137662 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
137663 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
137664 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
137665 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
137666 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
137667 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
137668 +}
137669 +
137670 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
137671 +{
137672 + int i;
137673 +
137674 + ccgr_q->cm_query.cs_thres.hword =
137675 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
137676 + ccgr_q->cm_query.cs_thres_x.hword =
137677 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
137678 + ccgr_q->cm_query.td_thres.hword =
137679 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
137680 + ccgr_q->cm_query.wr_parm_g.word =
137681 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
137682 + ccgr_q->cm_query.wr_parm_y.word =
137683 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
137684 + ccgr_q->cm_query.wr_parm_r.word =
137685 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
137686 + ccgr_q->cm_query.cscn_targ_dcp =
137687 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
137688 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
137689 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
137690 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
137691 + ccgr_q->cm_query.cscn_targ_swp[i] =
137692 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
137693 +}
137694 +
137695 +/* In the case that slow- and fast-path handling are both done by qman_poll()
137696 + * (ie. because there is no interrupt handling), we ought to balance how often
137697 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
137698 + * sources, so we call the fast poll 'n' times before calling the slow poll
137699 + * once. The idle decrementer constant is used when the last slow-poll detected
137700 + * no work to do, and the busy decrementer constant when the last slow-poll had
137701 + * work to do. */
137702 +#define SLOW_POLL_IDLE 1000
137703 +#define SLOW_POLL_BUSY 10
137704 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
137705 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
137706 + unsigned int poll_limit);
137707 +
137708 +/* Portal interrupt handler */
137709 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
137710 +{
137711 + struct qman_portal *p = ptr;
137712 + /*
137713 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
137714 + * it could race against a Query Congestion State command also given
137715 + * as part of the handling of this interrupt source. We mustn't
137716 + * clear it a second time in this top-level function.
137717 + */
137718 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
137719 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
137720 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
137721 + /* DQRR-handling if it's interrupt-driven */
137722 + if (is & QM_PIRQ_DQRI)
137723 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
137724 + /* Handling of anything else that's interrupt-driven */
137725 + clear |= __poll_portal_slow(p, is);
137726 + qm_isr_status_clear(&p->p, clear);
137727 + return IRQ_HANDLED;
137728 +}
137729 +
137730 +/* This inner version is used privately by qman_create_affine_portal(), as well
137731 + * as by the exported qman_stop_dequeues(). */
137732 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
137733 +{
137734 + unsigned long irqflags __maybe_unused;
137735 + PORTAL_IRQ_LOCK(p, irqflags);
137736 + if (!(p->dqrr_disable_ref++))
137737 + qm_dqrr_set_maxfill(&p->p, 0);
137738 + PORTAL_IRQ_UNLOCK(p, irqflags);
137739 +}
137740 +
137741 +static int drain_mr_fqrni(struct qm_portal *p)
137742 +{
137743 + const struct qm_mr_entry *msg;
137744 +loop:
137745 + msg = qm_mr_current(p);
137746 + if (!msg) {
137747 + /* if MR was full and h/w had other FQRNI entries to produce, we
137748 + * need to allow it time to produce those entries once the
137749 + * existing entries are consumed. A worst-case situation
137750 + * (fully-loaded system) means h/w sequencers may have to do 3-4
137751 + * other things before servicing the portal's MR pump, each of
137752 + * which (if slow) may take ~50 qman cycles (which is ~200
137753 + * processor cycles). So rounding up and then multiplying this
137754 + * worst-case estimate by a factor of 10, just to be
137755 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
137756 + * one entry at a time, so h/w has an opportunity to produce new
137757 + * entries well before the ring has been fully consumed, so
137758 + * we're being *really* paranoid here. */
137759 + u64 now, then = mfatb();
137760 + do {
137761 + now = mfatb();
137762 + } while ((then + 10000) > now);
137763 + msg = qm_mr_current(p);
137764 + if (!msg)
137765 + return 0;
137766 + }
137767 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
137768 + /* We aren't draining anything but FQRNIs */
137769 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
137770 + return -1;
137771 + }
137772 + qm_mr_next(p);
137773 + qm_mr_cci_consume(p, 1);
137774 + goto loop;
137775 +}
137776 +
137777 +#ifdef CONFIG_SUSPEND
137778 +static int _qman_portal_suspend_noirq(struct device *dev)
137779 +{
137780 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
137781 +#ifdef CONFIG_PM_DEBUG
137782 + struct platform_device *pdev = to_platform_device(dev);
137783 +#endif
137784 +
137785 + p->save_isdr = qm_isr_disable_read(&p->p);
137786 + qm_isr_disable_write(&p->p, 0xffffffff);
137787 + qm_isr_status_clear(&p->p, 0xffffffff);
137788 +#ifdef CONFIG_PM_DEBUG
137789 + pr_info("Suspend for %s\n", pdev->name);
137790 +#endif
137791 + return 0;
137792 +}
137793 +
137794 +static int _qman_portal_resume_noirq(struct device *dev)
137795 +{
137796 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
137797 +
137798 + /* restore isdr */
137799 + qm_isr_disable_write(&p->p, p->save_isdr);
137800 + return 0;
137801 +}
137802 +#else
137803 +#define _qman_portal_suspend_noirq NULL
137804 +#define _qman_portal_resume_noirq NULL
137805 +#endif
137806 +
137807 +struct dev_pm_domain qman_portal_device_pm_domain = {
137808 + .ops = {
137809 + USE_PLATFORM_PM_SLEEP_OPS
137810 + .suspend_noirq = _qman_portal_suspend_noirq,
137811 + .resume_noirq = _qman_portal_resume_noirq,
137812 + }
137813 +};
137814 +
137815 +struct qman_portal *qman_create_portal(
137816 + struct qman_portal *portal,
137817 + const struct qm_portal_config *config,
137818 + const struct qman_cgrs *cgrs)
137819 +{
137820 + struct qm_portal *__p;
137821 + char buf[16];
137822 + int ret;
137823 + u32 isdr;
137824 +
137825 + if (!portal) {
137826 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
137827 + if (!portal)
137828 + return portal;
137829 + portal->alloced = 1;
137830 + } else
137831 + portal->alloced = 0;
137832 +
137833 + __p = &portal->p;
137834 +
137835 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
137836 + /* PAMU is required for stashing */
137837 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
137838 + 1 : 0);
137839 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137840 + portal->use_eqcr_ci_stashing = 1;
137841 +#else
137842 + portal->use_eqcr_ci_stashing = 0;
137843 +#endif
137844 +
137845 + /* prep the low-level portal struct with the mapped addresses from the
137846 + * config, everything that follows depends on it and "config" is more
137847 + * for (de)reference... */
137848 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
137849 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
137850 + /*
137851 + * If CI-stashing is used, the current defaults use a threshold of 3,
137852 + * and stash with high-than-DQRR priority.
137853 + */
137854 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
137855 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
137856 + pr_err("Qman EQCR initialisation failed\n");
137857 + goto fail_eqcr;
137858 + }
137859 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
137860 + qm_dqrr_cdc, DQRR_MAXFILL)) {
137861 + pr_err("Qman DQRR initialisation failed\n");
137862 + goto fail_dqrr;
137863 + }
137864 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
137865 + pr_err("Qman MR initialisation failed\n");
137866 + goto fail_mr;
137867 + }
137868 + if (qm_mc_init(__p)) {
137869 + pr_err("Qman MC initialisation failed\n");
137870 + goto fail_mc;
137871 + }
137872 + if (qm_isr_init(__p)) {
137873 + pr_err("Qman ISR initialisation failed\n");
137874 + goto fail_isr;
137875 + }
137876 + /* static interrupt-gating controls */
137877 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
137878 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
137879 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
137880 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
137881 + if (!portal->cgrs)
137882 + goto fail_cgrs;
137883 + /* initial snapshot is no-depletion */
137884 + qman_cgrs_init(&portal->cgrs[1]);
137885 + if (cgrs)
137886 + portal->cgrs[0] = *cgrs;
137887 + else
137888 + /* if the given mask is NULL, assume all CGRs can be seen */
137889 + qman_cgrs_fill(&portal->cgrs[0]);
137890 + INIT_LIST_HEAD(&portal->cgr_cbs);
137891 + spin_lock_init(&portal->cgr_lock);
137892 + if (num_ceetms) {
137893 + for (ret = 0; ret < num_ceetms; ret++) {
137894 + portal->ccgrs[ret] = kmalloc(2 *
137895 + sizeof(struct qman_ccgrs), GFP_KERNEL);
137896 + if (!portal->ccgrs[ret])
137897 + goto fail_ccgrs;
137898 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
137899 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
137900 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
137901 + }
137902 + }
137903 + spin_lock_init(&portal->ccgr_lock);
137904 + portal->bits = 0;
137905 + portal->slowpoll = 0;
137906 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137907 + portal->eqci_owned = NULL;
137908 +#endif
137909 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137910 + raw_spin_lock_init(&portal->sharing_lock);
137911 + portal->is_shared = config->public_cfg.is_shared;
137912 + portal->sharing_redirect = NULL;
137913 +#endif
137914 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
137915 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
137916 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
137917 + portal->dqrr_disable_ref = 0;
137918 + portal->cb_dc_ern = NULL;
137919 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
137920 + portal->pdev = platform_device_alloc(buf, -1);
137921 + if (!portal->pdev) {
137922 + pr_err("qman_portal - platform_device_alloc() failed\n");
137923 + goto fail_devalloc;
137924 + }
137925 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137926 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
137927 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
137928 +#else
137929 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
137930 + pr_err("qman_portal - dma_set_mask() failed\n");
137931 + goto fail_devadd;
137932 + }
137933 +#endif
137934 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
137935 + portal->pdev->dev.platform_data = portal;
137936 + ret = platform_device_add(portal->pdev);
137937 + if (ret) {
137938 + pr_err("qman_portal - platform_device_add() failed\n");
137939 + goto fail_devadd;
137940 + }
137941 + dpa_rbtree_init(&portal->retire_table);
137942 + isdr = 0xffffffff;
137943 + qm_isr_disable_write(__p, isdr);
137944 + portal->irq_sources = 0;
137945 + qm_isr_enable_write(__p, portal->irq_sources);
137946 + qm_isr_status_clear(__p, 0xffffffff);
137947 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
137948 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
137949 + portal)) {
137950 + pr_err("request_irq() failed\n");
137951 + goto fail_irq;
137952 + }
137953 + if ((config->public_cfg.cpu != -1) &&
137954 + irq_can_set_affinity(config->public_cfg.irq) &&
137955 + irq_set_affinity(config->public_cfg.irq,
137956 + cpumask_of(config->public_cfg.cpu))) {
137957 + pr_err("irq_set_affinity() failed\n");
137958 + goto fail_affinity;
137959 + }
137960 +
137961 + /* Need EQCR to be empty before continuing */
137962 + isdr ^= QM_PIRQ_EQCI;
137963 + qm_isr_disable_write(__p, isdr);
137964 + ret = qm_eqcr_get_fill(__p);
137965 + if (ret) {
137966 + pr_err("Qman EQCR unclean\n");
137967 + goto fail_eqcr_empty;
137968 + }
137969 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
137970 + qm_isr_disable_write(__p, isdr);
137971 + if (qm_dqrr_current(__p) != NULL) {
137972 + pr_err("Qman DQRR unclean\n");
137973 + qm_dqrr_cdc_consume_n(__p, 0xffff);
137974 + }
137975 + if (qm_mr_current(__p) != NULL) {
137976 + /* special handling, drain just in case it's a few FQRNIs */
137977 + if (drain_mr_fqrni(__p)) {
137978 + const struct qm_mr_entry *e = qm_mr_current(__p);
137979 + /*
137980 + * Message ring cannot be empty no need to check
137981 + * qm_mr_current returned successfully
137982 + */
137983 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
137984 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
137985 + goto fail_dqrr_mr_empty;
137986 + }
137987 + }
137988 + /* Success */
137989 + portal->config = config;
137990 + qm_isr_disable_write(__p, 0);
137991 + qm_isr_uninhibit(__p);
137992 + /* Write a sane SDQCR */
137993 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
137994 + return portal;
137995 +fail_dqrr_mr_empty:
137996 +fail_eqcr_empty:
137997 +fail_affinity:
137998 + free_irq(config->public_cfg.irq, portal);
137999 +fail_irq:
138000 + platform_device_del(portal->pdev);
138001 +fail_devadd:
138002 + platform_device_put(portal->pdev);
138003 +fail_devalloc:
138004 + if (num_ceetms)
138005 + for (ret = 0; ret < num_ceetms; ret++)
138006 + kfree(portal->ccgrs[ret]);
138007 +fail_ccgrs:
138008 + kfree(portal->cgrs);
138009 +fail_cgrs:
138010 + qm_isr_finish(__p);
138011 +fail_isr:
138012 + qm_mc_finish(__p);
138013 +fail_mc:
138014 + qm_mr_finish(__p);
138015 +fail_mr:
138016 + qm_dqrr_finish(__p);
138017 +fail_dqrr:
138018 + qm_eqcr_finish(__p);
138019 +fail_eqcr:
138020 + if (portal->alloced)
138021 + kfree(portal);
138022 + return NULL;
138023 +}
138024 +
138025 +struct qman_portal *qman_create_affine_portal(
138026 + const struct qm_portal_config *config,
138027 + const struct qman_cgrs *cgrs)
138028 +{
138029 + struct qman_portal *res;
138030 + struct qman_portal *portal;
138031 +
138032 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
138033 + res = qman_create_portal(portal, config, cgrs);
138034 + if (res) {
138035 + spin_lock(&affine_mask_lock);
138036 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
138037 + affine_channels[config->public_cfg.cpu] =
138038 + config->public_cfg.channel;
138039 + affine_portals[config->public_cfg.cpu] = portal;
138040 + spin_unlock(&affine_mask_lock);
138041 + }
138042 + return res;
138043 +}
138044 +
138045 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
138046 + * these cases. */
138047 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
138048 + int cpu)
138049 +{
138050 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138051 + struct qman_portal *p;
138052 + p = &per_cpu(qman_affine_portal, cpu);
138053 + /* Check that we don't already have our own portal */
138054 + BUG_ON(p->config);
138055 + /* Check that we aren't already slaving to another portal */
138056 + BUG_ON(p->is_shared);
138057 + /* Check that 'redirect' is prepared to have us */
138058 + BUG_ON(!redirect->config->public_cfg.is_shared);
138059 + /* These are the only elements to initialise when redirecting */
138060 + p->irq_sources = 0;
138061 + p->sharing_redirect = redirect;
138062 + affine_portals[cpu] = p;
138063 + return p;
138064 +#else
138065 + BUG();
138066 + return NULL;
138067 +#endif
138068 +}
138069 +
138070 +void qman_destroy_portal(struct qman_portal *qm)
138071 +{
138072 + const struct qm_portal_config *pcfg;
138073 + int i;
138074 +
138075 + /* Stop dequeues on the portal */
138076 + qm_dqrr_sdqcr_set(&qm->p, 0);
138077 +
138078 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
138079 + * something related to QM_PIRQ_EQCI, this may need fixing.
138080 + * Also, due to the prefetching model used for CI updates in the enqueue
138081 + * path, this update will only invalidate the CI cacheline *after*
138082 + * working on it, so we need to call this twice to ensure a full update
138083 + * irrespective of where the enqueue processing was at when the teardown
138084 + * began. */
138085 + qm_eqcr_cce_update(&qm->p);
138086 + qm_eqcr_cce_update(&qm->p);
138087 + pcfg = qm->config;
138088 +
138089 + free_irq(pcfg->public_cfg.irq, qm);
138090 +
138091 + kfree(qm->cgrs);
138092 + if (num_ceetms)
138093 + for (i = 0; i < num_ceetms; i++)
138094 + kfree(qm->ccgrs[i]);
138095 + qm_isr_finish(&qm->p);
138096 + qm_mc_finish(&qm->p);
138097 + qm_mr_finish(&qm->p);
138098 + qm_dqrr_finish(&qm->p);
138099 + qm_eqcr_finish(&qm->p);
138100 +
138101 + platform_device_del(qm->pdev);
138102 + platform_device_put(qm->pdev);
138103 +
138104 + qm->config = NULL;
138105 + if (qm->alloced)
138106 + kfree(qm);
138107 +}
138108 +
138109 +const struct qm_portal_config *qman_destroy_affine_portal(void)
138110 +{
138111 + /* We don't want to redirect if we're a slave, use "raw" */
138112 + struct qman_portal *qm = get_raw_affine_portal();
138113 + const struct qm_portal_config *pcfg;
138114 + int cpu;
138115 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138116 + if (qm->sharing_redirect) {
138117 + qm->sharing_redirect = NULL;
138118 + put_affine_portal();
138119 + return NULL;
138120 + }
138121 + qm->is_shared = 0;
138122 +#endif
138123 + pcfg = qm->config;
138124 + cpu = pcfg->public_cfg.cpu;
138125 +
138126 + qman_destroy_portal(qm);
138127 +
138128 + spin_lock(&affine_mask_lock);
138129 + cpumask_clear_cpu(cpu, &affine_mask);
138130 + spin_unlock(&affine_mask_lock);
138131 + put_affine_portal();
138132 + return pcfg;
138133 +}
138134 +
138135 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
138136 +{
138137 + return &p->config->public_cfg;
138138 +}
138139 +EXPORT_SYMBOL(qman_p_get_portal_config);
138140 +
138141 +const struct qman_portal_config *qman_get_portal_config(void)
138142 +{
138143 + struct qman_portal *p = get_affine_portal();
138144 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
138145 + put_affine_portal();
138146 + return ret;
138147 +}
138148 +EXPORT_SYMBOL(qman_get_portal_config);
138149 +
138150 +/* Inline helper to reduce nesting in __poll_portal_slow() */
138151 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
138152 + const struct qm_mr_entry *msg, u8 verb)
138153 +{
138154 + FQLOCK(fq);
138155 + switch (verb) {
138156 + case QM_MR_VERB_FQRL:
138157 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
138158 + fq_clear(fq, QMAN_FQ_STATE_ORL);
138159 + table_del_fq(p, fq);
138160 + break;
138161 + case QM_MR_VERB_FQRN:
138162 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
138163 + (fq->state == qman_fq_state_sched));
138164 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
138165 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
138166 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
138167 + fq_set(fq, QMAN_FQ_STATE_NE);
138168 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
138169 + fq_set(fq, QMAN_FQ_STATE_ORL);
138170 + else
138171 + table_del_fq(p, fq);
138172 + fq->state = qman_fq_state_retired;
138173 + break;
138174 + case QM_MR_VERB_FQPN:
138175 + DPA_ASSERT(fq->state == qman_fq_state_sched);
138176 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
138177 + fq->state = qman_fq_state_parked;
138178 + }
138179 + FQUNLOCK(fq);
138180 +}
138181 +
138182 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
138183 +{
138184 + const struct qm_mr_entry *msg;
138185 + struct qm_mr_entry swapped_msg;
138186 + int k;
138187 +
138188 + if (is & QM_PIRQ_CSCI) {
138189 + struct qman_cgrs rr, c;
138190 + struct qm_mc_result *mcr;
138191 + struct qman_cgr *cgr;
138192 + unsigned long irqflags __maybe_unused;
138193 +
138194 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138195 + /*
138196 + * The CSCI bit must be cleared _before_ issuing the
138197 + * Query Congestion State command, to ensure that a long
138198 + * CGR State Change callback cannot miss an intervening
138199 + * state change.
138200 + */
138201 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
138202 + qm_mc_start(&p->p);
138203 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
138204 + while (!(mcr = qm_mc_result(&p->p)))
138205 + cpu_relax();
138206 + for (k = 0; k < 8; k++)
138207 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
138208 + mcr->querycongestion.state.__state[k]);
138209 + /* mask out the ones I'm not interested in */
138210 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
138211 + &mcr->querycongestion.state, &p->cgrs[0]);
138212 + /* check previous snapshot for delta, enter/exit congestion */
138213 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
138214 + /* update snapshot */
138215 + qman_cgrs_cp(&p->cgrs[1], &rr);
138216 + /* Invoke callback */
138217 + list_for_each_entry(cgr, &p->cgr_cbs, node)
138218 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
138219 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
138220 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138221 + }
138222 + if (is & QM_PIRQ_CCSCI) {
138223 + struct qman_ccgrs rr, c, congestion_result;
138224 + struct qm_mc_result *mcr;
138225 + struct qm_mc_command *mcc;
138226 + struct qm_ceetm_ccg *ccg;
138227 + unsigned long irqflags __maybe_unused;
138228 + int i, j;
138229 +
138230 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
138231 + /*
138232 + * The CCSCI bit must be cleared _before_ issuing the
138233 + * Query Congestion State command, to ensure that a long
138234 + * CCGR State Change callback cannot miss an intervening
138235 + * state change.
138236 + */
138237 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
138238 +
138239 + for (i = 0; i < num_ceetms; i++) {
138240 + for (j = 0; j < 2; j++) {
138241 + mcc = qm_mc_start(&p->p);
138242 + mcc->ccgr_query.ccgrid = cpu_to_be16(
138243 + CEETM_QUERY_CONGESTION_STATE | j);
138244 + mcc->ccgr_query.dcpid = i;
138245 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
138246 + while (!(mcr = qm_mc_result(&p->p)))
138247 + cpu_relax();
138248 + for (k = 0; k < 8; k++)
138249 + mcr->ccgr_query.congestion_state.state.
138250 + __state[k] = be32_to_cpu(
138251 + mcr->ccgr_query.
138252 + congestion_state.state.
138253 + __state[k]);
138254 + congestion_result.q[j] =
138255 + mcr->ccgr_query.congestion_state.state;
138256 + }
138257 + /* mask out the ones I'm not interested in */
138258 + qman_ccgrs_and(&rr, &congestion_result,
138259 + &p->ccgrs[i][0]);
138260 + /*
138261 + * check previous snapshot for delta, enter/exit
138262 + * congestion.
138263 + */
138264 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
138265 + /* update snapshot */
138266 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
138267 + /* Invoke callback */
138268 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
138269 + if (ccg->cb && qman_ccgrs_get(&c,
138270 + (ccg->parent->idx << 4) | ccg->idx))
138271 + ccg->cb(ccg, ccg->cb_ctx,
138272 + qman_ccgrs_get(&rr,
138273 + (ccg->parent->idx << 4)
138274 + | ccg->idx));
138275 + }
138276 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
138277 + }
138278 +
138279 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138280 + if (is & QM_PIRQ_EQCI) {
138281 + unsigned long irqflags;
138282 + PORTAL_IRQ_LOCK(p, irqflags);
138283 + p->eqci_owned = NULL;
138284 + PORTAL_IRQ_UNLOCK(p, irqflags);
138285 + wake_up(&affine_queue);
138286 + }
138287 +#endif
138288 +
138289 + if (is & QM_PIRQ_EQRI) {
138290 + unsigned long irqflags __maybe_unused;
138291 + PORTAL_IRQ_LOCK(p, irqflags);
138292 + qm_eqcr_cce_update(&p->p);
138293 + qm_eqcr_set_ithresh(&p->p, 0);
138294 + PORTAL_IRQ_UNLOCK(p, irqflags);
138295 + wake_up(&affine_queue);
138296 + }
138297 +
138298 + if (is & QM_PIRQ_MRI) {
138299 + struct qman_fq *fq;
138300 + u8 verb, num = 0;
138301 +mr_loop:
138302 + qm_mr_pvb_update(&p->p);
138303 + msg = qm_mr_current(&p->p);
138304 + if (!msg)
138305 + goto mr_done;
138306 + swapped_msg = *msg;
138307 + hw_fd_to_cpu(&swapped_msg.ern.fd);
138308 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
138309 + /* The message is a software ERN iff the 0x20 bit is set */
138310 + if (verb & 0x20) {
138311 + switch (verb) {
138312 + case QM_MR_VERB_FQRNI:
138313 + /* nada, we drop FQRNIs on the floor */
138314 + break;
138315 + case QM_MR_VERB_FQRN:
138316 + case QM_MR_VERB_FQRL:
138317 + /* Lookup in the retirement table */
138318 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
138319 + BUG_ON(!fq);
138320 + fq_state_change(p, fq, &swapped_msg, verb);
138321 + if (fq->cb.fqs)
138322 + fq->cb.fqs(p, fq, &swapped_msg);
138323 + break;
138324 + case QM_MR_VERB_FQPN:
138325 + /* Parked */
138326 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138327 + fq = get_fq_table_entry(
138328 + be32_to_cpu(msg->fq.contextB));
138329 +#else
138330 + fq = (void *)(uintptr_t)
138331 + be32_to_cpu(msg->fq.contextB);
138332 +#endif
138333 + fq_state_change(p, fq, msg, verb);
138334 + if (fq->cb.fqs)
138335 + fq->cb.fqs(p, fq, &swapped_msg);
138336 + break;
138337 + case QM_MR_VERB_DC_ERN:
138338 + /* DCP ERN */
138339 + if (p->cb_dc_ern)
138340 + p->cb_dc_ern(p, msg);
138341 + else if (cb_dc_ern)
138342 + cb_dc_ern(p, msg);
138343 + else {
138344 + static int warn_once;
138345 + if (!warn_once) {
138346 + pr_crit("Leaking DCP ERNs!\n");
138347 + warn_once = 1;
138348 + }
138349 + }
138350 + break;
138351 + default:
138352 + pr_crit("Invalid MR verb 0x%02x\n", verb);
138353 + }
138354 + } else {
138355 + /* Its a software ERN */
138356 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138357 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
138358 +#else
138359 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
138360 +#endif
138361 + fq->cb.ern(p, fq, &swapped_msg);
138362 + }
138363 + num++;
138364 + qm_mr_next(&p->p);
138365 + goto mr_loop;
138366 +mr_done:
138367 + qm_mr_cci_consume(&p->p, num);
138368 + }
138369 + /*
138370 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
138371 + * processing. If that interrupt source has meanwhile been re-asserted,
138372 + * we mustn't clear it here (or in the top-level interrupt handler).
138373 + */
138374 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
138375 +}
138376 +
138377 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
138378 + * inlined. */
138379 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
138380 +{
138381 + p->vdqcr_owned = NULL;
138382 + FQLOCK(fq);
138383 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
138384 + FQUNLOCK(fq);
138385 + wake_up(&affine_queue);
138386 +}
138387 +
138388 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
138389 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
138390 + const struct qm_dqrr_entry *src)
138391 +{
138392 + int i = 0;
138393 + const u64 *s64 = (u64*)src;
138394 + u64 *d64 = (u64*)dst;
138395 +
138396 + /* DQRR only has 32 bytes of valid data so only need to
138397 + * copy 4 - 64 bit values */
138398 + *d64 = *s64;
138399 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
138400 + {
138401 + u32 res, zero = 0;
138402 + /* Create a dependancy after copying first bytes ensures no wrap
138403 + transaction generated to QBMan */
138404 + /* Logical AND the value pointed to by s64 with 0x0 and
138405 + store the result in res */
138406 + asm volatile("and %[result], %[in1], %[in2]"
138407 + : [result] "=r" (res)
138408 + : [in1] "r" (zero), [in2] "r" (*s64)
138409 + : "memory");
138410 + /* Add res to s64 - this creates a dependancy on the result of
138411 + reading the value of s64 before the next read. The side
138412 + effect of this is that the core must stall until the first
138413 + aligned read is complete therefore preventing a WRAP
138414 + transaction to be seen by the QBMan */
138415 + asm volatile("add %[result], %[in1], %[in2]"
138416 + : [result] "=r" (s64)
138417 + : [in1] "r" (res), [in2] "r" (s64)
138418 + : "memory");
138419 + }
138420 +#endif
138421 + /* Copy the last 3 64 bit parts */
138422 + d64++; s64++;
138423 + for (;i<3; i++)
138424 + *d64++ = *s64++;
138425 +}
138426 +
138427 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
138428 + * that would conflict with other things if they ran at the same time on the
138429 + * same cpu are;
138430 + *
138431 + * (i) setting/clearing vdqcr_owned, and
138432 + * (ii) clearing the NE (Not Empty) flag.
138433 + *
138434 + * Both are safe. Because;
138435 + *
138436 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
138437 + * vdqcr_owned field (which it does before setting VDQCR), and
138438 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
138439 + * done so that we can't interfere.
138440 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
138441 + * with (i) that API prevents us from interfering until it's safe.
138442 + *
138443 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
138444 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
138445 + * advantage comes from this function not having to "lock" anything at all.
138446 + *
138447 + * Note also that the callbacks are invoked at points which are safe against the
138448 + * above potential conflicts, but that this function itself is not re-entrant
138449 + * (this is because the function tracks one end of each FIFO in the portal and
138450 + * we do *not* want to lock that). So the consequence is that it is safe for
138451 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
138452 + * sole API that could be invoking the callback through this function).
138453 + */
138454 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
138455 + unsigned int poll_limit)
138456 +{
138457 + const struct qm_dqrr_entry *dq;
138458 + struct qman_fq *fq;
138459 + enum qman_cb_dqrr_result res;
138460 + unsigned int limit = 0;
138461 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
138462 + struct qm_dqrr_entry *shadow;
138463 + const struct qm_dqrr_entry *orig_dq;
138464 +#endif
138465 +loop:
138466 + qm_dqrr_pvb_update(&p->p);
138467 + dq = qm_dqrr_current(&p->p);
138468 + if (!dq)
138469 + goto done;
138470 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
138471 + /* If running on an LE system the fields of the
138472 + dequeue entry must be swapped. Because the
138473 + QMan HW will ignore writes the DQRR entry is
138474 + copied and the index stored within the copy */
138475 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
138476 + /* Use safe copy here to avoid WRAP transaction */
138477 + safe_copy_dqrr(shadow, dq);
138478 + orig_dq = dq;
138479 + dq = shadow;
138480 + shadow->fqid = be32_to_cpu(shadow->fqid);
138481 + shadow->contextB = be32_to_cpu(shadow->contextB);
138482 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
138483 + hw_fd_to_cpu(&shadow->fd);
138484 +#endif
138485 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
138486 + /* VDQCR: don't trust contextB as the FQ may have been
138487 + * configured for h/w consumption and we're draining it
138488 + * post-retirement. */
138489 + fq = p->vdqcr_owned;
138490 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
138491 + * to check for clearing it when doing volatile dequeues. It's
138492 + * one less thing to check in the critical path (SDQCR). */
138493 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
138494 + fq_clear(fq, QMAN_FQ_STATE_NE);
138495 + /* this is duplicated from the SDQCR code, but we have stuff to
138496 + * do before *and* after this callback, and we don't want
138497 + * multiple if()s in the critical path (SDQCR). */
138498 + res = fq->cb.dqrr(p, fq, dq);
138499 + if (res == qman_cb_dqrr_stop)
138500 + goto done;
138501 + /* Check for VDQCR completion */
138502 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
138503 + clear_vdqcr(p, fq);
138504 + } else {
138505 + /* SDQCR: contextB points to the FQ */
138506 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138507 + fq = get_fq_table_entry(dq->contextB);
138508 +#else
138509 + fq = (void *)(uintptr_t)dq->contextB;
138510 +#endif
138511 + /* Now let the callback do its stuff */
138512 + res = fq->cb.dqrr(p, fq, dq);
138513 +
138514 + /* The callback can request that we exit without consuming this
138515 + * entry nor advancing; */
138516 + if (res == qman_cb_dqrr_stop)
138517 + goto done;
138518 + }
138519 + /* Interpret 'dq' from a driver perspective. */
138520 + /* Parking isn't possible unless HELDACTIVE was set. NB,
138521 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
138522 + * check for HELDACTIVE to cover both. */
138523 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
138524 + (res != qman_cb_dqrr_park));
138525 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
138526 + if (res != qman_cb_dqrr_defer)
138527 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
138528 + (res == qman_cb_dqrr_park));
138529 +#else
138530 + /* Defer just means "skip it, I'll consume it myself later on" */
138531 + if (res != qman_cb_dqrr_defer)
138532 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
138533 +#endif
138534 + /* Move forward */
138535 + qm_dqrr_next(&p->p);
138536 + /* Entry processed and consumed, increment our counter. The callback can
138537 + * request that we exit after consuming the entry, and we also exit if
138538 + * we reach our processing limit, so loop back only if neither of these
138539 + * conditions is met. */
138540 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
138541 + goto loop;
138542 +done:
138543 + return limit;
138544 +}
138545 +
138546 +u32 qman_irqsource_get(void)
138547 +{
138548 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
138549 + * should shut the user out if they are not the primary CPU hosting the
138550 + * portal. That's why we use the "raw" interface. */
138551 + struct qman_portal *p = get_raw_affine_portal();
138552 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
138553 + put_affine_portal();
138554 + return ret;
138555 +}
138556 +EXPORT_SYMBOL(qman_irqsource_get);
138557 +
138558 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
138559 +{
138560 + __maybe_unused unsigned long irqflags;
138561 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138562 + if (p->sharing_redirect)
138563 + return -EINVAL;
138564 + else
138565 +#endif
138566 + {
138567 + bits = bits & QM_PIRQ_VISIBLE;
138568 + PORTAL_IRQ_LOCK(p, irqflags);
138569 +
138570 + /* Clear any previously remaining interrupt conditions in
138571 + * QCSP_ISR. This prevents raising a false interrupt when
138572 + * interrupt conditions are enabled in QCSP_IER.
138573 + */
138574 + qm_isr_status_clear(&p->p, bits);
138575 + set_bits(bits, &p->irq_sources);
138576 + qm_isr_enable_write(&p->p, p->irq_sources);
138577 + PORTAL_IRQ_UNLOCK(p, irqflags);
138578 + }
138579 + return 0;
138580 +}
138581 +EXPORT_SYMBOL(qman_p_irqsource_add);
138582 +
138583 +int qman_irqsource_add(u32 bits __maybe_unused)
138584 +{
138585 + struct qman_portal *p = get_raw_affine_portal();
138586 + int ret;
138587 + ret = qman_p_irqsource_add(p, bits);
138588 + put_affine_portal();
138589 + return ret;
138590 +}
138591 +EXPORT_SYMBOL(qman_irqsource_add);
138592 +
138593 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
138594 +{
138595 + __maybe_unused unsigned long irqflags;
138596 + u32 ier;
138597 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138598 + if (p->sharing_redirect) {
138599 + put_affine_portal();
138600 + return -EINVAL;
138601 + }
138602 +#endif
138603 + /* Our interrupt handler only processes+clears status register bits that
138604 + * are in p->irq_sources. As we're trimming that mask, if one of them
138605 + * were to assert in the status register just before we remove it from
138606 + * the enable register, there would be an interrupt-storm when we
138607 + * release the IRQ lock. So we wait for the enable register update to
138608 + * take effect in h/w (by reading it back) and then clear all other bits
138609 + * in the status register. Ie. we clear them from ISR once it's certain
138610 + * IER won't allow them to reassert. */
138611 + PORTAL_IRQ_LOCK(p, irqflags);
138612 + bits &= QM_PIRQ_VISIBLE;
138613 + clear_bits(bits, &p->irq_sources);
138614 + qm_isr_enable_write(&p->p, p->irq_sources);
138615 +
138616 + ier = qm_isr_enable_read(&p->p);
138617 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
138618 + * data-dependency, ie. to protect against re-ordering. */
138619 + qm_isr_status_clear(&p->p, ~ier);
138620 + PORTAL_IRQ_UNLOCK(p, irqflags);
138621 + return 0;
138622 +}
138623 +EXPORT_SYMBOL(qman_p_irqsource_remove);
138624 +
138625 +int qman_irqsource_remove(u32 bits)
138626 +{
138627 + struct qman_portal *p = get_raw_affine_portal();
138628 + int ret;
138629 + ret = qman_p_irqsource_remove(p, bits);
138630 + put_affine_portal();
138631 + return ret;
138632 +}
138633 +EXPORT_SYMBOL(qman_irqsource_remove);
138634 +
138635 +const cpumask_t *qman_affine_cpus(void)
138636 +{
138637 + return &affine_mask;
138638 +}
138639 +EXPORT_SYMBOL(qman_affine_cpus);
138640 +
138641 +u16 qman_affine_channel(int cpu)
138642 +{
138643 + if (cpu < 0) {
138644 + struct qman_portal *portal = get_raw_affine_portal();
138645 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138646 + BUG_ON(portal->sharing_redirect);
138647 +#endif
138648 + cpu = portal->config->public_cfg.cpu;
138649 + put_affine_portal();
138650 + }
138651 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
138652 + return affine_channels[cpu];
138653 +}
138654 +EXPORT_SYMBOL(qman_affine_channel);
138655 +
138656 +void *qman_get_affine_portal(int cpu)
138657 +{
138658 + return affine_portals[cpu];
138659 +}
138660 +EXPORT_SYMBOL(qman_get_affine_portal);
138661 +
138662 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
138663 +{
138664 + int ret;
138665 +
138666 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138667 + if (unlikely(p->sharing_redirect))
138668 + ret = -EINVAL;
138669 + else
138670 +#endif
138671 + {
138672 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
138673 + ret = __poll_portal_fast(p, limit);
138674 + }
138675 + return ret;
138676 +}
138677 +EXPORT_SYMBOL(qman_p_poll_dqrr);
138678 +
138679 +int qman_poll_dqrr(unsigned int limit)
138680 +{
138681 + struct qman_portal *p = get_poll_portal();
138682 + int ret;
138683 + ret = qman_p_poll_dqrr(p, limit);
138684 + put_poll_portal();
138685 + return ret;
138686 +}
138687 +EXPORT_SYMBOL(qman_poll_dqrr);
138688 +
138689 +u32 qman_p_poll_slow(struct qman_portal *p)
138690 +{
138691 + u32 ret;
138692 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138693 + if (unlikely(p->sharing_redirect))
138694 + ret = (u32)-1;
138695 + else
138696 +#endif
138697 + {
138698 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
138699 + ret = __poll_portal_slow(p, is);
138700 + qm_isr_status_clear(&p->p, ret);
138701 + }
138702 + return ret;
138703 +}
138704 +EXPORT_SYMBOL(qman_p_poll_slow);
138705 +
138706 +u32 qman_poll_slow(void)
138707 +{
138708 + struct qman_portal *p = get_poll_portal();
138709 + u32 ret;
138710 + ret = qman_p_poll_slow(p);
138711 + put_poll_portal();
138712 + return ret;
138713 +}
138714 +EXPORT_SYMBOL(qman_poll_slow);
138715 +
138716 +/* Legacy wrapper */
138717 +void qman_p_poll(struct qman_portal *p)
138718 +{
138719 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138720 + if (unlikely(p->sharing_redirect))
138721 + return;
138722 +#endif
138723 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
138724 + if (!(p->slowpoll--)) {
138725 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
138726 + u32 active = __poll_portal_slow(p, is);
138727 + if (active) {
138728 + qm_isr_status_clear(&p->p, active);
138729 + p->slowpoll = SLOW_POLL_BUSY;
138730 + } else
138731 + p->slowpoll = SLOW_POLL_IDLE;
138732 + }
138733 + }
138734 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
138735 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
138736 +}
138737 +EXPORT_SYMBOL(qman_p_poll);
138738 +
138739 +void qman_poll(void)
138740 +{
138741 + struct qman_portal *p = get_poll_portal();
138742 + qman_p_poll(p);
138743 + put_poll_portal();
138744 +}
138745 +EXPORT_SYMBOL(qman_poll);
138746 +
138747 +void qman_p_stop_dequeues(struct qman_portal *p)
138748 +{
138749 + qman_stop_dequeues_ex(p);
138750 +}
138751 +EXPORT_SYMBOL(qman_p_stop_dequeues);
138752 +
138753 +void qman_stop_dequeues(void)
138754 +{
138755 + struct qman_portal *p = get_affine_portal();
138756 + qman_p_stop_dequeues(p);
138757 + put_affine_portal();
138758 +}
138759 +EXPORT_SYMBOL(qman_stop_dequeues);
138760 +
138761 +void qman_p_start_dequeues(struct qman_portal *p)
138762 +{
138763 + unsigned long irqflags __maybe_unused;
138764 + PORTAL_IRQ_LOCK(p, irqflags);
138765 + DPA_ASSERT(p->dqrr_disable_ref > 0);
138766 + if (!(--p->dqrr_disable_ref))
138767 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
138768 + PORTAL_IRQ_UNLOCK(p, irqflags);
138769 +}
138770 +EXPORT_SYMBOL(qman_p_start_dequeues);
138771 +
138772 +void qman_start_dequeues(void)
138773 +{
138774 + struct qman_portal *p = get_affine_portal();
138775 + qman_p_start_dequeues(p);
138776 + put_affine_portal();
138777 +}
138778 +EXPORT_SYMBOL(qman_start_dequeues);
138779 +
138780 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
138781 +{
138782 + unsigned long irqflags __maybe_unused;
138783 + PORTAL_IRQ_LOCK(p, irqflags);
138784 + pools &= p->config->public_cfg.pools;
138785 + p->sdqcr |= pools;
138786 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
138787 + PORTAL_IRQ_UNLOCK(p, irqflags);
138788 +}
138789 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
138790 +
138791 +void qman_static_dequeue_add(u32 pools)
138792 +{
138793 + struct qman_portal *p = get_affine_portal();
138794 + qman_p_static_dequeue_add(p, pools);
138795 + put_affine_portal();
138796 +}
138797 +EXPORT_SYMBOL(qman_static_dequeue_add);
138798 +
138799 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
138800 +{
138801 + unsigned long irqflags __maybe_unused;
138802 + PORTAL_IRQ_LOCK(p, irqflags);
138803 + pools &= p->config->public_cfg.pools;
138804 + p->sdqcr &= ~pools;
138805 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
138806 + PORTAL_IRQ_UNLOCK(p, irqflags);
138807 +}
138808 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
138809 +
138810 +void qman_static_dequeue_del(u32 pools)
138811 +{
138812 + struct qman_portal *p = get_affine_portal();
138813 + qman_p_static_dequeue_del(p, pools);
138814 + put_affine_portal();
138815 +}
138816 +EXPORT_SYMBOL(qman_static_dequeue_del);
138817 +
138818 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
138819 +{
138820 + return p->sdqcr;
138821 +}
138822 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
138823 +
138824 +u32 qman_static_dequeue_get(void)
138825 +{
138826 + struct qman_portal *p = get_affine_portal();
138827 + u32 ret = qman_p_static_dequeue_get(p);
138828 + put_affine_portal();
138829 + return ret;
138830 +}
138831 +EXPORT_SYMBOL(qman_static_dequeue_get);
138832 +
138833 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
138834 + int park_request)
138835 +{
138836 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
138837 +}
138838 +EXPORT_SYMBOL(qman_p_dca);
138839 +
138840 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
138841 +{
138842 + struct qman_portal *p = get_affine_portal();
138843 + qman_p_dca(p, dq, park_request);
138844 + put_affine_portal();
138845 +}
138846 +EXPORT_SYMBOL(qman_dca);
138847 +
138848 +/*******************/
138849 +/* Frame queue API */
138850 +/*******************/
138851 +
138852 +static const char *mcr_result_str(u8 result)
138853 +{
138854 + switch (result) {
138855 + case QM_MCR_RESULT_NULL:
138856 + return "QM_MCR_RESULT_NULL";
138857 + case QM_MCR_RESULT_OK:
138858 + return "QM_MCR_RESULT_OK";
138859 + case QM_MCR_RESULT_ERR_FQID:
138860 + return "QM_MCR_RESULT_ERR_FQID";
138861 + case QM_MCR_RESULT_ERR_FQSTATE:
138862 + return "QM_MCR_RESULT_ERR_FQSTATE";
138863 + case QM_MCR_RESULT_ERR_NOTEMPTY:
138864 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
138865 + case QM_MCR_RESULT_PENDING:
138866 + return "QM_MCR_RESULT_PENDING";
138867 + case QM_MCR_RESULT_ERR_BADCOMMAND:
138868 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
138869 + }
138870 + return "<unknown MCR result>";
138871 +}
138872 +
138873 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
138874 +{
138875 + struct qm_fqd fqd;
138876 + struct qm_mcr_queryfq_np np;
138877 + struct qm_mc_command *mcc;
138878 + struct qm_mc_result *mcr;
138879 + struct qman_portal *p;
138880 + unsigned long irqflags __maybe_unused;
138881 +
138882 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
138883 + int ret = qman_alloc_fqid(&fqid);
138884 + if (ret)
138885 + return ret;
138886 + }
138887 + spin_lock_init(&fq->fqlock);
138888 + fq->fqid = fqid;
138889 + fq->flags = flags;
138890 + fq->state = qman_fq_state_oos;
138891 + fq->cgr_groupid = 0;
138892 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138893 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
138894 + return -ENOMEM;
138895 +#endif
138896 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
138897 + return 0;
138898 + /* Everything else is AS_IS support */
138899 + p = get_affine_portal();
138900 + PORTAL_IRQ_LOCK(p, irqflags);
138901 + mcc = qm_mc_start(&p->p);
138902 + mcc->queryfq.fqid = cpu_to_be32(fqid);
138903 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
138904 + while (!(mcr = qm_mc_result(&p->p)))
138905 + cpu_relax();
138906 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
138907 + if (mcr->result != QM_MCR_RESULT_OK) {
138908 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
138909 + goto err;
138910 + }
138911 + fqd = mcr->queryfq.fqd;
138912 + hw_fqd_to_cpu(&fqd);
138913 + mcc = qm_mc_start(&p->p);
138914 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
138915 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
138916 + while (!(mcr = qm_mc_result(&p->p)))
138917 + cpu_relax();
138918 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
138919 + if (mcr->result != QM_MCR_RESULT_OK) {
138920 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
138921 + goto err;
138922 + }
138923 + np = mcr->queryfq_np;
138924 + /* Phew, have queryfq and queryfq_np results, stitch together
138925 + * the FQ object from those. */
138926 + fq->cgr_groupid = fqd.cgid;
138927 + switch (np.state & QM_MCR_NP_STATE_MASK) {
138928 + case QM_MCR_NP_STATE_OOS:
138929 + break;
138930 + case QM_MCR_NP_STATE_RETIRED:
138931 + fq->state = qman_fq_state_retired;
138932 + if (np.frm_cnt)
138933 + fq_set(fq, QMAN_FQ_STATE_NE);
138934 + break;
138935 + case QM_MCR_NP_STATE_TEN_SCHED:
138936 + case QM_MCR_NP_STATE_TRU_SCHED:
138937 + case QM_MCR_NP_STATE_ACTIVE:
138938 + fq->state = qman_fq_state_sched;
138939 + if (np.state & QM_MCR_NP_STATE_R)
138940 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
138941 + break;
138942 + case QM_MCR_NP_STATE_PARKED:
138943 + fq->state = qman_fq_state_parked;
138944 + break;
138945 + default:
138946 + DPA_ASSERT(NULL == "invalid FQ state");
138947 + }
138948 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
138949 + fq->state |= QMAN_FQ_STATE_CGR_EN;
138950 + PORTAL_IRQ_UNLOCK(p, irqflags);
138951 + put_affine_portal();
138952 + return 0;
138953 +err:
138954 + PORTAL_IRQ_UNLOCK(p, irqflags);
138955 + put_affine_portal();
138956 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
138957 + qman_release_fqid(fqid);
138958 + return -EIO;
138959 +}
138960 +EXPORT_SYMBOL(qman_create_fq);
138961 +
138962 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
138963 +{
138964 +
138965 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
138966 + * quiesced. Instead, run some checks. */
138967 + switch (fq->state) {
138968 + case qman_fq_state_parked:
138969 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
138970 + case qman_fq_state_oos:
138971 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
138972 + qman_release_fqid(fq->fqid);
138973 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138974 + clear_fq_table_entry(fq->key);
138975 +#endif
138976 + return;
138977 + default:
138978 + break;
138979 + }
138980 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
138981 +}
138982 +EXPORT_SYMBOL(qman_destroy_fq);
138983 +
138984 +u32 qman_fq_fqid(struct qman_fq *fq)
138985 +{
138986 + return fq->fqid;
138987 +}
138988 +EXPORT_SYMBOL(qman_fq_fqid);
138989 +
138990 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
138991 +{
138992 + if (state)
138993 + *state = fq->state;
138994 + if (flags)
138995 + *flags = fq->flags;
138996 +}
138997 +EXPORT_SYMBOL(qman_fq_state);
138998 +
138999 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
139000 +{
139001 + struct qm_mc_command *mcc;
139002 + struct qm_mc_result *mcr;
139003 + struct qman_portal *p;
139004 + unsigned long irqflags __maybe_unused;
139005 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
139006 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
139007 +
139008 + if ((fq->state != qman_fq_state_oos) &&
139009 + (fq->state != qman_fq_state_parked))
139010 + return -EINVAL;
139011 +#ifdef CONFIG_FSL_DPA_CHECKING
139012 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139013 + return -EINVAL;
139014 +#endif
139015 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
139016 + /* And can't be set at the same time as TDTHRESH */
139017 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
139018 + return -EINVAL;
139019 + }
139020 + /* Issue an INITFQ_[PARKED|SCHED] management command */
139021 + p = get_affine_portal();
139022 + PORTAL_IRQ_LOCK(p, irqflags);
139023 + FQLOCK(fq);
139024 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139025 + ((fq->state != qman_fq_state_oos) &&
139026 + (fq->state != qman_fq_state_parked)))) {
139027 + FQUNLOCK(fq);
139028 + PORTAL_IRQ_UNLOCK(p, irqflags);
139029 + put_affine_portal();
139030 + return -EBUSY;
139031 + }
139032 + mcc = qm_mc_start(&p->p);
139033 + if (opts)
139034 + mcc->initfq = *opts;
139035 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
139036 + mcc->initfq.count = 0;
139037 +
139038 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
139039 + * demux pointer. Otherwise, the caller-provided value is allowed to
139040 + * stand, don't overwrite it. */
139041 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
139042 + dma_addr_t phys_fq;
139043 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
139044 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139045 + mcc->initfq.fqd.context_b = fq->key;
139046 +#else
139047 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
139048 +#endif
139049 + /* and the physical address - NB, if the user wasn't trying to
139050 + * set CONTEXTA, clear the stashing settings. */
139051 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
139052 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
139053 + memset(&mcc->initfq.fqd.context_a, 0,
139054 + sizeof(mcc->initfq.fqd.context_a));
139055 + } else {
139056 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
139057 + DMA_TO_DEVICE);
139058 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
139059 + }
139060 + }
139061 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
139062 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
139063 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
139064 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
139065 + mcc->initfq.fqd.dest.wq = 4;
139066 + }
139067 + }
139068 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
139069 + cpu_to_hw_fqd(&mcc->initfq.fqd);
139070 + qm_mc_commit(&p->p, myverb);
139071 + while (!(mcr = qm_mc_result(&p->p)))
139072 + cpu_relax();
139073 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
139074 + res = mcr->result;
139075 + if (res != QM_MCR_RESULT_OK) {
139076 + FQUNLOCK(fq);
139077 + PORTAL_IRQ_UNLOCK(p, irqflags);
139078 + put_affine_portal();
139079 + return -EIO;
139080 + }
139081 + if (opts) {
139082 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
139083 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
139084 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
139085 + else
139086 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
139087 + }
139088 + if (opts->we_mask & QM_INITFQ_WE_CGID)
139089 + fq->cgr_groupid = opts->fqd.cgid;
139090 + }
139091 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
139092 + qman_fq_state_sched : qman_fq_state_parked;
139093 + FQUNLOCK(fq);
139094 + PORTAL_IRQ_UNLOCK(p, irqflags);
139095 + put_affine_portal();
139096 + return 0;
139097 +}
139098 +EXPORT_SYMBOL(qman_init_fq);
139099 +
139100 +int qman_schedule_fq(struct qman_fq *fq)
139101 +{
139102 + struct qm_mc_command *mcc;
139103 + struct qm_mc_result *mcr;
139104 + struct qman_portal *p;
139105 + unsigned long irqflags __maybe_unused;
139106 + int ret = 0;
139107 + u8 res;
139108 +
139109 + if (fq->state != qman_fq_state_parked)
139110 + return -EINVAL;
139111 +#ifdef CONFIG_FSL_DPA_CHECKING
139112 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139113 + return -EINVAL;
139114 +#endif
139115 + /* Issue a ALTERFQ_SCHED management command */
139116 + p = get_affine_portal();
139117 + PORTAL_IRQ_LOCK(p, irqflags);
139118 + FQLOCK(fq);
139119 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139120 + (fq->state != qman_fq_state_parked))) {
139121 + ret = -EBUSY;
139122 + goto out;
139123 + }
139124 + mcc = qm_mc_start(&p->p);
139125 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
139126 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
139127 + while (!(mcr = qm_mc_result(&p->p)))
139128 + cpu_relax();
139129 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
139130 + res = mcr->result;
139131 + if (res != QM_MCR_RESULT_OK) {
139132 + ret = -EIO;
139133 + goto out;
139134 + }
139135 + fq->state = qman_fq_state_sched;
139136 +out:
139137 + FQUNLOCK(fq);
139138 + PORTAL_IRQ_UNLOCK(p, irqflags);
139139 + put_affine_portal();
139140 + return ret;
139141 +}
139142 +EXPORT_SYMBOL(qman_schedule_fq);
139143 +
139144 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
139145 +{
139146 + struct qm_mc_command *mcc;
139147 + struct qm_mc_result *mcr;
139148 + struct qman_portal *p;
139149 + unsigned long irqflags __maybe_unused;
139150 + int rval;
139151 + u8 res;
139152 +
139153 + if ((fq->state != qman_fq_state_parked) &&
139154 + (fq->state != qman_fq_state_sched))
139155 + return -EINVAL;
139156 +#ifdef CONFIG_FSL_DPA_CHECKING
139157 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139158 + return -EINVAL;
139159 +#endif
139160 + p = get_affine_portal();
139161 + PORTAL_IRQ_LOCK(p, irqflags);
139162 + FQLOCK(fq);
139163 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139164 + (fq->state == qman_fq_state_retired) ||
139165 + (fq->state == qman_fq_state_oos))) {
139166 + rval = -EBUSY;
139167 + goto out;
139168 + }
139169 + rval = table_push_fq(p, fq);
139170 + if (rval)
139171 + goto out;
139172 + mcc = qm_mc_start(&p->p);
139173 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
139174 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
139175 + while (!(mcr = qm_mc_result(&p->p)))
139176 + cpu_relax();
139177 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
139178 + res = mcr->result;
139179 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
139180 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
139181 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
139182 + * friendly, otherwise the caller doesn't necessarily have a fully
139183 + * "retired" FQ on return even if the retirement was immediate. However
139184 + * this does mean some code duplication between here and
139185 + * fq_state_change(). */
139186 + if (likely(res == QM_MCR_RESULT_OK)) {
139187 + rval = 0;
139188 + /* Process 'fq' right away, we'll ignore FQRNI */
139189 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
139190 + fq_set(fq, QMAN_FQ_STATE_NE);
139191 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
139192 + fq_set(fq, QMAN_FQ_STATE_ORL);
139193 + else
139194 + table_del_fq(p, fq);
139195 + if (flags)
139196 + *flags = fq->flags;
139197 + fq->state = qman_fq_state_retired;
139198 + if (fq->cb.fqs) {
139199 + /* Another issue with supporting "immediate" retirement
139200 + * is that we're forced to drop FQRNIs, because by the
139201 + * time they're seen it may already be "too late" (the
139202 + * fq may have been OOS'd and free()'d already). But if
139203 + * the upper layer wants a callback whether it's
139204 + * immediate or not, we have to fake a "MR" entry to
139205 + * look like an FQRNI... */
139206 + struct qm_mr_entry msg;
139207 + msg.verb = QM_MR_VERB_FQRNI;
139208 + msg.fq.fqs = mcr->alterfq.fqs;
139209 + msg.fq.fqid = fq->fqid;
139210 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139211 + msg.fq.contextB = fq->key;
139212 +#else
139213 + msg.fq.contextB = (u32)(uintptr_t)fq;
139214 +#endif
139215 + fq->cb.fqs(p, fq, &msg);
139216 + }
139217 + } else if (res == QM_MCR_RESULT_PENDING) {
139218 + rval = 1;
139219 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
139220 + } else {
139221 + rval = -EIO;
139222 + table_del_fq(p, fq);
139223 + }
139224 +out:
139225 + FQUNLOCK(fq);
139226 + PORTAL_IRQ_UNLOCK(p, irqflags);
139227 + put_affine_portal();
139228 + return rval;
139229 +}
139230 +EXPORT_SYMBOL(qman_retire_fq);
139231 +
139232 +int qman_oos_fq(struct qman_fq *fq)
139233 +{
139234 + struct qm_mc_command *mcc;
139235 + struct qm_mc_result *mcr;
139236 + struct qman_portal *p;
139237 + unsigned long irqflags __maybe_unused;
139238 + int ret = 0;
139239 + u8 res;
139240 +
139241 + if (fq->state != qman_fq_state_retired)
139242 + return -EINVAL;
139243 +#ifdef CONFIG_FSL_DPA_CHECKING
139244 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139245 + return -EINVAL;
139246 +#endif
139247 + p = get_affine_portal();
139248 + PORTAL_IRQ_LOCK(p, irqflags);
139249 + FQLOCK(fq);
139250 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
139251 + (fq->state != qman_fq_state_retired))) {
139252 + ret = -EBUSY;
139253 + goto out;
139254 + }
139255 + mcc = qm_mc_start(&p->p);
139256 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
139257 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
139258 + while (!(mcr = qm_mc_result(&p->p)))
139259 + cpu_relax();
139260 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
139261 + res = mcr->result;
139262 + if (res != QM_MCR_RESULT_OK) {
139263 + ret = -EIO;
139264 + goto out;
139265 + }
139266 + fq->state = qman_fq_state_oos;
139267 +out:
139268 + FQUNLOCK(fq);
139269 + PORTAL_IRQ_UNLOCK(p, irqflags);
139270 + put_affine_portal();
139271 + return ret;
139272 +}
139273 +EXPORT_SYMBOL(qman_oos_fq);
139274 +
139275 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
139276 +{
139277 + struct qm_mc_command *mcc;
139278 + struct qm_mc_result *mcr;
139279 + struct qman_portal *p;
139280 + unsigned long irqflags __maybe_unused;
139281 + int ret = 0;
139282 + u8 res;
139283 + u8 myverb;
139284 +
139285 + if ((fq->state == qman_fq_state_oos) ||
139286 + (fq->state == qman_fq_state_retired) ||
139287 + (fq->state == qman_fq_state_parked))
139288 + return -EINVAL;
139289 +
139290 +#ifdef CONFIG_FSL_DPA_CHECKING
139291 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139292 + return -EINVAL;
139293 +#endif
139294 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
139295 + p = get_affine_portal();
139296 + PORTAL_IRQ_LOCK(p, irqflags);
139297 + FQLOCK(fq);
139298 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139299 + (fq->state == qman_fq_state_parked) ||
139300 + (fq->state == qman_fq_state_oos) ||
139301 + (fq->state == qman_fq_state_retired))) {
139302 + ret = -EBUSY;
139303 + goto out;
139304 + }
139305 + mcc = qm_mc_start(&p->p);
139306 + mcc->alterfq.fqid = fq->fqid;
139307 + mcc->alterfq.count = 0;
139308 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
139309 +
139310 + qm_mc_commit(&p->p, myverb);
139311 + while (!(mcr = qm_mc_result(&p->p)))
139312 + cpu_relax();
139313 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
139314 +
139315 + res = mcr->result;
139316 + if (res != QM_MCR_RESULT_OK) {
139317 + ret = -EIO;
139318 + goto out;
139319 + }
139320 +out:
139321 + FQUNLOCK(fq);
139322 + PORTAL_IRQ_UNLOCK(p, irqflags);
139323 + put_affine_portal();
139324 + return ret;
139325 +}
139326 +EXPORT_SYMBOL(qman_fq_flow_control);
139327 +
139328 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
139329 +{
139330 + struct qm_mc_command *mcc;
139331 + struct qm_mc_result *mcr;
139332 + struct qman_portal *p = get_affine_portal();
139333 + unsigned long irqflags __maybe_unused;
139334 + u8 res;
139335 +
139336 + PORTAL_IRQ_LOCK(p, irqflags);
139337 + mcc = qm_mc_start(&p->p);
139338 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
139339 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
139340 + while (!(mcr = qm_mc_result(&p->p)))
139341 + cpu_relax();
139342 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
139343 + res = mcr->result;
139344 + if (res == QM_MCR_RESULT_OK)
139345 + *fqd = mcr->queryfq.fqd;
139346 + hw_fqd_to_cpu(fqd);
139347 + PORTAL_IRQ_UNLOCK(p, irqflags);
139348 + put_affine_portal();
139349 + if (res != QM_MCR_RESULT_OK)
139350 + return -EIO;
139351 + return 0;
139352 +}
139353 +EXPORT_SYMBOL(qman_query_fq);
139354 +
139355 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
139356 +{
139357 + struct qm_mc_command *mcc;
139358 + struct qm_mc_result *mcr;
139359 + struct qman_portal *p = get_affine_portal();
139360 + unsigned long irqflags __maybe_unused;
139361 + u8 res;
139362 +
139363 + PORTAL_IRQ_LOCK(p, irqflags);
139364 + mcc = qm_mc_start(&p->p);
139365 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
139366 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
139367 + while (!(mcr = qm_mc_result(&p->p)))
139368 + cpu_relax();
139369 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
139370 + res = mcr->result;
139371 + if (res == QM_MCR_RESULT_OK) {
139372 + *np = mcr->queryfq_np;
139373 + np->fqd_link = be24_to_cpu(np->fqd_link);
139374 + np->odp_seq = be16_to_cpu(np->odp_seq);
139375 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
139376 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
139377 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
139378 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
139379 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
139380 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
139381 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
139382 + np->ics_surp = be16_to_cpu(np->ics_surp);
139383 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
139384 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
139385 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
139386 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
139387 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
139388 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
139389 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
139390 + }
139391 + PORTAL_IRQ_UNLOCK(p, irqflags);
139392 + put_affine_portal();
139393 + if (res == QM_MCR_RESULT_ERR_FQID)
139394 + return -ERANGE;
139395 + else if (res != QM_MCR_RESULT_OK)
139396 + return -EIO;
139397 + return 0;
139398 +}
139399 +EXPORT_SYMBOL(qman_query_fq_np);
139400 +
139401 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
139402 +{
139403 + struct qm_mc_command *mcc;
139404 + struct qm_mc_result *mcr;
139405 + struct qman_portal *p = get_affine_portal();
139406 + unsigned long irqflags __maybe_unused;
139407 + u8 res, myverb;
139408 +
139409 + PORTAL_IRQ_LOCK(p, irqflags);
139410 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
139411 + QM_MCR_VERB_QUERYWQ;
139412 + mcc = qm_mc_start(&p->p);
139413 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
139414 + qm_mc_commit(&p->p, myverb);
139415 + while (!(mcr = qm_mc_result(&p->p)))
139416 + cpu_relax();
139417 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
139418 + res = mcr->result;
139419 + if (res == QM_MCR_RESULT_OK) {
139420 + int i, array_len;
139421 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
139422 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
139423 + for (i = 0; i < array_len; i++)
139424 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
139425 + }
139426 + PORTAL_IRQ_UNLOCK(p, irqflags);
139427 + put_affine_portal();
139428 + if (res != QM_MCR_RESULT_OK) {
139429 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
139430 + return -EIO;
139431 + }
139432 + return 0;
139433 +}
139434 +EXPORT_SYMBOL(qman_query_wq);
139435 +
139436 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
139437 + struct qm_mcr_cgrtestwrite *result)
139438 +{
139439 + struct qm_mc_command *mcc;
139440 + struct qm_mc_result *mcr;
139441 + struct qman_portal *p = get_affine_portal();
139442 + unsigned long irqflags __maybe_unused;
139443 + u8 res;
139444 +
139445 + PORTAL_IRQ_LOCK(p, irqflags);
139446 + mcc = qm_mc_start(&p->p);
139447 + mcc->cgrtestwrite.cgid = cgr->cgrid;
139448 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
139449 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
139450 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
139451 + while (!(mcr = qm_mc_result(&p->p)))
139452 + cpu_relax();
139453 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
139454 + res = mcr->result;
139455 + if (res == QM_MCR_RESULT_OK)
139456 + *result = mcr->cgrtestwrite;
139457 + PORTAL_IRQ_UNLOCK(p, irqflags);
139458 + put_affine_portal();
139459 + if (res != QM_MCR_RESULT_OK) {
139460 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
139461 + return -EIO;
139462 + }
139463 + return 0;
139464 +}
139465 +EXPORT_SYMBOL(qman_testwrite_cgr);
139466 +
139467 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
139468 +{
139469 + struct qm_mc_command *mcc;
139470 + struct qm_mc_result *mcr;
139471 + struct qman_portal *p = get_affine_portal();
139472 + unsigned long irqflags __maybe_unused;
139473 + u8 res;
139474 + int i;
139475 +
139476 + PORTAL_IRQ_LOCK(p, irqflags);
139477 + mcc = qm_mc_start(&p->p);
139478 + mcc->querycgr.cgid = cgr->cgrid;
139479 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
139480 + while (!(mcr = qm_mc_result(&p->p)))
139481 + cpu_relax();
139482 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
139483 + res = mcr->result;
139484 + if (res == QM_MCR_RESULT_OK)
139485 + *cgrd = mcr->querycgr;
139486 + PORTAL_IRQ_UNLOCK(p, irqflags);
139487 + put_affine_portal();
139488 + if (res != QM_MCR_RESULT_OK) {
139489 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
139490 + return -EIO;
139491 + }
139492 + cgrd->cgr.wr_parm_g.word =
139493 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
139494 + cgrd->cgr.wr_parm_y.word =
139495 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
139496 + cgrd->cgr.wr_parm_r.word =
139497 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
139498 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
139499 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
139500 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
139501 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
139502 + return 0;
139503 +}
139504 +EXPORT_SYMBOL(qman_query_cgr);
139505 +
139506 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
139507 +{
139508 + struct qm_mc_result *mcr;
139509 + struct qman_portal *p = get_affine_portal();
139510 + unsigned long irqflags __maybe_unused;
139511 + u8 res;
139512 + int i;
139513 +
139514 + PORTAL_IRQ_LOCK(p, irqflags);
139515 + qm_mc_start(&p->p);
139516 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
139517 + while (!(mcr = qm_mc_result(&p->p)))
139518 + cpu_relax();
139519 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139520 + QM_MCC_VERB_QUERYCONGESTION);
139521 + res = mcr->result;
139522 + if (res == QM_MCR_RESULT_OK)
139523 + memcpy_fromio(congestion, &mcr->querycongestion,
139524 + sizeof(*congestion));
139525 + PORTAL_IRQ_UNLOCK(p, irqflags);
139526 + put_affine_portal();
139527 + if (res != QM_MCR_RESULT_OK) {
139528 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
139529 + return -EIO;
139530 + }
139531 +
139532 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
139533 + be32_to_cpus(&congestion->state.__state[i]);
139534 + return 0;
139535 +}
139536 +EXPORT_SYMBOL(qman_query_congestion);
139537 +
139538 +/* internal function used as a wait_event() expression */
139539 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
139540 +{
139541 + unsigned long irqflags __maybe_unused;
139542 + int ret = -EBUSY;
139543 + PORTAL_IRQ_LOCK(p, irqflags);
139544 + if (!p->vdqcr_owned) {
139545 + FQLOCK(fq);
139546 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
139547 + goto escape;
139548 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
139549 + FQUNLOCK(fq);
139550 + p->vdqcr_owned = fq;
139551 + ret = 0;
139552 + }
139553 +escape:
139554 + PORTAL_IRQ_UNLOCK(p, irqflags);
139555 + if (!ret)
139556 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
139557 + return ret;
139558 +}
139559 +
139560 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
139561 +{
139562 + int ret;
139563 + *p = get_affine_portal();
139564 + ret = set_p_vdqcr(*p, fq, vdqcr);
139565 + put_affine_portal();
139566 + return ret;
139567 +}
139568 +
139569 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139570 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
139571 + u32 vdqcr, u32 flags)
139572 +{
139573 + int ret = 0;
139574 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139575 + ret = wait_event_interruptible(affine_queue,
139576 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
139577 + else
139578 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
139579 + return ret;
139580 +}
139581 +
139582 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
139583 + u32 vdqcr, u32 flags)
139584 +{
139585 + int ret = 0;
139586 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139587 + ret = wait_event_interruptible(affine_queue,
139588 + !(ret = set_vdqcr(p, fq, vdqcr)));
139589 + else
139590 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
139591 + return ret;
139592 +}
139593 +#endif
139594 +
139595 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
139596 + u32 flags __maybe_unused, u32 vdqcr)
139597 +{
139598 + int ret;
139599 +
139600 + if ((fq->state != qman_fq_state_parked) &&
139601 + (fq->state != qman_fq_state_retired))
139602 + return -EINVAL;
139603 + if (vdqcr & QM_VDQCR_FQID_MASK)
139604 + return -EINVAL;
139605 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
139606 + return -EBUSY;
139607 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
139608 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139609 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
139610 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
139611 + else
139612 +#endif
139613 + ret = set_p_vdqcr(p, fq, vdqcr);
139614 + if (ret)
139615 + return ret;
139616 + /* VDQCR is set */
139617 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139618 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
139619 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139620 + /* NB: don't propagate any error - the caller wouldn't
139621 + * know whether the VDQCR was issued or not. A signal
139622 + * could arrive after returning anyway, so the caller
139623 + * can check signal_pending() if that's an issue. */
139624 + wait_event_interruptible(affine_queue,
139625 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
139626 + else
139627 + wait_event(affine_queue,
139628 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
139629 + }
139630 +#endif
139631 + return 0;
139632 +}
139633 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
139634 +
139635 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
139636 + u32 vdqcr)
139637 +{
139638 + struct qman_portal *p;
139639 + int ret;
139640 +
139641 + if ((fq->state != qman_fq_state_parked) &&
139642 + (fq->state != qman_fq_state_retired))
139643 + return -EINVAL;
139644 + if (vdqcr & QM_VDQCR_FQID_MASK)
139645 + return -EINVAL;
139646 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
139647 + return -EBUSY;
139648 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
139649 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139650 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
139651 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
139652 + else
139653 +#endif
139654 + ret = set_vdqcr(&p, fq, vdqcr);
139655 + if (ret)
139656 + return ret;
139657 + /* VDQCR is set */
139658 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139659 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
139660 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139661 + /* NB: don't propagate any error - the caller wouldn't
139662 + * know whether the VDQCR was issued or not. A signal
139663 + * could arrive after returning anyway, so the caller
139664 + * can check signal_pending() if that's an issue. */
139665 + wait_event_interruptible(affine_queue,
139666 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
139667 + else
139668 + wait_event(affine_queue,
139669 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
139670 + }
139671 +#endif
139672 + return 0;
139673 +}
139674 +EXPORT_SYMBOL(qman_volatile_dequeue);
139675 +
139676 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
139677 +{
139678 + if (avail)
139679 + qm_eqcr_cce_prefetch(&p->p);
139680 + else
139681 + qm_eqcr_cce_update(&p->p);
139682 +}
139683 +
139684 +int qman_eqcr_is_empty(void)
139685 +{
139686 + unsigned long irqflags __maybe_unused;
139687 + struct qman_portal *p = get_affine_portal();
139688 + u8 avail;
139689 +
139690 + PORTAL_IRQ_LOCK(p, irqflags);
139691 + update_eqcr_ci(p, 0);
139692 + avail = qm_eqcr_get_fill(&p->p);
139693 + PORTAL_IRQ_UNLOCK(p, irqflags);
139694 + put_affine_portal();
139695 + return avail == 0;
139696 +}
139697 +EXPORT_SYMBOL(qman_eqcr_is_empty);
139698 +
139699 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
139700 +{
139701 + if (affine) {
139702 + unsigned long irqflags __maybe_unused;
139703 + struct qman_portal *p = get_affine_portal();
139704 + PORTAL_IRQ_LOCK(p, irqflags);
139705 + p->cb_dc_ern = handler;
139706 + PORTAL_IRQ_UNLOCK(p, irqflags);
139707 + put_affine_portal();
139708 + } else
139709 + cb_dc_ern = handler;
139710 +}
139711 +EXPORT_SYMBOL(qman_set_dc_ern);
139712 +
139713 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
139714 + unsigned long *irqflags __maybe_unused,
139715 + struct qman_fq *fq,
139716 + const struct qm_fd *fd,
139717 + u32 flags)
139718 +{
139719 + struct qm_eqcr_entry *eq;
139720 + u8 avail;
139721 + PORTAL_IRQ_LOCK(p, (*irqflags));
139722 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139723 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139724 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139725 + if (p->eqci_owned) {
139726 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
139727 + return NULL;
139728 + }
139729 + p->eqci_owned = fq;
139730 + }
139731 +#endif
139732 + if (p->use_eqcr_ci_stashing) {
139733 + /*
139734 + * The stashing case is easy, only update if we need to in
139735 + * order to try and liberate ring entries.
139736 + */
139737 + eq = qm_eqcr_start_stash(&p->p);
139738 + } else {
139739 + /*
139740 + * The non-stashing case is harder, need to prefetch ahead of
139741 + * time.
139742 + */
139743 + avail = qm_eqcr_get_avail(&p->p);
139744 + if (avail < 2)
139745 + update_eqcr_ci(p, avail);
139746 + eq = qm_eqcr_start_no_stash(&p->p);
139747 + }
139748 +
139749 + if (unlikely(!eq)) {
139750 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139751 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139752 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
139753 + p->eqci_owned = NULL;
139754 +#endif
139755 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
139756 + return NULL;
139757 + }
139758 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
139759 + eq->dca = QM_EQCR_DCA_ENABLE |
139760 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
139761 + QM_EQCR_DCA_PARK : 0) |
139762 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
139763 + eq->fqid = cpu_to_be32(fq->fqid);
139764 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139765 + eq->tag = cpu_to_be32(fq->key);
139766 +#else
139767 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
139768 +#endif
139769 + eq->fd = *fd;
139770 + cpu_to_hw_fd(&eq->fd);
139771 + return eq;
139772 +}
139773 +
139774 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
139775 + unsigned long *irqflags __maybe_unused,
139776 + struct qman_fq *fq,
139777 + const struct qm_fd *fd,
139778 + u32 flags)
139779 +{
139780 + struct qm_eqcr_entry *eq;
139781 + *p = get_affine_portal();
139782 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
139783 + if (!eq)
139784 + put_affine_portal();
139785 + return eq;
139786 +}
139787 +
139788 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139789 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
139790 + unsigned long *irqflags __maybe_unused,
139791 + struct qman_fq *fq,
139792 + const struct qm_fd *fd,
139793 + u32 flags)
139794 +{
139795 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
139796 + if (!eq)
139797 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
139798 + return eq;
139799 +}
139800 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
139801 + unsigned long *irqflags __maybe_unused,
139802 + struct qman_fq *fq,
139803 + const struct qm_fd *fd,
139804 + u32 flags)
139805 +{
139806 + struct qm_eqcr_entry *eq;
139807 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139808 + /* NB: return NULL if signal occurs before completion. Signal
139809 + * can occur during return. Caller must check for signal */
139810 + wait_event_interruptible(affine_queue,
139811 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
139812 + else
139813 + wait_event(affine_queue,
139814 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
139815 + return eq;
139816 +}
139817 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
139818 + unsigned long *irqflags __maybe_unused,
139819 + struct qman_fq *fq,
139820 + const struct qm_fd *fd,
139821 + u32 flags)
139822 +{
139823 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
139824 + if (!eq)
139825 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
139826 + return eq;
139827 +}
139828 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
139829 + unsigned long *irqflags __maybe_unused,
139830 + struct qman_fq *fq,
139831 + const struct qm_fd *fd,
139832 + u32 flags)
139833 +{
139834 + struct qm_eqcr_entry *eq;
139835 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139836 + /* NB: return NULL if signal occurs before completion. Signal
139837 + * can occur during return. Caller must check for signal */
139838 + wait_event_interruptible(affine_queue,
139839 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
139840 + else
139841 + wait_event(affine_queue,
139842 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
139843 + return eq;
139844 +}
139845 +#endif
139846 +
139847 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
139848 + const struct qm_fd *fd, u32 flags)
139849 +{
139850 + struct qm_eqcr_entry *eq;
139851 + unsigned long irqflags __maybe_unused;
139852 +
139853 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139854 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139855 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
139856 + else
139857 +#endif
139858 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
139859 + if (!eq)
139860 + return -EBUSY;
139861 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139862 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139863 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139864 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139865 + PORTAL_IRQ_UNLOCK(p, irqflags);
139866 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139867 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139868 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139869 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139870 + /* NB: return success even if signal occurs before
139871 + * condition is true. pvb_commit guarantees success */
139872 + wait_event_interruptible(affine_queue,
139873 + (p->eqci_owned != fq));
139874 + else
139875 + wait_event(affine_queue, (p->eqci_owned != fq));
139876 + }
139877 +#endif
139878 + return 0;
139879 +}
139880 +EXPORT_SYMBOL(qman_p_enqueue);
139881 +
139882 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
139883 +{
139884 + struct qman_portal *p;
139885 + struct qm_eqcr_entry *eq;
139886 + unsigned long irqflags __maybe_unused;
139887 +
139888 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139889 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139890 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
139891 + else
139892 +#endif
139893 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
139894 + if (!eq)
139895 + return -EBUSY;
139896 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139897 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
139898 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139899 + /* Factor the below out, it's used from qman_enqueue_orp() too */
139900 + PORTAL_IRQ_UNLOCK(p, irqflags);
139901 + put_affine_portal();
139902 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139903 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139904 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139905 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139906 + /* NB: return success even if signal occurs before
139907 + * condition is true. pvb_commit guarantees success */
139908 + wait_event_interruptible(affine_queue,
139909 + (p->eqci_owned != fq));
139910 + else
139911 + wait_event(affine_queue, (p->eqci_owned != fq));
139912 + }
139913 +#endif
139914 + return 0;
139915 +}
139916 +EXPORT_SYMBOL(qman_enqueue);
139917 +
139918 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
139919 + const struct qm_fd *fd, u32 flags,
139920 + struct qman_fq *orp, u16 orp_seqnum)
139921 +{
139922 + struct qm_eqcr_entry *eq;
139923 + unsigned long irqflags __maybe_unused;
139924 +
139925 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139926 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139927 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
139928 + else
139929 +#endif
139930 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
139931 + if (!eq)
139932 + return -EBUSY;
139933 + /* Process ORP-specifics here */
139934 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
139935 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
139936 + else {
139937 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
139938 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
139939 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
139940 + else
139941 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
139942 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
139943 + }
139944 + eq->seqnum = cpu_to_be16(orp_seqnum);
139945 + eq->orp = cpu_to_be32(orp->fqid);
139946 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139947 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
139948 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
139949 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
139950 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
139951 + PORTAL_IRQ_UNLOCK(p, irqflags);
139952 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
139953 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
139954 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
139955 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
139956 + /* NB: return success even if signal occurs before
139957 + * condition is true. pvb_commit guarantees success */
139958 + wait_event_interruptible(affine_queue,
139959 + (p->eqci_owned != fq));
139960 + else
139961 + wait_event(affine_queue, (p->eqci_owned != fq));
139962 + }
139963 +#endif
139964 + return 0;
139965 +}
139966 +EXPORT_SYMBOL(qman_p_enqueue_orp);
139967 +
139968 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
139969 + struct qman_fq *orp, u16 orp_seqnum)
139970 +{
139971 + struct qman_portal *p;
139972 + struct qm_eqcr_entry *eq;
139973 + unsigned long irqflags __maybe_unused;
139974 +
139975 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139976 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
139977 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
139978 + else
139979 +#endif
139980 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
139981 + if (!eq)
139982 + return -EBUSY;
139983 + /* Process ORP-specifics here */
139984 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
139985 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
139986 + else {
139987 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
139988 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
139989 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
139990 + else
139991 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
139992 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
139993 + }
139994 + eq->seqnum = cpu_to_be16(orp_seqnum);
139995 + eq->orp = cpu_to_be32(orp->fqid);
139996 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
139997 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
139998 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
139999 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
140000 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140001 + PORTAL_IRQ_UNLOCK(p, irqflags);
140002 + put_affine_portal();
140003 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140004 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140005 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140006 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140007 + /* NB: return success even if signal occurs before
140008 + * condition is true. pvb_commit guarantees success */
140009 + wait_event_interruptible(affine_queue,
140010 + (p->eqci_owned != fq));
140011 + else
140012 + wait_event(affine_queue, (p->eqci_owned != fq));
140013 + }
140014 +#endif
140015 + return 0;
140016 +}
140017 +EXPORT_SYMBOL(qman_enqueue_orp);
140018 +
140019 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
140020 + const struct qm_fd *fd, u32 flags,
140021 + qman_cb_precommit cb, void *cb_arg)
140022 +{
140023 + struct qm_eqcr_entry *eq;
140024 + unsigned long irqflags __maybe_unused;
140025 +
140026 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140027 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140028 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
140029 + else
140030 +#endif
140031 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
140032 + if (!eq)
140033 + return -EBUSY;
140034 + /* invoke user supplied callback function before writing commit verb */
140035 + if (cb(cb_arg)) {
140036 + PORTAL_IRQ_UNLOCK(p, irqflags);
140037 + return -EINVAL;
140038 + }
140039 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140040 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
140041 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140042 + /* Factor the below out, it's used from qman_enqueue_orp() too */
140043 + PORTAL_IRQ_UNLOCK(p, irqflags);
140044 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140045 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140046 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140047 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140048 + /* NB: return success even if signal occurs before
140049 + * condition is true. pvb_commit guarantees success */
140050 + wait_event_interruptible(affine_queue,
140051 + (p->eqci_owned != fq));
140052 + else
140053 + wait_event(affine_queue, (p->eqci_owned != fq));
140054 + }
140055 +#endif
140056 + return 0;
140057 +}
140058 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
140059 +
140060 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
140061 + u32 flags, qman_cb_precommit cb, void *cb_arg)
140062 +{
140063 + struct qman_portal *p;
140064 + struct qm_eqcr_entry *eq;
140065 + unsigned long irqflags __maybe_unused;
140066 +
140067 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140068 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140069 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
140070 + else
140071 +#endif
140072 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
140073 + if (!eq)
140074 + return -EBUSY;
140075 + /* invoke user supplied callback function before writing commit verb */
140076 + if (cb(cb_arg)) {
140077 + PORTAL_IRQ_UNLOCK(p, irqflags);
140078 + put_affine_portal();
140079 + return -EINVAL;
140080 + }
140081 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140082 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
140083 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140084 + /* Factor the below out, it's used from qman_enqueue_orp() too */
140085 + PORTAL_IRQ_UNLOCK(p, irqflags);
140086 + put_affine_portal();
140087 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140088 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140089 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140090 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140091 + /* NB: return success even if signal occurs before
140092 + * condition is true. pvb_commit guarantees success */
140093 + wait_event_interruptible(affine_queue,
140094 + (p->eqci_owned != fq));
140095 + else
140096 + wait_event(affine_queue, (p->eqci_owned != fq));
140097 + }
140098 +#endif
140099 + return 0;
140100 +}
140101 +EXPORT_SYMBOL(qman_enqueue_precommit);
140102 +
140103 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
140104 + struct qm_mcc_initcgr *opts)
140105 +{
140106 + struct qm_mc_command *mcc;
140107 + struct qm_mc_result *mcr;
140108 + struct qman_portal *p = get_affine_portal();
140109 + unsigned long irqflags __maybe_unused;
140110 + u8 res;
140111 + u8 verb = QM_MCC_VERB_MODIFYCGR;
140112 +
140113 + PORTAL_IRQ_LOCK(p, irqflags);
140114 + mcc = qm_mc_start(&p->p);
140115 + if (opts)
140116 + mcc->initcgr = *opts;
140117 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
140118 + mcc->initcgr.cgr.wr_parm_g.word =
140119 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
140120 + mcc->initcgr.cgr.wr_parm_y.word =
140121 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
140122 + mcc->initcgr.cgr.wr_parm_r.word =
140123 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
140124 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
140125 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
140126 +
140127 + mcc->initcgr.cgid = cgr->cgrid;
140128 + if (flags & QMAN_CGR_FLAG_USE_INIT)
140129 + verb = QM_MCC_VERB_INITCGR;
140130 + qm_mc_commit(&p->p, verb);
140131 + while (!(mcr = qm_mc_result(&p->p)))
140132 + cpu_relax();
140133 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
140134 + res = mcr->result;
140135 + PORTAL_IRQ_UNLOCK(p, irqflags);
140136 + put_affine_portal();
140137 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
140138 +}
140139 +EXPORT_SYMBOL(qman_modify_cgr);
140140 +
140141 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
140142 + QM_CHANNEL_SWPORTAL0))
140143 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
140144 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
140145 +
140146 +static u8 qman_cgr_cpus[__CGR_NUM];
140147 +
140148 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
140149 + struct qm_mcc_initcgr *opts)
140150 +{
140151 + unsigned long irqflags __maybe_unused;
140152 + struct qm_mcr_querycgr cgr_state;
140153 + struct qm_mcc_initcgr local_opts;
140154 + int ret;
140155 + struct qman_portal *p;
140156 +
140157 + /* We have to check that the provided CGRID is within the limits of the
140158 + * data-structures, for obvious reasons. However we'll let h/w take
140159 + * care of determining whether it's within the limits of what exists on
140160 + * the SoC. */
140161 + if (cgr->cgrid >= __CGR_NUM)
140162 + return -EINVAL;
140163 +
140164 + preempt_disable();
140165 + p = get_affine_portal();
140166 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
140167 + preempt_enable();
140168 +
140169 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
140170 + cgr->chan = p->config->public_cfg.channel;
140171 + spin_lock_irqsave(&p->cgr_lock, irqflags);
140172 +
140173 + /* if no opts specified, just add it to the list */
140174 + if (!opts)
140175 + goto add_list;
140176 +
140177 + ret = qman_query_cgr(cgr, &cgr_state);
140178 + if (ret)
140179 + goto release_lock;
140180 + if (opts)
140181 + local_opts = *opts;
140182 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
140183 + local_opts.cgr.cscn_targ_upd_ctrl =
140184 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
140185 + else
140186 + /* Overwrite TARG */
140187 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
140188 + TARG_MASK(p);
140189 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
140190 +
140191 + /* send init if flags indicate so */
140192 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
140193 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
140194 + else
140195 + ret = qman_modify_cgr(cgr, 0, &local_opts);
140196 + if (ret)
140197 + goto release_lock;
140198 +add_list:
140199 + list_add(&cgr->node, &p->cgr_cbs);
140200 +
140201 + /* Determine if newly added object requires its callback to be called */
140202 + ret = qman_query_cgr(cgr, &cgr_state);
140203 + if (ret) {
140204 + /* we can't go back, so proceed and return success, but screen
140205 + * and wail to the log file */
140206 + pr_crit("CGR HW state partially modified\n");
140207 + ret = 0;
140208 + goto release_lock;
140209 + }
140210 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
140211 + cgr->cgrid))
140212 + cgr->cb(p, cgr, 1);
140213 +release_lock:
140214 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
140215 + put_affine_portal();
140216 + return ret;
140217 +}
140218 +EXPORT_SYMBOL(qman_create_cgr);
140219 +
140220 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
140221 + struct qm_mcc_initcgr *opts)
140222 +{
140223 + unsigned long irqflags __maybe_unused;
140224 + struct qm_mcc_initcgr local_opts;
140225 + struct qm_mcr_querycgr cgr_state;
140226 + int ret;
140227 +
140228 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
140229 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
140230 + return -EINVAL;
140231 + }
140232 + /* We have to check that the provided CGRID is within the limits of the
140233 + * data-structures, for obvious reasons. However we'll let h/w take
140234 + * care of determining whether it's within the limits of what exists on
140235 + * the SoC.
140236 + */
140237 + if (cgr->cgrid >= __CGR_NUM)
140238 + return -EINVAL;
140239 +
140240 + ret = qman_query_cgr(cgr, &cgr_state);
140241 + if (ret)
140242 + return ret;
140243 +
140244 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
140245 + if (opts)
140246 + local_opts = *opts;
140247 +
140248 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
140249 + local_opts.cgr.cscn_targ_upd_ctrl =
140250 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
140251 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
140252 + else
140253 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
140254 + TARG_DCP_MASK(dcp_portal);
140255 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
140256 +
140257 + /* send init if flags indicate so */
140258 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
140259 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
140260 + &local_opts);
140261 + else
140262 + ret = qman_modify_cgr(cgr, 0, &local_opts);
140263 +
140264 + return ret;
140265 +}
140266 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
140267 +
140268 +int qman_delete_cgr(struct qman_cgr *cgr)
140269 +{
140270 + unsigned long irqflags __maybe_unused;
140271 + struct qm_mcr_querycgr cgr_state;
140272 + struct qm_mcc_initcgr local_opts;
140273 + int ret = 0;
140274 + struct qman_cgr *i;
140275 + struct qman_portal *p = get_affine_portal();
140276 +
140277 + if (cgr->chan != p->config->public_cfg.channel) {
140278 + pr_crit("Attempting to delete cgr from different portal "
140279 + "than it was create: create 0x%x, delete 0x%x\n",
140280 + cgr->chan, p->config->public_cfg.channel);
140281 + ret = -EINVAL;
140282 + goto put_portal;
140283 + }
140284 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
140285 + spin_lock_irqsave(&p->cgr_lock, irqflags);
140286 + list_del(&cgr->node);
140287 + /*
140288 + * If there are no other CGR objects for this CGRID in the list, update
140289 + * CSCN_TARG accordingly
140290 + */
140291 + list_for_each_entry(i, &p->cgr_cbs, node)
140292 + if ((i->cgrid == cgr->cgrid) && i->cb)
140293 + goto release_lock;
140294 + ret = qman_query_cgr(cgr, &cgr_state);
140295 + if (ret) {
140296 + /* add back to the list */
140297 + list_add(&cgr->node, &p->cgr_cbs);
140298 + goto release_lock;
140299 + }
140300 + /* Overwrite TARG */
140301 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
140302 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
140303 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
140304 + else
140305 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
140306 + ~(TARG_MASK(p));
140307 + ret = qman_modify_cgr(cgr, 0, &local_opts);
140308 + if (ret)
140309 + /* add back to the list */
140310 + list_add(&cgr->node, &p->cgr_cbs);
140311 +release_lock:
140312 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
140313 +put_portal:
140314 + put_affine_portal();
140315 + return ret;
140316 +}
140317 +EXPORT_SYMBOL(qman_delete_cgr);
140318 +
140319 +struct cgr_comp {
140320 + struct qman_cgr *cgr;
140321 + struct completion completion;
140322 +};
140323 +
140324 +static void qman_delete_cgr_smp_call(void *p)
140325 +{
140326 + qman_delete_cgr((struct qman_cgr *)p);
140327 +}
140328 +
140329 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
140330 +{
140331 + preempt_disable();
140332 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
140333 + smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
140334 + qman_delete_cgr_smp_call, cgr, true);
140335 + preempt_enable();
140336 + return;
140337 + }
140338 + qman_delete_cgr(cgr);
140339 + preempt_enable();
140340 +}
140341 +EXPORT_SYMBOL(qman_delete_cgr_safe);
140342 +
140343 +int qm_get_clock(u64 *clock_hz)
140344 +{
140345 + if (!qman_clk) {
140346 + pr_warn("Qman clock speed is unknown\n");
140347 + return -EINVAL;
140348 + }
140349 + *clock_hz = (u64)qman_clk;
140350 + return 0;
140351 +}
140352 +EXPORT_SYMBOL(qm_get_clock);
140353 +
140354 +int qm_set_clock(u64 clock_hz)
140355 +{
140356 + if (qman_clk)
140357 + return -1;
140358 + qman_clk = (u32)clock_hz;
140359 + return 0;
140360 +}
140361 +EXPORT_SYMBOL(qm_set_clock);
140362 +
140363 +/* CEETM management command */
140364 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
140365 +{
140366 + struct qm_mc_command *mcc;
140367 + struct qm_mc_result *mcr;
140368 + struct qman_portal *p;
140369 + unsigned long irqflags __maybe_unused;
140370 + u8 res;
140371 +
140372 + p = get_affine_portal();
140373 + PORTAL_IRQ_LOCK(p, irqflags);
140374 +
140375 + mcc = qm_mc_start(&p->p);
140376 + mcc->lfqmt_config = *opts;
140377 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
140378 + while (!(mcr = qm_mc_result(&p->p)))
140379 + cpu_relax();
140380 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140381 + QM_CEETM_VERB_LFQMT_CONFIG);
140382 + PORTAL_IRQ_UNLOCK(p, irqflags);
140383 + put_affine_portal();
140384 +
140385 + res = mcr->result;
140386 + if (res != QM_MCR_RESULT_OK) {
140387 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
140388 + return -EIO;
140389 + }
140390 + return 0;
140391 +}
140392 +
140393 +int qman_ceetm_query_lfqmt(int lfqid,
140394 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
140395 +{
140396 + struct qm_mc_command *mcc;
140397 + struct qm_mc_result *mcr;
140398 + struct qman_portal *p;
140399 + unsigned long irqflags __maybe_unused;
140400 + u8 res;
140401 +
140402 + p = get_affine_portal();
140403 + PORTAL_IRQ_LOCK(p, irqflags);
140404 +
140405 + mcc = qm_mc_start(&p->p);
140406 + mcc->lfqmt_query.lfqid = lfqid;
140407 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
140408 + while (!(mcr = qm_mc_result(&p->p)))
140409 + cpu_relax();
140410 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
140411 + res = mcr->result;
140412 + if (res == QM_MCR_RESULT_OK)
140413 + *lfqmt_query = mcr->lfqmt_query;
140414 +
140415 + PORTAL_IRQ_UNLOCK(p, irqflags);
140416 + put_affine_portal();
140417 + if (res != QM_MCR_RESULT_OK) {
140418 + pr_err("CEETM: QUERY LFQMT failed\n");
140419 + return -EIO;
140420 + }
140421 + return 0;
140422 +}
140423 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
140424 +
140425 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
140426 +{
140427 + struct qm_mc_command *mcc;
140428 + struct qm_mc_result *mcr;
140429 + struct qman_portal *p;
140430 + unsigned long irqflags __maybe_unused;
140431 + u8 res;
140432 +
140433 + p = get_affine_portal();
140434 + PORTAL_IRQ_LOCK(p, irqflags);
140435 +
140436 + mcc = qm_mc_start(&p->p);
140437 + mcc->cq_config = *opts;
140438 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
140439 + while (!(mcr = qm_mc_result(&p->p)))
140440 + cpu_relax();
140441 + res = mcr->result;
140442 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
140443 +
140444 + PORTAL_IRQ_UNLOCK(p, irqflags);
140445 + put_affine_portal();
140446 +
140447 + if (res != QM_MCR_RESULT_OK) {
140448 + pr_err("CEETM: CONFIGURE CQ failed\n");
140449 + return -EIO;
140450 + }
140451 + return 0;
140452 +}
140453 +
140454 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
140455 + struct qm_mcr_ceetm_cq_query *cq_query)
140456 +{
140457 + struct qm_mc_command *mcc;
140458 + struct qm_mc_result *mcr;
140459 + struct qman_portal *p;
140460 + unsigned long irqflags __maybe_unused;
140461 + u8 res;
140462 +
140463 + p = get_affine_portal();
140464 + PORTAL_IRQ_LOCK(p, irqflags);
140465 +
140466 + mcc = qm_mc_start(&p->p);
140467 + mcc->cq_query.cqid = cpu_to_be16(cqid);
140468 + mcc->cq_query.dcpid = dcpid;
140469 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
140470 + while (!(mcr = qm_mc_result(&p->p)))
140471 + cpu_relax();
140472 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
140473 + res = mcr->result;
140474 + if (res == QM_MCR_RESULT_OK) {
140475 + *cq_query = mcr->cq_query;
140476 + hw_cq_query_to_cpu(cq_query);
140477 + }
140478 +
140479 + PORTAL_IRQ_UNLOCK(p, irqflags);
140480 + put_affine_portal();
140481 +
140482 + if (res != QM_MCR_RESULT_OK) {
140483 + pr_err("CEETM: QUERY CQ failed\n");
140484 + return -EIO;
140485 + }
140486 +
140487 + return 0;
140488 +}
140489 +EXPORT_SYMBOL(qman_ceetm_query_cq);
140490 +
140491 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
140492 +{
140493 + struct qm_mc_command *mcc;
140494 + struct qm_mc_result *mcr;
140495 + struct qman_portal *p;
140496 + unsigned long irqflags __maybe_unused;
140497 + u8 res;
140498 +
140499 + p = get_affine_portal();
140500 + PORTAL_IRQ_LOCK(p, irqflags);
140501 +
140502 + mcc = qm_mc_start(&p->p);
140503 + mcc->dct_config = *opts;
140504 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
140505 + while (!(mcr = qm_mc_result(&p->p)))
140506 + cpu_relax();
140507 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
140508 + res = mcr->result;
140509 +
140510 + PORTAL_IRQ_UNLOCK(p, irqflags);
140511 + put_affine_portal();
140512 +
140513 + if (res != QM_MCR_RESULT_OK) {
140514 + pr_err("CEETM: CONFIGURE DCT failed\n");
140515 + return -EIO;
140516 + }
140517 + return 0;
140518 +}
140519 +
140520 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
140521 + struct qm_mcr_ceetm_dct_query *dct_query)
140522 +{
140523 + struct qm_mc_command *mcc;
140524 + struct qm_mc_result *mcr;
140525 + struct qman_portal *p = get_affine_portal();
140526 + unsigned long irqflags __maybe_unused;
140527 + u8 res;
140528 +
140529 + PORTAL_IRQ_LOCK(p, irqflags);
140530 +
140531 + mcc = qm_mc_start(&p->p);
140532 + mcc->dct_query = *opts;
140533 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
140534 + while (!(mcr = qm_mc_result(&p->p)))
140535 + cpu_relax();
140536 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
140537 + res = mcr->result;
140538 +
140539 + PORTAL_IRQ_UNLOCK(p, irqflags);
140540 + put_affine_portal();
140541 +
140542 + if (res != QM_MCR_RESULT_OK) {
140543 + pr_err("CEETM: QUERY DCT failed\n");
140544 + return -EIO;
140545 + }
140546 +
140547 + *dct_query = mcr->dct_query;
140548 + return 0;
140549 +}
140550 +
140551 +static int qman_ceetm_configure_class_scheduler(
140552 + struct qm_mcc_ceetm_class_scheduler_config *opts)
140553 +{
140554 + struct qm_mc_command *mcc;
140555 + struct qm_mc_result *mcr;
140556 + struct qman_portal *p;
140557 + unsigned long irqflags __maybe_unused;
140558 + u8 res;
140559 +
140560 + p = get_affine_portal();
140561 + PORTAL_IRQ_LOCK(p, irqflags);
140562 +
140563 + mcc = qm_mc_start(&p->p);
140564 + mcc->csch_config = *opts;
140565 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
140566 + while (!(mcr = qm_mc_result(&p->p)))
140567 + cpu_relax();
140568 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140569 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
140570 + res = mcr->result;
140571 +
140572 + PORTAL_IRQ_UNLOCK(p, irqflags);
140573 + put_affine_portal();
140574 +
140575 + if (res != QM_MCR_RESULT_OK) {
140576 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
140577 + return -EIO;
140578 + }
140579 + return 0;
140580 +}
140581 +
140582 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
140583 + struct qm_mcr_ceetm_class_scheduler_query *query)
140584 +{
140585 + struct qm_mc_command *mcc;
140586 + struct qm_mc_result *mcr;
140587 + struct qman_portal *p;
140588 + unsigned long irqflags __maybe_unused;
140589 + u8 res;
140590 +
140591 + p = get_affine_portal();
140592 + PORTAL_IRQ_LOCK(p, irqflags);
140593 +
140594 + mcc = qm_mc_start(&p->p);
140595 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
140596 + mcc->csch_query.dcpid = channel->dcp_idx;
140597 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
140598 + while (!(mcr = qm_mc_result(&p->p)))
140599 + cpu_relax();
140600 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140601 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
140602 + res = mcr->result;
140603 +
140604 + PORTAL_IRQ_UNLOCK(p, irqflags);
140605 + put_affine_portal();
140606 +
140607 + if (res != QM_MCR_RESULT_OK) {
140608 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
140609 + return -EIO;
140610 + }
140611 + *query = mcr->csch_query;
140612 + return 0;
140613 +}
140614 +
140615 +static int qman_ceetm_configure_mapping_shaper_tcfc(
140616 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
140617 +{
140618 + struct qm_mc_command *mcc;
140619 + struct qm_mc_result *mcr;
140620 + struct qman_portal *p;
140621 + unsigned long irqflags __maybe_unused;
140622 + u8 res;
140623 +
140624 + p = get_affine_portal();
140625 + PORTAL_IRQ_LOCK(p, irqflags);
140626 +
140627 + mcc = qm_mc_start(&p->p);
140628 + mcc->mst_config = *opts;
140629 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
140630 + while (!(mcr = qm_mc_result(&p->p)))
140631 + cpu_relax();
140632 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140633 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
140634 + res = mcr->result;
140635 +
140636 + PORTAL_IRQ_UNLOCK(p, irqflags);
140637 + put_affine_portal();
140638 +
140639 + if (res != QM_MCR_RESULT_OK) {
140640 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
140641 + return -EIO;
140642 + }
140643 + return 0;
140644 +}
140645 +
140646 +static int qman_ceetm_query_mapping_shaper_tcfc(
140647 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
140648 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
140649 +{
140650 + struct qm_mc_command *mcc;
140651 + struct qm_mc_result *mcr;
140652 + struct qman_portal *p;
140653 + unsigned long irqflags __maybe_unused;
140654 + u8 res;
140655 +
140656 + p = get_affine_portal();
140657 + PORTAL_IRQ_LOCK(p, irqflags);
140658 +
140659 + mcc = qm_mc_start(&p->p);
140660 + mcc->mst_query = *opts;
140661 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
140662 + while (!(mcr = qm_mc_result(&p->p)))
140663 + cpu_relax();
140664 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140665 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
140666 + res = mcr->result;
140667 +
140668 + PORTAL_IRQ_UNLOCK(p, irqflags);
140669 + put_affine_portal();
140670 +
140671 + if (res != QM_MCR_RESULT_OK) {
140672 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
140673 + return -EIO;
140674 + }
140675 +
140676 + *response = mcr->mst_query;
140677 + return 0;
140678 +}
140679 +
140680 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
140681 +{
140682 + struct qm_mc_command *mcc;
140683 + struct qm_mc_result *mcr;
140684 + struct qman_portal *p;
140685 + unsigned long irqflags __maybe_unused;
140686 + u8 res;
140687 +
140688 + p = get_affine_portal();
140689 + PORTAL_IRQ_LOCK(p, irqflags);
140690 +
140691 + mcc = qm_mc_start(&p->p);
140692 + mcc->ccgr_config = *opts;
140693 +
140694 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
140695 + while (!(mcr = qm_mc_result(&p->p)))
140696 + cpu_relax();
140697 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
140698 +
140699 + PORTAL_IRQ_UNLOCK(p, irqflags);
140700 + put_affine_portal();
140701 +
140702 + res = mcr->result;
140703 + if (res != QM_MCR_RESULT_OK) {
140704 + pr_err("CEETM: CONFIGURE CCGR failed\n");
140705 + return -EIO;
140706 + }
140707 + return 0;
140708 +}
140709 +
140710 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
140711 + struct qm_mcr_ceetm_ccgr_query *response)
140712 +{
140713 + struct qm_mc_command *mcc;
140714 + struct qm_mc_result *mcr;
140715 + struct qman_portal *p;
140716 + unsigned long irqflags __maybe_unused;
140717 + u8 res;
140718 +
140719 + p = get_affine_portal();
140720 + PORTAL_IRQ_LOCK(p, irqflags);
140721 +
140722 + mcc = qm_mc_start(&p->p);
140723 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
140724 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
140725 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
140726 +
140727 + while (!(mcr = qm_mc_result(&p->p)))
140728 + cpu_relax();
140729 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
140730 + res = mcr->result;
140731 + if (res == QM_MCR_RESULT_OK) {
140732 + *response = mcr->ccgr_query;
140733 + hw_ccgr_query_to_cpu(response);
140734 + }
140735 +
140736 + PORTAL_IRQ_UNLOCK(p, irqflags);
140737 + put_affine_portal();
140738 + if (res != QM_MCR_RESULT_OK) {
140739 + pr_err("CEETM: QUERY CCGR failed\n");
140740 + return -EIO;
140741 + }
140742 + return 0;
140743 +}
140744 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
140745 +
140746 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
140747 + u8 command_type, u16 xsfdr,
140748 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
140749 +{
140750 + struct qm_mc_command *mcc;
140751 + struct qm_mc_result *mcr;
140752 + struct qman_portal *p;
140753 + unsigned long irqflags __maybe_unused;
140754 + u8 res;
140755 +
140756 + p = get_affine_portal();
140757 + PORTAL_IRQ_LOCK(p, irqflags);
140758 +
140759 + mcc = qm_mc_start(&p->p);
140760 + switch (command_type) {
140761 + case 0:
140762 + case 1:
140763 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
140764 + break;
140765 + case 2:
140766 + mcc->cq_ppxr.xsfdr = xsfdr;
140767 + break;
140768 + default:
140769 + break;
140770 + }
140771 + mcc->cq_ppxr.ct = command_type;
140772 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
140773 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
140774 + while (!(mcr = qm_mc_result(&p->p)))
140775 + cpu_relax();
140776 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140777 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
140778 +
140779 + PORTAL_IRQ_UNLOCK(p, irqflags);
140780 + put_affine_portal();
140781 +
140782 + res = mcr->result;
140783 + if (res != QM_MCR_RESULT_OK) {
140784 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
140785 + return -EIO;
140786 + }
140787 + *cq_ppxr = mcr->cq_ppxr;
140788 + return 0;
140789 +}
140790 +
140791 +static int qman_ceetm_query_statistics(u16 cid,
140792 + enum qm_dc_portal dcp_idx,
140793 + u16 command_type,
140794 + struct qm_mcr_ceetm_statistics_query *query_result)
140795 +{
140796 + struct qm_mc_command *mcc;
140797 + struct qm_mc_result *mcr;
140798 + struct qman_portal *p;
140799 + unsigned long irqflags __maybe_unused;
140800 + u8 res;
140801 +
140802 + p = get_affine_portal();
140803 + PORTAL_IRQ_LOCK(p, irqflags);
140804 +
140805 + mcc = qm_mc_start(&p->p);
140806 + mcc->stats_query_write.cid = cid;
140807 + mcc->stats_query_write.dcpid = dcp_idx;
140808 + mcc->stats_query_write.ct = command_type;
140809 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
140810 +
140811 + while (!(mcr = qm_mc_result(&p->p)))
140812 + cpu_relax();
140813 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140814 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
140815 +
140816 + PORTAL_IRQ_UNLOCK(p, irqflags);
140817 + put_affine_portal();
140818 +
140819 + res = mcr->result;
140820 + if (res != QM_MCR_RESULT_OK) {
140821 + pr_err("CEETM: STATISTICS QUERY failed\n");
140822 + return -EIO;
140823 + }
140824 + *query_result = mcr->stats_query;
140825 + return 0;
140826 +}
140827 +
140828 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
140829 + u16 command_type, u64 frame_count,
140830 + u64 byte_count)
140831 +{
140832 + struct qm_mc_command *mcc;
140833 + struct qm_mc_result *mcr;
140834 + struct qman_portal *p;
140835 + unsigned long irqflags __maybe_unused;
140836 + u8 res;
140837 +
140838 + p = get_affine_portal();
140839 + PORTAL_IRQ_LOCK(p, irqflags);
140840 +
140841 + mcc = qm_mc_start(&p->p);
140842 + mcc->stats_query_write.cid = cid;
140843 + mcc->stats_query_write.dcpid = dcp_idx;
140844 + mcc->stats_query_write.ct = command_type;
140845 + mcc->stats_query_write.frm_cnt = frame_count;
140846 + mcc->stats_query_write.byte_cnt = byte_count;
140847 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
140848 +
140849 + while (!(mcr = qm_mc_result(&p->p)))
140850 + cpu_relax();
140851 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140852 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
140853 +
140854 + PORTAL_IRQ_UNLOCK(p, irqflags);
140855 + put_affine_portal();
140856 +
140857 + res = mcr->result;
140858 + if (res != QM_MCR_RESULT_OK) {
140859 + pr_err("CEETM: STATISTICS WRITE failed\n");
140860 + return -EIO;
140861 + }
140862 + return 0;
140863 +}
140864 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
140865 +
140866 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
140867 + int rounding)
140868 +{
140869 + u16 pres;
140870 + u64 temp;
140871 + u64 qman_freq;
140872 + int ret;
140873 +
140874 + /* Read PRES from CEET_CFG_PRES register */
140875 + ret = qman_ceetm_get_prescaler(&pres);
140876 + if (ret)
140877 + return -EINVAL;
140878 +
140879 + ret = qm_get_clock(&qman_freq);
140880 + if (ret)
140881 + return -EINVAL;
140882 +
140883 + /* token-rate = bytes-per-second * update-reference-period
140884 + *
140885 + * Where token-rate is N/8192 for a integer N, and
140886 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
140887 + * is the prescalar value and QHz is the QMan clock frequency.
140888 + * So:
140889 + *
140890 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
140891 + *
140892 + * Converting to bits-per-second gives;
140893 + *
140894 + * token-rate = (bps*2^19) / (PRES*QHZ)
140895 + * N = (bps*2^32) / (PRES*QHz)
140896 + *
140897 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
140898 + * (yet minimise rounding error if 'bps' is small), we reorganise
140899 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
140900 + * N = (((bps*2^16)/PRES)*2^16)/QHz
140901 + */
140902 + temp = ROUNDING((bps << 16), pres, rounding);
140903 + temp = ROUNDING((temp << 16), qman_freq, rounding);
140904 + token_rate->whole = temp >> 13;
140905 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
140906 + return 0;
140907 +}
140908 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
140909 +
140910 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
140911 + int rounding)
140912 +{
140913 + u16 pres;
140914 + u64 temp;
140915 + u64 qman_freq;
140916 + int ret;
140917 +
140918 + /* Read PRES from CEET_CFG_PRES register */
140919 + ret = qman_ceetm_get_prescaler(&pres);
140920 + if (ret)
140921 + return -EINVAL;
140922 +
140923 + ret = qm_get_clock(&qman_freq);
140924 + if (ret)
140925 + return -EINVAL;
140926 +
140927 + /* bytes-per-second = token-rate / update-reference-period
140928 + *
140929 + * where "token-rate" is N/8192 for an integer N, and
140930 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
140931 + * the prescalar value and QHz is the QMan clock frequency. So;
140932 + *
140933 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
140934 + * = N*PRES*QHz / (4194304*8192)
140935 + * = N*PRES*QHz / (2^35)
140936 + *
140937 + * Converting to bits-per-second gives;
140938 + *
140939 + * bps = N*PRES*QHZ / (2^32)
140940 + *
140941 + * Note, the numerator has a maximum width of 72 bits! So to
140942 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
140943 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
140944 + * multiplying by N (goes to maximum of 63 bits).
140945 + *
140946 + * temp = PRES*QHZ / (2^16)
140947 + * kbps = temp*N / (2^16)
140948 + */
140949 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
140950 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
140951 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
140952 + return 0;
140953 +}
140954 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
140955 +
140956 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
140957 + unsigned int sp_idx)
140958 +{
140959 + struct qm_ceetm_sp *p;
140960 +
140961 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
140962 + (dcp_idx == qm_dc_portal_fman1));
140963 +
140964 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
140965 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
140966 + qman_ceetms[dcp_idx].sp_range[1]))) {
140967 + pr_err("Sub-portal index doesn't exist\n");
140968 + return -EINVAL;
140969 + }
140970 +
140971 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
140972 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
140973 + p->is_claimed = 1;
140974 + *sp = p;
140975 + return 0;
140976 + }
140977 + }
140978 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
140979 + return -ENODEV;
140980 +}
140981 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
140982 +
140983 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
140984 +{
140985 + struct qm_ceetm_sp *p;
140986 +
140987 + if (sp->lni && sp->lni->is_claimed == 1) {
140988 + pr_err("The dependency of sub-portal has not been released!\n");
140989 + return -EBUSY;
140990 + }
140991 +
140992 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
140993 + if (p->idx == sp->idx) {
140994 + p->is_claimed = 0;
140995 + p->lni = NULL;
140996 + }
140997 + }
140998 + /* Disable CEETM mode of this sub-portal */
140999 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
141000 +
141001 + return 0;
141002 +}
141003 +EXPORT_SYMBOL(qman_ceetm_sp_release);
141004 +
141005 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
141006 + unsigned int lni_idx)
141007 +{
141008 + struct qm_ceetm_lni *p;
141009 +
141010 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
141011 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
141012 + qman_ceetms[dcp_idx].lni_range[1]))) {
141013 + pr_err("The lni index is out of range\n");
141014 + return -EINVAL;
141015 + }
141016 +
141017 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
141018 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
141019 + *lni = p;
141020 + p->is_claimed = 1;
141021 + return 0;
141022 + }
141023 + }
141024 +
141025 + pr_err("The LNI#%d is not available!\n", lni_idx);
141026 + return -EINVAL;
141027 +}
141028 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
141029 +
141030 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
141031 +{
141032 + struct qm_ceetm_lni *p;
141033 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141034 +
141035 + if (!list_empty(&lni->channels)) {
141036 + pr_err("The LNI dependencies are not released!\n");
141037 + return -EBUSY;
141038 + }
141039 +
141040 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
141041 + if (p->idx == lni->idx) {
141042 + p->shaper_enable = 0;
141043 + p->shaper_couple = 0;
141044 + p->cr_token_rate.whole = 0;
141045 + p->cr_token_rate.fraction = 0;
141046 + p->er_token_rate.whole = 0;
141047 + p->er_token_rate.fraction = 0;
141048 + p->cr_token_bucket_limit = 0;
141049 + p->er_token_bucket_limit = 0;
141050 + p->is_claimed = 0;
141051 + }
141052 + }
141053 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141054 + config_opts.dcpid = lni->dcp_idx;
141055 + memset(&config_opts.shaper_config, 0,
141056 + sizeof(config_opts.shaper_config));
141057 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141058 +}
141059 +EXPORT_SYMBOL(qman_ceetm_lni_release);
141060 +
141061 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
141062 +{
141063 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141064 +
141065 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
141066 + config_opts.dcpid = sp->dcp_idx;
141067 + config_opts.sp_mapping.map_lni_id = lni->idx;
141068 + sp->lni = lni;
141069 +
141070 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
141071 + return -EINVAL;
141072 +
141073 + /* Enable CEETM mode for this sub-portal */
141074 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
141075 +}
141076 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
141077 +
141078 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
141079 +{
141080 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141081 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141082 +
141083 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
141084 + query_opts.dcpid = sp->dcp_idx;
141085 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141086 + pr_err("Can't get SP <-> LNI mapping\n");
141087 + return -EINVAL;
141088 + }
141089 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
141090 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
141091 + return 0;
141092 +}
141093 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
141094 +
141095 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
141096 + int oal)
141097 +{
141098 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141099 +
141100 + if (lni->shaper_enable) {
141101 + pr_err("The shaper has already been enabled\n");
141102 + return -EINVAL;
141103 + }
141104 + lni->shaper_enable = 1;
141105 + lni->shaper_couple = coupled;
141106 + lni->oal = oal;
141107 +
141108 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141109 + config_opts.dcpid = lni->dcp_idx;
141110 + config_opts.shaper_config.cpl = coupled;
141111 + config_opts.shaper_config.oal = oal;
141112 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
141113 + << 13) | lni->cr_token_rate.fraction);
141114 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
141115 + << 13) | lni->er_token_rate.fraction);
141116 + config_opts.shaper_config.crtbl =
141117 + cpu_to_be16(lni->cr_token_bucket_limit);
141118 + config_opts.shaper_config.ertbl =
141119 + cpu_to_be16(lni->er_token_bucket_limit);
141120 + config_opts.shaper_config.mps = 60;
141121 +
141122 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141123 +}
141124 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
141125 +
141126 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
141127 +{
141128 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141129 +
141130 + if (!lni->shaper_enable) {
141131 + pr_err("The shaper has been disabled\n");
141132 + return -EINVAL;
141133 + }
141134 +
141135 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141136 + config_opts.dcpid = lni->dcp_idx;
141137 + config_opts.shaper_config.cpl = lni->shaper_couple;
141138 + config_opts.shaper_config.oal = lni->oal;
141139 + config_opts.shaper_config.crtbl =
141140 + cpu_to_be16(lni->cr_token_bucket_limit);
141141 + config_opts.shaper_config.ertbl =
141142 + cpu_to_be16(lni->er_token_bucket_limit);
141143 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
141144 + * disable the shaping.
141145 + */
141146 + config_opts.shaper_config.crtcr = 0xFFFFFF;
141147 + config_opts.shaper_config.ertcr = 0xFFFFFF;
141148 + config_opts.shaper_config.mps = 60;
141149 + lni->shaper_enable = 0;
141150 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141151 +}
141152 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
141153 +
141154 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
141155 +{
141156 + return lni->shaper_enable;
141157 +}
141158 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
141159 +
141160 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
141161 + const struct qm_ceetm_rate *token_rate,
141162 + u16 token_limit)
141163 +{
141164 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141165 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141166 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141167 + int ret;
141168 +
141169 + lni->cr_token_rate.whole = token_rate->whole;
141170 + lni->cr_token_rate.fraction = token_rate->fraction;
141171 + lni->cr_token_bucket_limit = token_limit;
141172 + if (!lni->shaper_enable)
141173 + return 0;
141174 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141175 + query_opts.dcpid = lni->dcp_idx;
141176 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
141177 + &query_result);
141178 + if (ret) {
141179 + pr_err("Fail to get current LNI shaper setting\n");
141180 + return -EINVAL;
141181 + }
141182 +
141183 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141184 + config_opts.dcpid = lni->dcp_idx;
141185 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
141186 + | (token_rate->fraction));
141187 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
141188 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
141189 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
141190 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
141191 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
141192 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
141193 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141194 +}
141195 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
141196 +
141197 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
141198 + u64 bps,
141199 + u16 token_limit)
141200 +{
141201 + struct qm_ceetm_rate token_rate;
141202 + int ret;
141203 +
141204 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
141205 + if (ret) {
141206 + pr_err("Can not convert bps to token rate\n");
141207 + return -EINVAL;
141208 + }
141209 +
141210 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
141211 +}
141212 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
141213 +
141214 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
141215 + struct qm_ceetm_rate *token_rate,
141216 + u16 *token_limit)
141217 +{
141218 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141219 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141220 + int ret;
141221 +
141222 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141223 + query_opts.dcpid = lni->dcp_idx;
141224 +
141225 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141226 + if (ret) {
141227 + pr_err("The LNI CR rate or limit is not set\n");
141228 + return -EINVAL;
141229 + }
141230 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
141231 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
141232 + 0x1FFF;
141233 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
141234 + return 0;
141235 +}
141236 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
141237 +
141238 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
141239 + u64 *bps, u16 *token_limit)
141240 +{
141241 + struct qm_ceetm_rate token_rate;
141242 + int ret;
141243 +
141244 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
141245 + if (ret) {
141246 + pr_err("The LNI CR rate or limit is not available\n");
141247 + return -EINVAL;
141248 + }
141249 +
141250 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
141251 +}
141252 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
141253 +
141254 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
141255 + const struct qm_ceetm_rate *token_rate,
141256 + u16 token_limit)
141257 +{
141258 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141259 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141260 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141261 + int ret;
141262 +
141263 + lni->er_token_rate.whole = token_rate->whole;
141264 + lni->er_token_rate.fraction = token_rate->fraction;
141265 + lni->er_token_bucket_limit = token_limit;
141266 + if (!lni->shaper_enable)
141267 + return 0;
141268 +
141269 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141270 + query_opts.dcpid = lni->dcp_idx;
141271 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
141272 + &query_result);
141273 + if (ret) {
141274 + pr_err("Fail to get current LNI shaper setting\n");
141275 + return -EINVAL;
141276 + }
141277 +
141278 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141279 + config_opts.dcpid = lni->dcp_idx;
141280 + config_opts.shaper_config.ertcr = cpu_to_be24(
141281 + (token_rate->whole << 13) | (token_rate->fraction));
141282 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
141283 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
141284 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
141285 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
141286 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
141287 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
141288 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141289 +}
141290 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
141291 +
141292 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
141293 + u64 bps,
141294 + u16 token_limit)
141295 +{
141296 + struct qm_ceetm_rate token_rate;
141297 + int ret;
141298 +
141299 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
141300 + if (ret) {
141301 + pr_err("Can not convert bps to token rate\n");
141302 + return -EINVAL;
141303 + }
141304 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
141305 +}
141306 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
141307 +
141308 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
141309 + struct qm_ceetm_rate *token_rate,
141310 + u16 *token_limit)
141311 +{
141312 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141313 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141314 + int ret;
141315 +
141316 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141317 + query_opts.dcpid = lni->dcp_idx;
141318 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141319 + if (ret) {
141320 + pr_err("The LNI ER rate or limit is not set\n");
141321 + return -EINVAL;
141322 + }
141323 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
141324 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
141325 + 0x1FFF;
141326 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
141327 + return 0;
141328 +}
141329 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
141330 +
141331 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
141332 + u64 *bps, u16 *token_limit)
141333 +{
141334 + struct qm_ceetm_rate token_rate;
141335 + int ret;
141336 +
141337 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
141338 + if (ret) {
141339 + pr_err("The LNI ER rate or limit is not available\n");
141340 + return -EINVAL;
141341 + }
141342 +
141343 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
141344 +}
141345 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
141346 +
141347 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
141348 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
141349 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
141350 + unsigned int cq_level,
141351 + int traffic_class)
141352 +{
141353 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141354 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141355 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141356 + u64 lnitcfcc;
141357 +
141358 + if ((cq_level > 15) | (traffic_class > 7)) {
141359 + pr_err("The CQ or traffic class id is out of range\n");
141360 + return -EINVAL;
141361 + }
141362 +
141363 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
141364 + query_opts.dcpid = lni->dcp_idx;
141365 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141366 + pr_err("Fail to query tcfcc\n");
141367 + return -EINVAL;
141368 + }
141369 +
141370 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
141371 + if (traffic_class == -1) {
141372 + /* disable tcfc for this CQ */
141373 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
141374 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
141375 + } else {
141376 + lnitcfcc &= ~((u64)0xF <<
141377 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
141378 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
141379 + traffic_class)) <<
141380 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
141381 + }
141382 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
141383 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
141384 + config_opts.dcpid = lni->dcp_idx;
141385 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141386 +}
141387 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
141388 +
141389 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
141390 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
141391 + int *traffic_class)
141392 +{
141393 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141394 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141395 + int ret;
141396 + u8 lnitcfcc;
141397 +
141398 + if (cq_level > 15) {
141399 + pr_err("the CQ level is out of range\n");
141400 + return -EINVAL;
141401 + }
141402 +
141403 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
141404 + query_opts.dcpid = lni->dcp_idx;
141405 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141406 + if (ret)
141407 + return ret;
141408 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
141409 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
141410 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
141411 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
141412 + else
141413 + *traffic_class = -1;
141414 + return 0;
141415 +}
141416 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
141417 +
141418 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
141419 + struct qm_ceetm_lni *lni)
141420 +{
141421 + struct qm_ceetm_channel *p;
141422 + u32 channel_idx;
141423 + int ret = 0;
141424 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141425 +
141426 + if (lni->dcp_idx == qm_dc_portal_fman0) {
141427 + ret = qman_alloc_ceetm0_channel(&channel_idx);
141428 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
141429 + ret = qman_alloc_ceetm1_channel(&channel_idx);
141430 + } else {
141431 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141432 + lni->dcp_idx);
141433 + return -EINVAL;
141434 + }
141435 +
141436 + if (ret) {
141437 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
141438 + return -ENODEV;
141439 + }
141440 +
141441 + p = kzalloc(sizeof(*p), GFP_KERNEL);
141442 + if (!p)
141443 + return -ENOMEM;
141444 + p->idx = channel_idx;
141445 + p->dcp_idx = lni->dcp_idx;
141446 + p->lni_idx = lni->idx;
141447 + list_add_tail(&p->node, &lni->channels);
141448 + INIT_LIST_HEAD(&p->class_queues);
141449 + INIT_LIST_HEAD(&p->ccgs);
141450 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141451 + channel_idx);
141452 + config_opts.dcpid = lni->dcp_idx;
141453 + config_opts.channel_mapping.map_lni_id = lni->idx;
141454 + config_opts.channel_mapping.map_shaped = 0;
141455 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
141456 + pr_err("Can't map channel#%d for LNI#%d\n",
141457 + channel_idx, lni->idx);
141458 + return -EINVAL;
141459 + }
141460 + *channel = p;
141461 + return 0;
141462 +}
141463 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
141464 +
141465 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
141466 +{
141467 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141468 + if (!list_empty(&channel->class_queues)) {
141469 + pr_err("CEETM channel#%d has class queue unreleased!\n",
141470 + channel->idx);
141471 + return -EBUSY;
141472 + }
141473 + if (!list_empty(&channel->ccgs)) {
141474 + pr_err("CEETM channel#%d has ccg unreleased!\n",
141475 + channel->idx);
141476 + return -EBUSY;
141477 + }
141478 +
141479 + /* channel->dcp_idx corresponds to known fman validation */
141480 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
141481 + (channel->dcp_idx != qm_dc_portal_fman1)) {
141482 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141483 + channel->dcp_idx);
141484 + return -EINVAL;
141485 + }
141486 +
141487 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141488 + channel->idx);
141489 + config_opts.dcpid = channel->dcp_idx;
141490 + memset(&config_opts.shaper_config, 0,
141491 + sizeof(config_opts.shaper_config));
141492 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
141493 + pr_err("Can't reset channel shapping parameters\n");
141494 + return -EINVAL;
141495 + }
141496 +
141497 + if (channel->dcp_idx == qm_dc_portal_fman0) {
141498 + qman_release_ceetm0_channelid(channel->idx);
141499 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
141500 + qman_release_ceetm1_channelid(channel->idx);
141501 + } else {
141502 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141503 + channel->dcp_idx);
141504 + return -EINVAL;
141505 + }
141506 + list_del(&channel->node);
141507 + kfree(channel);
141508 +
141509 + return 0;
141510 +}
141511 +EXPORT_SYMBOL(qman_ceetm_channel_release);
141512 +
141513 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
141514 + int coupled)
141515 +{
141516 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141517 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141518 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141519 +
141520 + if (channel->shaper_enable == 1) {
141521 + pr_err("This channel shaper has been enabled!\n");
141522 + return -EINVAL;
141523 + }
141524 +
141525 + channel->shaper_enable = 1;
141526 + channel->shaper_couple = coupled;
141527 +
141528 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141529 + channel->idx);
141530 + query_opts.dcpid = channel->dcp_idx;
141531 +
141532 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141533 + pr_err("Can't query channel mapping\n");
141534 + return -EINVAL;
141535 + }
141536 +
141537 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141538 + channel->idx);
141539 + config_opts.dcpid = channel->dcp_idx;
141540 + config_opts.channel_mapping.map_lni_id =
141541 + query_result.channel_mapping_query.map_lni_id;
141542 + config_opts.channel_mapping.map_shaped = 1;
141543 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
141544 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
141545 + return -EINVAL;
141546 + }
141547 +
141548 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141549 + channel->idx);
141550 + config_opts.shaper_config.cpl = coupled;
141551 + config_opts.shaper_config.crtcr =
141552 + cpu_to_be24((channel->cr_token_rate.whole
141553 + << 13) |
141554 + channel->cr_token_rate.fraction);
141555 + config_opts.shaper_config.ertcr =
141556 + cpu_to_be24(channel->er_token_rate.whole
141557 + << 13 |
141558 + channel->er_token_rate.fraction);
141559 + config_opts.shaper_config.crtbl =
141560 + cpu_to_be16(channel->cr_token_bucket_limit);
141561 + config_opts.shaper_config.ertbl =
141562 + cpu_to_be16(channel->er_token_bucket_limit);
141563 +
141564 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141565 +}
141566 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
141567 +
141568 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
141569 +{
141570 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141571 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141572 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141573 +
141574 +
141575 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141576 + channel->idx);
141577 + query_opts.dcpid = channel->dcp_idx;
141578 +
141579 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141580 + pr_err("Can't query channel mapping\n");
141581 + return -EINVAL;
141582 + }
141583 +
141584 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141585 + channel->idx);
141586 + config_opts.dcpid = channel->dcp_idx;
141587 + config_opts.channel_mapping.map_shaped = 0;
141588 + config_opts.channel_mapping.map_lni_id =
141589 + query_result.channel_mapping_query.map_lni_id;
141590 +
141591 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141592 +}
141593 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
141594 +
141595 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
141596 +{
141597 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141598 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141599 +
141600 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141601 + channel->idx);
141602 + query_opts.dcpid = channel->dcp_idx;
141603 +
141604 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141605 + pr_err("Can't query channel mapping\n");
141606 + return -EINVAL;
141607 + }
141608 +
141609 + return query_result.channel_mapping_query.map_shaped;
141610 +}
141611 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
141612 +
141613 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
141614 + const struct qm_ceetm_rate *token_rate,
141615 + u16 token_limit)
141616 +{
141617 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141618 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141619 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141620 + int ret;
141621 +
141622 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141623 + channel->idx);
141624 + query_opts.dcpid = channel->dcp_idx;
141625 +
141626 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141627 + if (ret) {
141628 + pr_err("Fail to get the current channel shaper setting\n");
141629 + return -EINVAL;
141630 + }
141631 +
141632 + channel->cr_token_rate.whole = token_rate->whole;
141633 + channel->cr_token_rate.fraction = token_rate->fraction;
141634 + channel->cr_token_bucket_limit = token_limit;
141635 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141636 + channel->idx);
141637 + config_opts.dcpid = channel->dcp_idx;
141638 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
141639 + << 13) | (token_rate->fraction));
141640 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
141641 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
141642 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
141643 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
141644 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141645 +}
141646 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
141647 +
141648 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
141649 + u64 bps, u16 token_limit)
141650 +{
141651 + struct qm_ceetm_rate token_rate;
141652 + int ret;
141653 +
141654 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
141655 + if (ret) {
141656 + pr_err("Can not convert bps to token rate\n");
141657 + return -EINVAL;
141658 + }
141659 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
141660 + token_limit);
141661 +}
141662 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
141663 +
141664 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
141665 + struct qm_ceetm_rate *token_rate,
141666 + u16 *token_limit)
141667 +{
141668 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141669 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141670 + int ret;
141671 +
141672 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141673 + channel->idx);
141674 + query_opts.dcpid = channel->dcp_idx;
141675 +
141676 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141677 + if (ret | !query_result.shaper_query.crtcr |
141678 + !query_result.shaper_query.crtbl) {
141679 + pr_err("The channel commit rate or limit is not set\n");
141680 + return -EINVAL;
141681 + }
141682 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
141683 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
141684 + 0x1FFF;
141685 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
141686 + return 0;
141687 +}
141688 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
141689 +
141690 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
141691 + u64 *bps, u16 *token_limit)
141692 +{
141693 + struct qm_ceetm_rate token_rate;
141694 + int ret;
141695 +
141696 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
141697 + token_limit);
141698 + if (ret) {
141699 + pr_err("The channel CR rate or limit is not available\n");
141700 + return -EINVAL;
141701 + }
141702 +
141703 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
141704 +}
141705 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
141706 +
141707 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
141708 + const struct qm_ceetm_rate *token_rate,
141709 + u16 token_limit)
141710 +{
141711 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141712 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141713 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141714 + int ret;
141715 +
141716 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141717 + channel->idx);
141718 + query_opts.dcpid = channel->dcp_idx;
141719 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141720 + if (ret) {
141721 + pr_err("Fail to get the current channel shaper setting\n");
141722 + return -EINVAL;
141723 + }
141724 +
141725 + channel->er_token_rate.whole = token_rate->whole;
141726 + channel->er_token_rate.fraction = token_rate->fraction;
141727 + channel->er_token_bucket_limit = token_limit;
141728 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141729 + channel->idx);
141730 + config_opts.dcpid = channel->dcp_idx;
141731 + config_opts.shaper_config.ertcr = cpu_to_be24(
141732 + (token_rate->whole << 13) | (token_rate->fraction));
141733 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
141734 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
141735 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
141736 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
141737 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141738 +}
141739 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
141740 +
141741 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
141742 + u64 bps, u16 token_limit)
141743 +{
141744 + struct qm_ceetm_rate token_rate;
141745 + int ret;
141746 +
141747 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
141748 + if (ret) {
141749 + pr_err("Can not convert bps to token rate\n");
141750 + return -EINVAL;
141751 + }
141752 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
141753 + token_limit);
141754 +}
141755 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
141756 +
141757 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
141758 + struct qm_ceetm_rate *token_rate,
141759 + u16 *token_limit)
141760 +{
141761 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141762 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141763 + int ret;
141764 +
141765 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141766 + channel->idx);
141767 + query_opts.dcpid = channel->dcp_idx;
141768 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141769 + if (ret | !query_result.shaper_query.ertcr |
141770 + !query_result.shaper_query.ertbl) {
141771 + pr_err("The channel excess rate or limit is not set\n");
141772 + return -EINVAL;
141773 + }
141774 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
141775 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
141776 + 0x1FFF;
141777 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
141778 + return 0;
141779 +}
141780 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
141781 +
141782 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
141783 + u64 *bps, u16 *token_limit)
141784 +{
141785 + struct qm_ceetm_rate token_rate;
141786 + int ret;
141787 +
141788 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
141789 + token_limit);
141790 + if (ret) {
141791 + pr_err("The channel ER rate or limit is not available\n");
141792 + return -EINVAL;
141793 + }
141794 +
141795 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
141796 +}
141797 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
141798 +
141799 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
141800 + u16 token_limit)
141801 +{
141802 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141803 +
141804 + if (channel->shaper_enable) {
141805 + pr_err("This channel is a shaped one\n");
141806 + return -EINVAL;
141807 + }
141808 +
141809 + channel->cr_token_bucket_limit = token_limit;
141810 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141811 + channel->idx);
141812 + config_opts.dcpid = channel->dcp_idx;
141813 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
141814 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141815 +}
141816 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
141817 +
141818 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
141819 + u16 *token_limit)
141820 +{
141821 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141822 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141823 + int ret;
141824 +
141825 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141826 + channel->idx);
141827 + query_opts.dcpid = channel->dcp_idx;
141828 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141829 + if (ret | !query_result.shaper_query.crtbl) {
141830 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
141831 + return -EINVAL;
141832 + }
141833 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
141834 + return 0;
141835 +}
141836 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
141837 +
141838 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
141839 + unsigned int prio_a, unsigned int prio_b)
141840 +{
141841 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
141842 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141843 + int i;
141844 +
141845 + if (prio_a > 7) {
141846 + pr_err("The priority of group A is out of range\n");
141847 + return -EINVAL;
141848 + }
141849 + if (group_b && (prio_b > 7)) {
141850 + pr_err("The priority of group B is out of range\n");
141851 + return -EINVAL;
141852 + }
141853 +
141854 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
141855 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
141856 + return -EINVAL;
141857 + }
141858 +
141859 + config_opts.cqcid = cpu_to_be16(channel->idx);
141860 + config_opts.dcpid = channel->dcp_idx;
141861 + config_opts.gpc_combine_flag = !group_b;
141862 + config_opts.gpc_prio_a = prio_a;
141863 + config_opts.gpc_prio_b = prio_b;
141864 +
141865 + for (i = 0; i < 8; i++)
141866 + config_opts.w[i] = query_result.w[i];
141867 + config_opts.crem = query_result.crem;
141868 + config_opts.erem = query_result.erem;
141869 +
141870 + return qman_ceetm_configure_class_scheduler(&config_opts);
141871 +}
141872 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
141873 +
141874 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
141875 + unsigned int *prio_a, unsigned int *prio_b)
141876 +{
141877 + struct qm_mcr_ceetm_class_scheduler_query query_result;
141878 +
141879 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
141880 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
141881 + return -EINVAL;
141882 + }
141883 + *group_b = !query_result.gpc_combine_flag;
141884 + *prio_a = query_result.gpc_prio_a;
141885 + *prio_b = query_result.gpc_prio_b;
141886 +
141887 + return 0;
141888 +}
141889 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
141890 +
141891 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
141892 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
141893 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
141894 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
141895 + *channel, int group_b, int cre)
141896 +{
141897 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141898 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141899 + int i;
141900 +
141901 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141902 + pr_err("Cannot get the channel %d scheduler setting.\n",
141903 + channel->idx);
141904 + return -EINVAL;
141905 + }
141906 + csch_config.cqcid = cpu_to_be16(channel->idx);
141907 + csch_config.dcpid = channel->dcp_idx;
141908 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141909 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
141910 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
141911 +
141912 + for (i = 0; i < 8; i++)
141913 + csch_config.w[i] = csch_query.w[i];
141914 + csch_config.erem = csch_query.erem;
141915 + if (group_b)
141916 + csch_config.crem = (be16_to_cpu(csch_query.crem)
141917 + & ~GROUP_B_ELIGIBILITY_SET)
141918 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
141919 + else
141920 + csch_config.crem = (be16_to_cpu(csch_query.crem)
141921 + & ~GROUP_A_ELIGIBILITY_SET)
141922 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
141923 +
141924 + csch_config.crem = cpu_to_be16(csch_config.crem);
141925 +
141926 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141927 + pr_err("Cannot config channel %d's scheduler with "
141928 + "group_%c's cr eligibility\n", channel->idx,
141929 + group_b ? 'b' : 'a');
141930 + return -EINVAL;
141931 + }
141932 +
141933 + return 0;
141934 +}
141935 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
141936 +
141937 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
141938 + *channel, int group_b, int ere)
141939 +{
141940 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141941 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141942 + int i;
141943 +
141944 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141945 + pr_err("Cannot get the channel %d scheduler setting.\n",
141946 + channel->idx);
141947 + return -EINVAL;
141948 + }
141949 + csch_config.cqcid = cpu_to_be16(channel->idx);
141950 + csch_config.dcpid = channel->dcp_idx;
141951 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141952 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
141953 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
141954 +
141955 + for (i = 0; i < 8; i++)
141956 + csch_config.w[i] = csch_query.w[i];
141957 + csch_config.crem = csch_query.crem;
141958 + if (group_b)
141959 + csch_config.erem = (be16_to_cpu(csch_query.erem)
141960 + & ~GROUP_B_ELIGIBILITY_SET)
141961 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
141962 + else
141963 + csch_config.erem = (be16_to_cpu(csch_query.erem)
141964 + & ~GROUP_A_ELIGIBILITY_SET)
141965 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
141966 +
141967 + csch_config.erem = cpu_to_be16(csch_config.erem);
141968 +
141969 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
141970 + pr_err("Cannot config channel %d's scheduler with "
141971 + "group_%c's er eligibility\n", channel->idx,
141972 + group_b ? 'b' : 'a');
141973 + return -EINVAL;
141974 + }
141975 +
141976 + return 0;
141977 +}
141978 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
141979 +
141980 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
141981 + unsigned int idx, int cre)
141982 +{
141983 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
141984 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
141985 + int i;
141986 +
141987 + if (idx > 7) {
141988 + pr_err("CQ index is out of range\n");
141989 + return -EINVAL;
141990 + }
141991 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
141992 + pr_err("Cannot get the channel %d scheduler setting.\n",
141993 + channel->idx);
141994 + return -EINVAL;
141995 + }
141996 + csch_config.cqcid = cpu_to_be16(channel->idx);
141997 + csch_config.dcpid = channel->dcp_idx;
141998 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
141999 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
142000 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
142001 + for (i = 0; i < 8; i++)
142002 + csch_config.w[i] = csch_query.w[i];
142003 + csch_config.erem = csch_query.erem;
142004 + csch_config.crem = (be16_to_cpu(csch_query.crem)
142005 + & ~CQ_ELIGIBILITY_SET(idx)) |
142006 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
142007 + csch_config.crem = cpu_to_be16(csch_config.crem);
142008 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
142009 + pr_err("Cannot config channel scheduler to set "
142010 + "cr eligibility mask for CQ#%d\n", idx);
142011 + return -EINVAL;
142012 + }
142013 +
142014 + return 0;
142015 +}
142016 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
142017 +
142018 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
142019 + unsigned int idx, int ere)
142020 +{
142021 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
142022 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
142023 + int i;
142024 +
142025 + if (idx > 7) {
142026 + pr_err("CQ index is out of range\n");
142027 + return -EINVAL;
142028 + }
142029 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
142030 + pr_err("Cannot get the channel %d scheduler setting.\n",
142031 + channel->idx);
142032 + return -EINVAL;
142033 + }
142034 + csch_config.cqcid = cpu_to_be16(channel->idx);
142035 + csch_config.dcpid = channel->dcp_idx;
142036 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
142037 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
142038 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
142039 + for (i = 0; i < 8; i++)
142040 + csch_config.w[i] = csch_query.w[i];
142041 + csch_config.crem = csch_query.crem;
142042 + csch_config.erem = (be16_to_cpu(csch_query.erem)
142043 + & ~CQ_ELIGIBILITY_SET(idx)) |
142044 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
142045 + csch_config.erem = cpu_to_be16(csch_config.erem);
142046 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
142047 + pr_err("Cannot config channel scheduler to set "
142048 + "er eligibility mask for CQ#%d\n", idx);
142049 + return -EINVAL;
142050 + }
142051 + return 0;
142052 +}
142053 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
142054 +
142055 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
142056 + struct qm_ceetm_channel *channel, unsigned int idx,
142057 + struct qm_ceetm_ccg *ccg)
142058 +{
142059 + struct qm_ceetm_cq *p;
142060 + struct qm_mcc_ceetm_cq_config cq_config;
142061 +
142062 + if (idx > 7) {
142063 + pr_err("The independent class queue id is out of range\n");
142064 + return -EINVAL;
142065 + }
142066 +
142067 + list_for_each_entry(p, &channel->class_queues, node) {
142068 + if (p->idx == idx) {
142069 + pr_err("The CQ#%d has been claimed!\n", idx);
142070 + return -EINVAL;
142071 + }
142072 + }
142073 +
142074 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142075 + if (!p) {
142076 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
142077 + return -ENOMEM;
142078 + }
142079 +
142080 + list_add_tail(&p->node, &channel->class_queues);
142081 + p->idx = idx;
142082 + p->is_claimed = 1;
142083 + p->parent = channel;
142084 + INIT_LIST_HEAD(&p->bound_lfqids);
142085 +
142086 + if (ccg) {
142087 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
142088 + cq_config.dcpid = channel->dcp_idx;
142089 + cq_config.ccgid = cpu_to_be16(ccg->idx);
142090 + if (qman_ceetm_configure_cq(&cq_config)) {
142091 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
142092 + idx, ccg->idx);
142093 + list_del(&p->node);
142094 + kfree(p);
142095 + return -EINVAL;
142096 + }
142097 + }
142098 +
142099 + *cq = p;
142100 + return 0;
142101 +}
142102 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
142103 +
142104 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
142105 + struct qm_ceetm_channel *channel, unsigned int idx,
142106 + struct qm_ceetm_ccg *ccg)
142107 +{
142108 + struct qm_ceetm_cq *p;
142109 + struct qm_mcc_ceetm_cq_config cq_config;
142110 +
142111 + if ((idx < 8) || (idx > 15)) {
142112 + pr_err("This grouped class queue id is out of range\n");
142113 + return -EINVAL;
142114 + }
142115 +
142116 + list_for_each_entry(p, &channel->class_queues, node) {
142117 + if (p->idx == idx) {
142118 + pr_err("The CQ#%d has been claimed!\n", idx);
142119 + return -EINVAL;
142120 + }
142121 + }
142122 +
142123 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142124 + if (!p) {
142125 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
142126 + return -ENOMEM;
142127 + }
142128 +
142129 + list_add_tail(&p->node, &channel->class_queues);
142130 + p->idx = idx;
142131 + p->is_claimed = 1;
142132 + p->parent = channel;
142133 + INIT_LIST_HEAD(&p->bound_lfqids);
142134 +
142135 + if (ccg) {
142136 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
142137 + cq_config.dcpid = channel->dcp_idx;
142138 + cq_config.ccgid = cpu_to_be16(ccg->idx);
142139 + if (qman_ceetm_configure_cq(&cq_config)) {
142140 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
142141 + idx, ccg->idx);
142142 + list_del(&p->node);
142143 + kfree(p);
142144 + return -EINVAL;
142145 + }
142146 + }
142147 + *cq = p;
142148 + return 0;
142149 +}
142150 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
142151 +
142152 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
142153 + struct qm_ceetm_channel *channel, unsigned int idx,
142154 + struct qm_ceetm_ccg *ccg)
142155 +{
142156 + struct qm_ceetm_cq *p;
142157 + struct qm_mcc_ceetm_cq_config cq_config;
142158 +
142159 + if ((idx < 12) || (idx > 15)) {
142160 + pr_err("This grouped class queue id is out of range\n");
142161 + return -EINVAL;
142162 + }
142163 +
142164 + list_for_each_entry(p, &channel->class_queues, node) {
142165 + if (p->idx == idx) {
142166 + pr_err("The CQ#%d has been claimed!\n", idx);
142167 + return -EINVAL;
142168 + }
142169 + }
142170 +
142171 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142172 + if (!p) {
142173 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
142174 + return -ENOMEM;
142175 + }
142176 +
142177 + list_add_tail(&p->node, &channel->class_queues);
142178 + p->idx = idx;
142179 + p->is_claimed = 1;
142180 + p->parent = channel;
142181 + INIT_LIST_HEAD(&p->bound_lfqids);
142182 +
142183 + if (ccg) {
142184 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
142185 + cq_config.dcpid = channel->dcp_idx;
142186 + cq_config.ccgid = cpu_to_be16(ccg->idx);
142187 + if (qman_ceetm_configure_cq(&cq_config)) {
142188 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
142189 + idx, ccg->idx);
142190 + list_del(&p->node);
142191 + kfree(p);
142192 + return -EINVAL;
142193 + }
142194 + }
142195 + *cq = p;
142196 + return 0;
142197 +}
142198 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
142199 +
142200 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
142201 +{
142202 + if (!list_empty(&cq->bound_lfqids)) {
142203 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
142204 + return -EBUSY;
142205 + }
142206 + list_del(&cq->node);
142207 + qman_ceetm_drain_cq(cq);
142208 + kfree(cq);
142209 + return 0;
142210 +}
142211 +EXPORT_SYMBOL(qman_ceetm_cq_release);
142212 +
142213 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
142214 + struct qm_ceetm_weight_code *weight_code)
142215 +{
142216 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
142217 + struct qm_mcr_ceetm_class_scheduler_query query_result;
142218 + int i;
142219 +
142220 + if (cq->idx < 8) {
142221 + pr_err("Can not set weight for ungrouped class queue\n");
142222 + return -EINVAL;
142223 + }
142224 +
142225 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
142226 + pr_err("Can't query channel#%d's scheduler!\n",
142227 + cq->parent->idx);
142228 + return -EINVAL;
142229 + }
142230 +
142231 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
142232 + config_opts.dcpid = cq->parent->dcp_idx;
142233 + config_opts.crem = query_result.crem;
142234 + config_opts.erem = query_result.erem;
142235 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
142236 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
142237 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
142238 +
142239 + for (i = 0; i < 8; i++)
142240 + config_opts.w[i] = query_result.w[i];
142241 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
142242 + (weight_code->x & 0x7));
142243 + return qman_ceetm_configure_class_scheduler(&config_opts);
142244 +}
142245 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
142246 +
142247 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
142248 + struct qm_ceetm_weight_code *weight_code)
142249 +{
142250 + struct qm_mcr_ceetm_class_scheduler_query query_result;
142251 +
142252 + if (cq->idx < 8) {
142253 + pr_err("Can not get weight for ungrouped class queue\n");
142254 + return -EINVAL;
142255 + }
142256 +
142257 + if (qman_ceetm_query_class_scheduler(cq->parent,
142258 + &query_result)) {
142259 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
142260 + return -EINVAL;
142261 + }
142262 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
142263 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
142264 +
142265 + return 0;
142266 +}
142267 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
142268 +
142269 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
142270 + * effective weight = 2^x / (1 - (y/64))
142271 + * = 2^(x+6) / (64 - y)
142272 + */
142273 +static void reduce_fraction(u32 *n, u32 *d)
142274 +{
142275 + u32 factor = 2;
142276 + u32 lesser = (*n < *d) ? *n : *d;
142277 + /* If factor exceeds the square-root of the lesser of *n and *d,
142278 + * then there's no point continuing. Proof: if there was a factor
142279 + * bigger than the square root, that would imply there exists
142280 + * another factor smaller than the square-root with which it
142281 + * multiplies to give 'lesser' - but that's a contradiction
142282 + * because the other factor would have already been found and
142283 + * divided out.
142284 + */
142285 + while ((factor * factor) <= lesser) {
142286 + /* If 'factor' is a factor of *n and *d, divide them both
142287 + * by 'factor' as many times as possible.
142288 + */
142289 + while (!(*n % factor) && !(*d % factor)) {
142290 + *n /= factor;
142291 + *d /= factor;
142292 + lesser /= factor;
142293 + }
142294 + if (factor == 2)
142295 + factor = 3;
142296 + else
142297 + factor += 2;
142298 + }
142299 +}
142300 +
142301 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
142302 + u32 *numerator,
142303 + u32 *denominator)
142304 +{
142305 + *numerator = (u32) 1 << (weight_code->x + 6);
142306 + *denominator = 64 - weight_code->y;
142307 + reduce_fraction(numerator, denominator);
142308 + return 0;
142309 +}
142310 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
142311 +
142312 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
142313 + * So find 'x' by range, and then estimate 'y' using:
142314 + * 64 - y = 2^(x + 6) / weight
142315 + * = 2^(x + 6) / (n/d)
142316 + * = d * 2^(x+6) / n
142317 + * y = 64 - (d * 2^(x+6) / n)
142318 + */
142319 +int qman_ceetm_ratio2wbfs(u32 numerator,
142320 + u32 denominator,
142321 + struct qm_ceetm_weight_code *weight_code,
142322 + int rounding)
142323 +{
142324 + unsigned int y, x = 0;
142325 + /* search incrementing 'x' until:
142326 + * weight < 2^(x+1)
142327 + * n/d < 2^(x+1)
142328 + * n < d * 2^(x+1)
142329 + */
142330 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
142331 + x++;
142332 + if (x >= 8)
142333 + return -ERANGE;
142334 + /* because of the subtraction, use '-rounding' */
142335 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
142336 + if (y >= 32)
142337 + return -ERANGE;
142338 + weight_code->x = x;
142339 + weight_code->y = y;
142340 + return 0;
142341 +}
142342 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
142343 +
142344 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
142345 +{
142346 + struct qm_ceetm_weight_code weight_code;
142347 +
142348 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
142349 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
142350 + return -EINVAL;
142351 + }
142352 + return qman_ceetm_set_queue_weight(cq, &weight_code);
142353 +}
142354 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
142355 +
142356 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
142357 +{
142358 + struct qm_ceetm_weight_code weight_code;
142359 + u32 n, d;
142360 +
142361 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
142362 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
142363 + return -EINVAL;
142364 + }
142365 +
142366 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
142367 + pr_err("Cannot get the ratio with wbfs code\n");
142368 + return -EINVAL;
142369 + }
142370 +
142371 + *ratio = (n * 100) / d;
142372 + return 0;
142373 +}
142374 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
142375 +
142376 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
142377 + u64 *frame_count, u64 *byte_count)
142378 +{
142379 + struct qm_mcr_ceetm_statistics_query result;
142380 + u16 cid, command_type;
142381 + enum qm_dc_portal dcp_idx;
142382 + int ret;
142383 +
142384 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
142385 + dcp_idx = cq->parent->dcp_idx;
142386 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
142387 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
142388 + else
142389 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
142390 +
142391 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
142392 + if (ret) {
142393 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
142394 + return -EINVAL;
142395 + }
142396 +
142397 + *frame_count = be40_to_cpu(result.frm_cnt);
142398 + *byte_count = be48_to_cpu(result.byte_cnt);
142399 + return 0;
142400 +}
142401 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
142402 +
142403 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
142404 +{
142405 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
142406 + int ret;
142407 +
142408 + do {
142409 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
142410 + if (ret) {
142411 + pr_err("Failed to pop frame from CQ\n");
142412 + return -EINVAL;
142413 + }
142414 + } while (!(ppxr.stat & 0x2));
142415 +
142416 + return 0;
142417 +}
142418 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
142419 +
142420 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
142421 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
142422 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
142423 + struct qm_ceetm_cq *cq)
142424 +{
142425 + struct qm_ceetm_lfq *p;
142426 + u32 lfqid;
142427 + int ret = 0;
142428 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
142429 +
142430 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
142431 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
142432 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
142433 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
142434 + } else {
142435 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
142436 + cq->parent->dcp_idx);
142437 + return -EINVAL;
142438 + }
142439 +
142440 + if (ret) {
142441 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
142442 + return -ENODEV;
142443 + }
142444 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142445 + if (!p)
142446 + return -ENOMEM;
142447 + p->idx = lfqid;
142448 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
142449 + p->parent = cq->parent;
142450 + list_add_tail(&p->node, &cq->bound_lfqids);
142451 +
142452 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
142453 + (cq->parent->dcp_idx << 16) |
142454 + (lfqid & CEETM_LFQMT_LFQID_LSB));
142455 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
142456 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
142457 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
142458 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
142459 + lfqid, cq->idx);
142460 + list_del(&p->node);
142461 + kfree(p);
142462 + return -EINVAL;
142463 + }
142464 + *lfq = p;
142465 + return 0;
142466 +}
142467 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
142468 +
142469 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
142470 +{
142471 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
142472 + qman_release_ceetm0_lfqid(lfq->idx);
142473 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
142474 + qman_release_ceetm1_lfqid(lfq->idx);
142475 + } else {
142476 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
142477 + lfq->parent->dcp_idx);
142478 + return -EINVAL;
142479 + }
142480 + list_del(&lfq->node);
142481 + kfree(lfq);
142482 + return 0;
142483 +}
142484 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
142485 +
142486 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
142487 + u32 context_b)
142488 +{
142489 + struct qm_mcc_ceetm_dct_config dct_config;
142490 + lfq->context_a = context_a;
142491 + lfq->context_b = context_b;
142492 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
142493 + dct_config.dcpid = lfq->parent->dcp_idx;
142494 + dct_config.context_b = cpu_to_be32(context_b);
142495 + dct_config.context_a = cpu_to_be64(context_a);
142496 +
142497 + return qman_ceetm_configure_dct(&dct_config);
142498 +}
142499 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
142500 +
142501 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
142502 + u32 *context_b)
142503 +{
142504 + struct qm_mcc_ceetm_dct_query dct_query;
142505 + struct qm_mcr_ceetm_dct_query query_result;
142506 +
142507 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
142508 + dct_query.dcpid = lfq->parent->dcp_idx;
142509 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
142510 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
142511 + return -EINVAL;
142512 + }
142513 + *context_a = be64_to_cpu(query_result.context_a);
142514 + *context_b = be32_to_cpu(query_result.context_b);
142515 + return 0;
142516 +}
142517 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
142518 +
142519 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
142520 +{
142521 + spin_lock_init(&fq->fqlock);
142522 + fq->fqid = lfq->idx;
142523 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
142524 + if (lfq->ern)
142525 + fq->cb.ern = lfq->ern;
142526 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
142527 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
142528 + return -ENOMEM;
142529 +#endif
142530 + return 0;
142531 +}
142532 +EXPORT_SYMBOL(qman_ceetm_create_fq);
142533 +
142534 +#define MAX_CCG_IDX 0x000F
142535 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
142536 + struct qm_ceetm_channel *channel,
142537 + unsigned int idx,
142538 + void (*cscn)(struct qm_ceetm_ccg *,
142539 + void *cb_ctx,
142540 + int congested),
142541 + void *cb_ctx)
142542 +{
142543 + struct qm_ceetm_ccg *p;
142544 +
142545 + if (idx > MAX_CCG_IDX) {
142546 + pr_err("The given ccg index is out of range\n");
142547 + return -EINVAL;
142548 + }
142549 +
142550 + list_for_each_entry(p, &channel->ccgs, node) {
142551 + if (p->idx == idx) {
142552 + pr_err("The CCG#%d has been claimed\n", idx);
142553 + return -EINVAL;
142554 + }
142555 + }
142556 +
142557 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142558 + if (!p) {
142559 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
142560 + return -ENOMEM;
142561 + }
142562 +
142563 + list_add_tail(&p->node, &channel->ccgs);
142564 +
142565 + p->idx = idx;
142566 + p->parent = channel;
142567 + p->cb = cscn;
142568 + p->cb_ctx = cb_ctx;
142569 + INIT_LIST_HEAD(&p->cb_node);
142570 +
142571 + *ccg = p;
142572 + return 0;
142573 +}
142574 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
142575 +
142576 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
142577 +{
142578 + unsigned long irqflags __maybe_unused;
142579 + struct qm_mcc_ceetm_ccgr_config config_opts;
142580 + int ret = 0;
142581 + struct qman_portal *p = get_affine_portal();
142582 +
142583 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
142584 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
142585 + if (!list_empty(&ccg->cb_node))
142586 + list_del(&ccg->cb_node);
142587 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
142588 + (ccg->parent->idx << 4) | ccg->idx);
142589 + config_opts.dcpid = ccg->parent->dcp_idx;
142590 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
142591 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
142592 + ret = qman_ceetm_configure_ccgr(&config_opts);
142593 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
142594 + put_affine_portal();
142595 +
142596 + list_del(&ccg->node);
142597 + kfree(ccg);
142598 + return ret;
142599 +}
142600 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
142601 +
142602 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
142603 + const struct qm_ceetm_ccg_params *params)
142604 +{
142605 + struct qm_mcc_ceetm_ccgr_config config_opts;
142606 + unsigned long irqflags __maybe_unused;
142607 + int ret;
142608 + struct qman_portal *p;
142609 +
142610 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
142611 + return -EINVAL;
142612 +
142613 + p = get_affine_portal();
142614 +
142615 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
142616 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
142617 +
142618 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
142619 + (ccg->parent->idx << 4) | ccg->idx);
142620 + config_opts.dcpid = ccg->parent->dcp_idx;
142621 + config_opts.we_mask = we_mask;
142622 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
142623 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
142624 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
142625 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
142626 + }
142627 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
142628 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
142629 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
142630 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
142631 + config_opts.cm_config.ctl_td_en = params->td_en;
142632 + config_opts.cm_config.ctl_td_mode = params->td_mode;
142633 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
142634 + config_opts.cm_config.ctl_mode = params->mode;
142635 + config_opts.cm_config.oal = params->oal;
142636 + config_opts.cm_config.cs_thres.hword =
142637 + cpu_to_be16(params->cs_thres_in.hword);
142638 + config_opts.cm_config.cs_thres_x.hword =
142639 + cpu_to_be16(params->cs_thres_out.hword);
142640 + config_opts.cm_config.td_thres.hword =
142641 + cpu_to_be16(params->td_thres.hword);
142642 + config_opts.cm_config.wr_parm_g.word =
142643 + cpu_to_be32(params->wr_parm_g.word);
142644 + config_opts.cm_config.wr_parm_y.word =
142645 + cpu_to_be32(params->wr_parm_y.word);
142646 + config_opts.cm_config.wr_parm_r.word =
142647 + cpu_to_be32(params->wr_parm_r.word);
142648 + ret = qman_ceetm_configure_ccgr(&config_opts);
142649 + if (ret) {
142650 + pr_err("Configure CCGR CM failed!\n");
142651 + goto release_lock;
142652 + }
142653 +
142654 + if (we_mask & QM_CCGR_WE_CSCN_EN)
142655 + if (list_empty(&ccg->cb_node))
142656 + list_add(&ccg->cb_node,
142657 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
142658 +release_lock:
142659 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
142660 + put_affine_portal();
142661 + return ret;
142662 +}
142663 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
142664 +
142665 +#define CEETM_CCGR_CTL_MASK 0x01
142666 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
142667 + struct qm_ceetm_ccg_params *params)
142668 +{
142669 + struct qm_mcc_ceetm_ccgr_query query_opts;
142670 + struct qm_mcr_ceetm_ccgr_query query_result;
142671 +
142672 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
142673 + (ccg->parent->idx << 4) | ccg->idx);
142674 + query_opts.dcpid = ccg->parent->dcp_idx;
142675 +
142676 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
142677 + pr_err("Can't query CCGR#%d\n", ccg->idx);
142678 + return -EINVAL;
142679 + }
142680 +
142681 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
142682 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
142683 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
142684 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
142685 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
142686 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
142687 + params->oal = query_result.cm_query.oal;
142688 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
142689 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
142690 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
142691 + params->td_en = query_result.cm_query.ctl_td_en;
142692 + params->td_mode = query_result.cm_query.ctl_td_mode;
142693 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
142694 + params->mode = query_result.cm_query.ctl_mode;
142695 +
142696 + return 0;
142697 +}
142698 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
142699 +
142700 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
142701 + u64 *frame_count, u64 *byte_count)
142702 +{
142703 + struct qm_mcr_ceetm_statistics_query result;
142704 + u16 cid, command_type;
142705 + enum qm_dc_portal dcp_idx;
142706 + int ret;
142707 +
142708 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
142709 + dcp_idx = ccg->parent->dcp_idx;
142710 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
142711 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
142712 + else
142713 + command_type = CEETM_QUERY_REJECT_STATISTICS;
142714 +
142715 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
142716 + if (ret) {
142717 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
142718 + return -EINVAL;
142719 + }
142720 +
142721 + *frame_count = be40_to_cpu(result.frm_cnt);
142722 + *byte_count = be48_to_cpu(result.byte_cnt);
142723 + return 0;
142724 +}
142725 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
142726 +
142727 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
142728 + u16 swp_idx,
142729 + unsigned int *cscn_enabled)
142730 +{
142731 + struct qm_mcc_ceetm_ccgr_query query_opts;
142732 + struct qm_mcr_ceetm_ccgr_query query_result;
142733 + int i;
142734 +
142735 + DPA_ASSERT(swp_idx < 127);
142736 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
142737 + (ccg->parent->idx << 4) | ccg->idx);
142738 + query_opts.dcpid = ccg->parent->dcp_idx;
142739 +
142740 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
142741 + pr_err("Can't query CCGR#%d\n", ccg->idx);
142742 + return -EINVAL;
142743 + }
142744 +
142745 + i = swp_idx / 32;
142746 + i = 3 - i;
142747 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
142748 + (31 - swp_idx % 32);
142749 +
142750 + return 0;
142751 +}
142752 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
142753 +
142754 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
142755 + u16 dcp_idx,
142756 + u8 vcgid,
142757 + unsigned int cscn_enabled,
142758 + u16 we_mask,
142759 + const struct qm_ceetm_ccg_params *params)
142760 +{
142761 + struct qm_mcc_ceetm_ccgr_config config_opts;
142762 + int ret;
142763 +
142764 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
142765 + (ccg->parent->idx << 4) | ccg->idx);
142766 + config_opts.dcpid = ccg->parent->dcp_idx;
142767 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
142768 + QM_CCGR_WE_CDV);
142769 + config_opts.cm_config.cdv = vcgid;
142770 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
142771 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
142772 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
142773 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
142774 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
142775 + config_opts.cm_config.ctl_td_en = params->td_en;
142776 + config_opts.cm_config.ctl_td_mode = params->td_mode;
142777 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
142778 + config_opts.cm_config.ctl_mode = params->mode;
142779 + config_opts.cm_config.cs_thres.hword =
142780 + cpu_to_be16(params->cs_thres_in.hword);
142781 + config_opts.cm_config.cs_thres_x.hword =
142782 + cpu_to_be16(params->cs_thres_out.hword);
142783 + config_opts.cm_config.td_thres.hword =
142784 + cpu_to_be16(params->td_thres.hword);
142785 + config_opts.cm_config.wr_parm_g.word =
142786 + cpu_to_be32(params->wr_parm_g.word);
142787 + config_opts.cm_config.wr_parm_y.word =
142788 + cpu_to_be32(params->wr_parm_y.word);
142789 + config_opts.cm_config.wr_parm_r.word =
142790 + cpu_to_be32(params->wr_parm_r.word);
142791 +
142792 + ret = qman_ceetm_configure_ccgr(&config_opts);
142793 + if (ret) {
142794 + pr_err("Configure CSCN_TARG_DCP failed!\n");
142795 + return -EINVAL;
142796 + }
142797 + return 0;
142798 +}
142799 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
142800 +
142801 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
142802 + u16 dcp_idx,
142803 + u8 *vcgid,
142804 + unsigned int *cscn_enabled)
142805 +{
142806 + struct qm_mcc_ceetm_ccgr_query query_opts;
142807 + struct qm_mcr_ceetm_ccgr_query query_result;
142808 +
142809 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
142810 + (ccg->parent->idx << 4) | ccg->idx);
142811 + query_opts.dcpid = ccg->parent->dcp_idx;
142812 +
142813 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
142814 + pr_err("Can't query CCGR#%d\n", ccg->idx);
142815 + return -EINVAL;
142816 + }
142817 +
142818 + *vcgid = query_result.cm_query.cdv;
142819 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
142820 + return 0;
142821 +}
142822 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
142823 +
142824 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
142825 + unsigned int dcp_idx)
142826 +{
142827 + struct qm_mc_command *mcc;
142828 + struct qm_mc_result *mcr;
142829 + struct qman_portal *p;
142830 + unsigned long irqflags __maybe_unused;
142831 + u8 res;
142832 + int i, j;
142833 +
142834 + p = get_affine_portal();
142835 + PORTAL_IRQ_LOCK(p, irqflags);
142836 +
142837 + mcc = qm_mc_start(&p->p);
142838 + for (i = 0; i < 2; i++) {
142839 + mcc->ccgr_query.ccgrid =
142840 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
142841 + mcc->ccgr_query.dcpid = dcp_idx;
142842 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
142843 +
142844 + while (!(mcr = qm_mc_result(&p->p)))
142845 + cpu_relax();
142846 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142847 + QM_CEETM_VERB_CCGR_QUERY);
142848 + res = mcr->result;
142849 + if (res == QM_MCR_RESULT_OK) {
142850 + for (j = 0; j < 8; j++)
142851 + mcr->ccgr_query.congestion_state.state.
142852 + __state[j] = be32_to_cpu(mcr->ccgr_query.
142853 + congestion_state.state.__state[j]);
142854 + *(ccg_state + i) =
142855 + mcr->ccgr_query.congestion_state.state;
142856 + } else {
142857 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
142858 + PORTAL_IRQ_UNLOCK(p, irqflags);
142859 + return -EIO;
142860 + }
142861 + }
142862 + PORTAL_IRQ_UNLOCK(p, irqflags);
142863 + put_affine_portal();
142864 + return 0;
142865 +}
142866 +
142867 +int qman_set_wpm(int wpm_enable)
142868 +{
142869 + return qm_set_wpm(wpm_enable);
142870 +}
142871 +EXPORT_SYMBOL(qman_set_wpm);
142872 +
142873 +int qman_get_wpm(int *wpm_enable)
142874 +{
142875 + return qm_get_wpm(wpm_enable);
142876 +}
142877 +EXPORT_SYMBOL(qman_get_wpm);
142878 +
142879 +int qman_shutdown_fq(u32 fqid)
142880 +{
142881 + struct qman_portal *p;
142882 + unsigned long irqflags __maybe_unused;
142883 + int ret;
142884 + struct qm_portal *low_p;
142885 + p = get_affine_portal();
142886 + PORTAL_IRQ_LOCK(p, irqflags);
142887 + low_p = &p->p;
142888 + ret = qm_shutdown_fq(&low_p, 1, fqid);
142889 + PORTAL_IRQ_UNLOCK(p, irqflags);
142890 + put_affine_portal();
142891 + return ret;
142892 +}
142893 +
142894 +const struct qm_portal_config *qman_get_qm_portal_config(
142895 + struct qman_portal *portal)
142896 +{
142897 + return portal->sharing_redirect ? NULL : portal->config;
142898 +}
142899 --- /dev/null
142900 +++ b/drivers/staging/fsl_qbman/qman_low.h
142901 @@ -0,0 +1,1445 @@
142902 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
142903 + *
142904 + * Redistribution and use in source and binary forms, with or without
142905 + * modification, are permitted provided that the following conditions are met:
142906 + * * Redistributions of source code must retain the above copyright
142907 + * notice, this list of conditions and the following disclaimer.
142908 + * * Redistributions in binary form must reproduce the above copyright
142909 + * notice, this list of conditions and the following disclaimer in the
142910 + * documentation and/or other materials provided with the distribution.
142911 + * * Neither the name of Freescale Semiconductor nor the
142912 + * names of its contributors may be used to endorse or promote products
142913 + * derived from this software without specific prior written permission.
142914 + *
142915 + *
142916 + * ALTERNATIVELY, this software may be distributed under the terms of the
142917 + * GNU General Public License ("GPL") as published by the Free Software
142918 + * Foundation, either version 2 of that License or (at your option) any
142919 + * later version.
142920 + *
142921 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
142922 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
142923 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
142924 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
142925 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
142926 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
142927 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
142928 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142929 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
142930 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142931 + */
142932 +
142933 +#include "qman_private.h"
142934 +
142935 +/***************************/
142936 +/* Portal register assists */
142937 +/***************************/
142938 +
142939 +/* Cache-inhibited register offsets */
142940 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142941 +
142942 +#define QM_REG_EQCR_PI_CINH 0x0000
142943 +#define QM_REG_EQCR_CI_CINH 0x0004
142944 +#define QM_REG_EQCR_ITR 0x0008
142945 +#define QM_REG_DQRR_PI_CINH 0x0040
142946 +#define QM_REG_DQRR_CI_CINH 0x0044
142947 +#define QM_REG_DQRR_ITR 0x0048
142948 +#define QM_REG_DQRR_DCAP 0x0050
142949 +#define QM_REG_DQRR_SDQCR 0x0054
142950 +#define QM_REG_DQRR_VDQCR 0x0058
142951 +#define QM_REG_DQRR_PDQCR 0x005c
142952 +#define QM_REG_MR_PI_CINH 0x0080
142953 +#define QM_REG_MR_CI_CINH 0x0084
142954 +#define QM_REG_MR_ITR 0x0088
142955 +#define QM_REG_CFG 0x0100
142956 +#define QM_REG_ISR 0x0e00
142957 +#define QM_REG_IIR 0x0e0c
142958 +#define QM_REG_ITPR 0x0e14
142959 +
142960 +/* Cache-enabled register offsets */
142961 +#define QM_CL_EQCR 0x0000
142962 +#define QM_CL_DQRR 0x1000
142963 +#define QM_CL_MR 0x2000
142964 +#define QM_CL_EQCR_PI_CENA 0x3000
142965 +#define QM_CL_EQCR_CI_CENA 0x3100
142966 +#define QM_CL_DQRR_PI_CENA 0x3200
142967 +#define QM_CL_DQRR_CI_CENA 0x3300
142968 +#define QM_CL_MR_PI_CENA 0x3400
142969 +#define QM_CL_MR_CI_CENA 0x3500
142970 +#define QM_CL_CR 0x3800
142971 +#define QM_CL_RR0 0x3900
142972 +#define QM_CL_RR1 0x3940
142973 +
142974 +#endif
142975 +
142976 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142977 +
142978 +#define QM_REG_EQCR_PI_CINH 0x3000
142979 +#define QM_REG_EQCR_CI_CINH 0x3040
142980 +#define QM_REG_EQCR_ITR 0x3080
142981 +#define QM_REG_DQRR_PI_CINH 0x3100
142982 +#define QM_REG_DQRR_CI_CINH 0x3140
142983 +#define QM_REG_DQRR_ITR 0x3180
142984 +#define QM_REG_DQRR_DCAP 0x31C0
142985 +#define QM_REG_DQRR_SDQCR 0x3200
142986 +#define QM_REG_DQRR_VDQCR 0x3240
142987 +#define QM_REG_DQRR_PDQCR 0x3280
142988 +#define QM_REG_MR_PI_CINH 0x3300
142989 +#define QM_REG_MR_CI_CINH 0x3340
142990 +#define QM_REG_MR_ITR 0x3380
142991 +#define QM_REG_CFG 0x3500
142992 +#define QM_REG_ISR 0x3600
142993 +#define QM_REG_IIR 0x36C0
142994 +#define QM_REG_ITPR 0x3740
142995 +
142996 +/* Cache-enabled register offsets */
142997 +#define QM_CL_EQCR 0x0000
142998 +#define QM_CL_DQRR 0x1000
142999 +#define QM_CL_MR 0x2000
143000 +#define QM_CL_EQCR_PI_CENA 0x3000
143001 +#define QM_CL_EQCR_CI_CENA 0x3040
143002 +#define QM_CL_DQRR_PI_CENA 0x3100
143003 +#define QM_CL_DQRR_CI_CENA 0x3140
143004 +#define QM_CL_MR_PI_CENA 0x3300
143005 +#define QM_CL_MR_CI_CENA 0x3340
143006 +#define QM_CL_CR 0x3800
143007 +#define QM_CL_RR0 0x3900
143008 +#define QM_CL_RR1 0x3940
143009 +
143010 +#endif
143011 +
143012 +
143013 +/* BTW, the drivers (and h/w programming model) already obtain the required
143014 + * synchronisation for portal accesses via lwsync(), hwsync(), and
143015 + * data-dependencies. Use of barrier()s or other order-preserving primitives
143016 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
143017 + * simply ensure that the compiler treats the portal registers as volatile (ie.
143018 + * non-coherent). */
143019 +
143020 +/* Cache-inhibited register access. */
143021 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
143022 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
143023 + (qm)->addr_ci + (o));
143024 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
143025 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
143026 +
143027 +/* Cache-enabled (index) register access */
143028 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
143029 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
143030 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
143031 +#define __qm_cl_out(qm, o, val) \
143032 + do { \
143033 + u32 *__tmpclout = (qm)->addr_ce + (o); \
143034 + __raw_writel(cpu_to_be32(val), __tmpclout); \
143035 + dcbf(__tmpclout); \
143036 + } while (0)
143037 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
143038 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
143039 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
143040 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
143041 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
143042 +#define qm_cl_invalidate(reg)\
143043 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
143044 +
143045 +/* Cache-enabled ring access */
143046 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
143047 +
143048 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
143049 + * analysis, look at using the "extra" bit in the ring index registers to avoid
143050 + * cyclic issues. */
143051 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
143052 +{
143053 + /* 'first' is included, 'last' is excluded */
143054 + if (first <= last)
143055 + return last - first;
143056 + return ringsize + last - first;
143057 +}
143058 +
143059 +/* Portal modes.
143060 + * Enum types;
143061 + * pmode == production mode
143062 + * cmode == consumption mode,
143063 + * dmode == h/w dequeue mode.
143064 + * Enum values use 3 letter codes. First letter matches the portal mode,
143065 + * remaining two letters indicate;
143066 + * ci == cache-inhibited portal register
143067 + * ce == cache-enabled portal register
143068 + * vb == in-band valid-bit (cache-enabled)
143069 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
143070 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
143071 + */
143072 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
143073 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
143074 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
143075 + qm_eqcr_pvb = 2 /* valid-bit */
143076 +};
143077 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
143078 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
143079 + qm_dqrr_dpull = 1 /* PDQCR */
143080 +};
143081 +enum qm_dqrr_pmode { /* s/w-only */
143082 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
143083 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
143084 + qm_dqrr_pvb /* reads valid-bit */
143085 +};
143086 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
143087 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
143088 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
143089 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
143090 +};
143091 +enum qm_mr_pmode { /* s/w-only */
143092 + qm_mr_pci, /* reads MR_PI_CINH */
143093 + qm_mr_pce, /* reads MR_PI_CENA */
143094 + qm_mr_pvb /* reads valid-bit */
143095 +};
143096 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
143097 + qm_mr_cci = 0, /* CI index, cache-inhibited */
143098 + qm_mr_cce = 1 /* CI index, cache-enabled */
143099 +};
143100 +
143101 +
143102 +/* ------------------------- */
143103 +/* --- Portal structures --- */
143104 +
143105 +#define QM_EQCR_SIZE 8
143106 +#define QM_DQRR_SIZE 16
143107 +#define QM_MR_SIZE 8
143108 +
143109 +struct qm_eqcr {
143110 + struct qm_eqcr_entry *ring, *cursor;
143111 + u8 ci, available, ithresh, vbit;
143112 +#ifdef CONFIG_FSL_DPA_CHECKING
143113 + u32 busy;
143114 + enum qm_eqcr_pmode pmode;
143115 +#endif
143116 +};
143117 +
143118 +struct qm_dqrr {
143119 + const struct qm_dqrr_entry *ring, *cursor;
143120 + u8 pi, ci, fill, ithresh, vbit;
143121 +#ifdef CONFIG_FSL_DPA_CHECKING
143122 + enum qm_dqrr_dmode dmode;
143123 + enum qm_dqrr_pmode pmode;
143124 + enum qm_dqrr_cmode cmode;
143125 +#endif
143126 +};
143127 +
143128 +struct qm_mr {
143129 + const struct qm_mr_entry *ring, *cursor;
143130 + u8 pi, ci, fill, ithresh, vbit;
143131 +#ifdef CONFIG_FSL_DPA_CHECKING
143132 + enum qm_mr_pmode pmode;
143133 + enum qm_mr_cmode cmode;
143134 +#endif
143135 +};
143136 +
143137 +struct qm_mc {
143138 + struct qm_mc_command *cr;
143139 + struct qm_mc_result *rr;
143140 + u8 rridx, vbit;
143141 +#ifdef CONFIG_FSL_DPA_CHECKING
143142 + enum {
143143 + /* Can be _mc_start()ed */
143144 + qman_mc_idle,
143145 + /* Can be _mc_commit()ed or _mc_abort()ed */
143146 + qman_mc_user,
143147 + /* Can only be _mc_retry()ed */
143148 + qman_mc_hw
143149 + } state;
143150 +#endif
143151 +};
143152 +
143153 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
143154 +
143155 +struct qm_addr {
143156 + void __iomem *addr_ce; /* cache-enabled */
143157 + void __iomem *addr_ci; /* cache-inhibited */
143158 +};
143159 +
143160 +struct qm_portal {
143161 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
143162 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
143163 + * is setup-only, so isn't a cause for a concern. In other words, don't
143164 + * rearrange this structure on a whim, there be dragons ... */
143165 + struct qm_addr addr;
143166 + struct qm_eqcr eqcr;
143167 + struct qm_dqrr dqrr;
143168 + struct qm_mr mr;
143169 + struct qm_mc mc;
143170 +} QM_PORTAL_ALIGNMENT;
143171 +
143172 +
143173 +/* ---------------- */
143174 +/* --- EQCR API --- */
143175 +
143176 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
143177 +#define EQCR_CARRYCLEAR(p) \
143178 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
143179 +
143180 +/* Bit-wise logic to convert a ring pointer to a ring index */
143181 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
143182 +{
143183 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
143184 +}
143185 +
143186 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
143187 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
143188 +{
143189 + /* NB: this is odd-looking, but experiments show that it generates fast
143190 + * code with essentially no branching overheads. We increment to the
143191 + * next EQCR pointer and handle overflow and 'vbit'. */
143192 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
143193 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
143194 + if (partial != eqcr->cursor)
143195 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
143196 +}
143197 +
143198 +static inline int qm_eqcr_init(struct qm_portal *portal,
143199 + enum qm_eqcr_pmode pmode,
143200 + unsigned int eq_stash_thresh,
143201 + int eq_stash_prio)
143202 +{
143203 + /* This use of 'register', as well as all other occurrences, is because
143204 + * it has been observed to generate much faster code with gcc than is
143205 + * otherwise the case. */
143206 + register struct qm_eqcr *eqcr = &portal->eqcr;
143207 + u32 cfg;
143208 + u8 pi;
143209 +
143210 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
143211 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
143212 + qm_cl_invalidate(EQCR_CI);
143213 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
143214 + eqcr->cursor = eqcr->ring + pi;
143215 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
143216 + QM_EQCR_VERB_VBIT : 0;
143217 + eqcr->available = QM_EQCR_SIZE - 1 -
143218 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
143219 + eqcr->ithresh = qm_in(EQCR_ITR);
143220 +#ifdef CONFIG_FSL_DPA_CHECKING
143221 + eqcr->busy = 0;
143222 + eqcr->pmode = pmode;
143223 +#endif
143224 + cfg = (qm_in(CFG) & 0x00ffffff) |
143225 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
143226 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
143227 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
143228 + qm_out(CFG, cfg);
143229 + return 0;
143230 +}
143231 +
143232 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
143233 +{
143234 + return (qm_in(CFG) >> 28) & 0x7;
143235 +}
143236 +
143237 +static inline void qm_eqcr_finish(struct qm_portal *portal)
143238 +{
143239 + register struct qm_eqcr *eqcr = &portal->eqcr;
143240 + u8 pi, ci;
143241 + u32 cfg;
143242 +
143243 + /*
143244 + * Disable EQCI stashing because the QMan only
143245 + * presents the value it previously stashed to
143246 + * maintain coherency. Setting the stash threshold
143247 + * to 1 then 0 ensures that QMan has resyncronized
143248 + * its internal copy so that the portal is clean
143249 + * when it is reinitialized in the future
143250 + */
143251 + cfg = (qm_in(CFG) & 0x0fffffff) |
143252 + (1 << 28); /* QCSP_CFG: EST */
143253 + qm_out(CFG, cfg);
143254 + cfg &= 0x0fffffff; /* stash threshold = 0 */
143255 + qm_out(CFG, cfg);
143256 +
143257 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
143258 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
143259 +
143260 + /* Refresh EQCR CI cache value */
143261 + qm_cl_invalidate(EQCR_CI);
143262 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
143263 +
143264 + DPA_ASSERT(!eqcr->busy);
143265 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
143266 + pr_crit("losing uncommited EQCR entries\n");
143267 + if (ci != eqcr->ci)
143268 + pr_crit("missing existing EQCR completions\n");
143269 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
143270 + pr_crit("EQCR destroyed unquiesced\n");
143271 +}
143272 +
143273 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
143274 + *portal)
143275 +{
143276 + register struct qm_eqcr *eqcr = &portal->eqcr;
143277 + DPA_ASSERT(!eqcr->busy);
143278 + if (!eqcr->available)
143279 + return NULL;
143280 +
143281 +
143282 +#ifdef CONFIG_FSL_DPA_CHECKING
143283 + eqcr->busy = 1;
143284 +#endif
143285 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143286 + dcbz_64(eqcr->cursor);
143287 +#endif
143288 + return eqcr->cursor;
143289 +}
143290 +
143291 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
143292 + *portal)
143293 +{
143294 + register struct qm_eqcr *eqcr = &portal->eqcr;
143295 + u8 diff, old_ci;
143296 +
143297 + DPA_ASSERT(!eqcr->busy);
143298 + if (!eqcr->available) {
143299 + old_ci = eqcr->ci;
143300 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
143301 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
143302 + eqcr->available += diff;
143303 + if (!diff)
143304 + return NULL;
143305 + }
143306 +#ifdef CONFIG_FSL_DPA_CHECKING
143307 + eqcr->busy = 1;
143308 +#endif
143309 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143310 + dcbz_64(eqcr->cursor);
143311 +#endif
143312 + return eqcr->cursor;
143313 +}
143314 +
143315 +static inline void qm_eqcr_abort(struct qm_portal *portal)
143316 +{
143317 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
143318 + DPA_ASSERT(eqcr->busy);
143319 +#ifdef CONFIG_FSL_DPA_CHECKING
143320 + eqcr->busy = 0;
143321 +#endif
143322 +}
143323 +
143324 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
143325 + struct qm_portal *portal, u8 myverb)
143326 +{
143327 + register struct qm_eqcr *eqcr = &portal->eqcr;
143328 + DPA_ASSERT(eqcr->busy);
143329 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
143330 + if (eqcr->available == 1)
143331 + return NULL;
143332 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143333 + dcbf(eqcr->cursor);
143334 + EQCR_INC(eqcr);
143335 + eqcr->available--;
143336 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143337 + dcbz_64(eqcr->cursor);
143338 +#endif
143339 + return eqcr->cursor;
143340 +}
143341 +
143342 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
143343 +#define EQCR_COMMIT_CHECKS(eqcr) \
143344 +do { \
143345 + DPA_ASSERT(eqcr->busy); \
143346 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
143347 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
143348 +} while (0)
143349 +#else
143350 +#define EQCR_COMMIT_CHECKS(eqcr) \
143351 +do { \
143352 + DPA_ASSERT(eqcr->busy); \
143353 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
143354 + cpu_to_be32(0x00ffffff))); \
143355 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
143356 + cpu_to_be32(0x00ffffff))); \
143357 +} while (0)
143358 +#endif
143359 +
143360 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
143361 +{
143362 + register struct qm_eqcr *eqcr = &portal->eqcr;
143363 + EQCR_COMMIT_CHECKS(eqcr);
143364 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
143365 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143366 + EQCR_INC(eqcr);
143367 + eqcr->available--;
143368 + dcbf(eqcr->cursor);
143369 + hwsync();
143370 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
143371 +#ifdef CONFIG_FSL_DPA_CHECKING
143372 + eqcr->busy = 0;
143373 +#endif
143374 +}
143375 +
143376 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
143377 +{
143378 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
143379 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
143380 + qm_cl_invalidate(EQCR_PI);
143381 + qm_cl_touch_rw(EQCR_PI);
143382 +}
143383 +
143384 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
143385 +{
143386 + register struct qm_eqcr *eqcr = &portal->eqcr;
143387 + EQCR_COMMIT_CHECKS(eqcr);
143388 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
143389 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143390 + EQCR_INC(eqcr);
143391 + eqcr->available--;
143392 + dcbf(eqcr->cursor);
143393 + lwsync();
143394 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
143395 +#ifdef CONFIG_FSL_DPA_CHECKING
143396 + eqcr->busy = 0;
143397 +#endif
143398 +}
143399 +
143400 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
143401 +{
143402 + register struct qm_eqcr *eqcr = &portal->eqcr;
143403 + struct qm_eqcr_entry *eqcursor;
143404 + EQCR_COMMIT_CHECKS(eqcr);
143405 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
143406 + lwsync();
143407 + eqcursor = eqcr->cursor;
143408 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143409 + dcbf(eqcursor);
143410 + EQCR_INC(eqcr);
143411 + eqcr->available--;
143412 +#ifdef CONFIG_FSL_DPA_CHECKING
143413 + eqcr->busy = 0;
143414 +#endif
143415 +}
143416 +
143417 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
143418 +{
143419 + register struct qm_eqcr *eqcr = &portal->eqcr;
143420 + u8 diff, old_ci = eqcr->ci;
143421 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
143422 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
143423 + eqcr->available += diff;
143424 + return diff;
143425 +}
143426 +
143427 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
143428 +{
143429 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
143430 + qm_cl_touch_ro(EQCR_CI);
143431 +}
143432 +
143433 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
143434 +{
143435 + register struct qm_eqcr *eqcr = &portal->eqcr;
143436 + u8 diff, old_ci = eqcr->ci;
143437 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
143438 + qm_cl_invalidate(EQCR_CI);
143439 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
143440 + eqcr->available += diff;
143441 + return diff;
143442 +}
143443 +
143444 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
143445 +{
143446 + register struct qm_eqcr *eqcr = &portal->eqcr;
143447 + return eqcr->ithresh;
143448 +}
143449 +
143450 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
143451 +{
143452 + register struct qm_eqcr *eqcr = &portal->eqcr;
143453 + eqcr->ithresh = ithresh;
143454 + qm_out(EQCR_ITR, ithresh);
143455 +}
143456 +
143457 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
143458 +{
143459 + register struct qm_eqcr *eqcr = &portal->eqcr;
143460 + return eqcr->available;
143461 +}
143462 +
143463 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
143464 +{
143465 + register struct qm_eqcr *eqcr = &portal->eqcr;
143466 + return QM_EQCR_SIZE - 1 - eqcr->available;
143467 +}
143468 +
143469 +
143470 +/* ---------------- */
143471 +/* --- DQRR API --- */
143472 +
143473 +/* FIXME: many possible improvements;
143474 + * - look at changing the API to use pointer rather than index parameters now
143475 + * that 'cursor' is a pointer,
143476 + * - consider moving other parameters to pointer if it could help (ci)
143477 + */
143478 +
143479 +#define DQRR_CARRYCLEAR(p) \
143480 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
143481 +
143482 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
143483 +{
143484 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
143485 +}
143486 +
143487 +static inline const struct qm_dqrr_entry *DQRR_INC(
143488 + const struct qm_dqrr_entry *e)
143489 +{
143490 + return DQRR_CARRYCLEAR(e + 1);
143491 +}
143492 +
143493 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
143494 +{
143495 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
143496 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
143497 +}
143498 +
143499 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
143500 +{
143501 + register struct qm_dqrr *dqrr = &portal->dqrr;
143502 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
143503 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
143504 + qm_out(DQRR_CI_CINH, dqrr->ci);
143505 +}
143506 +
143507 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
143508 +{
143509 + register struct qm_dqrr *dqrr = &portal->dqrr;
143510 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
143511 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
143512 + qm_cl_out(DQRR_CI, dqrr->ci);
143513 +}
143514 +
143515 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
143516 +{
143517 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143518 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143519 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
143520 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
143521 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
143522 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
143523 +}
143524 +
143525 +static inline int qm_dqrr_init(struct qm_portal *portal,
143526 + const struct qm_portal_config *config,
143527 + enum qm_dqrr_dmode dmode,
143528 + __maybe_unused enum qm_dqrr_pmode pmode,
143529 + enum qm_dqrr_cmode cmode, u8 max_fill)
143530 +{
143531 + register struct qm_dqrr *dqrr = &portal->dqrr;
143532 + u32 cfg;
143533 +
143534 + /* Make sure the DQRR will be idle when we enable */
143535 + qm_out(DQRR_SDQCR, 0);
143536 + qm_out(DQRR_VDQCR, 0);
143537 + qm_out(DQRR_PDQCR, 0);
143538 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
143539 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
143540 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
143541 + dqrr->cursor = dqrr->ring + dqrr->ci;
143542 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
143543 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
143544 + QM_DQRR_VERB_VBIT : 0;
143545 + dqrr->ithresh = qm_in(DQRR_ITR);
143546 +
143547 + /* Free up pending DQRR entries if any as per current DCM */
143548 + if (dqrr->fill) {
143549 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
143550 +
143551 +#ifdef CONFIG_FSL_DPA_CHECKING
143552 + dqrr->cmode = dcm;
143553 +#endif
143554 + switch (dcm) {
143555 + case qm_dqrr_cci:
143556 + qm_dqrr_cci_consume(portal, dqrr->fill);
143557 + break;
143558 + case qm_dqrr_cce:
143559 + qm_dqrr_cce_consume(portal, dqrr->fill);
143560 + break;
143561 + case qm_dqrr_cdc:
143562 + qm_dqrr_cdc_consume_n(portal, (1<<QM_DQRR_SIZE) - 1);
143563 + break;
143564 + default:
143565 + DPA_ASSERT(0);
143566 + }
143567 + }
143568 +
143569 +#ifdef CONFIG_FSL_DPA_CHECKING
143570 + dqrr->dmode = dmode;
143571 + dqrr->pmode = pmode;
143572 + dqrr->cmode = cmode;
143573 +#endif
143574 + /* Invalidate every ring entry before beginning */
143575 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
143576 + dcbi(qm_cl(dqrr->ring, cfg));
143577 + cfg = (qm_in(CFG) & 0xff000f00) |
143578 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
143579 + ((dmode & 1) << 18) | /* DP */
143580 + ((cmode & 3) << 16) | /* DCM */
143581 + 0xa0 | /* RE+SE */
143582 + (0 ? 0x40 : 0) | /* Ignore RP */
143583 + (0 ? 0x10 : 0); /* Ignore SP */
143584 + qm_out(CFG, cfg);
143585 + qm_dqrr_set_maxfill(portal, max_fill);
143586 +
143587 + /* Recalculate cursor as we may have consumed frames */
143588 + dqrr->cursor = dqrr->ring + dqrr->ci;
143589 + return 0;
143590 +}
143591 +
143592 +static inline void qm_dqrr_finish(struct qm_portal *portal)
143593 +{
143594 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143595 +#ifdef CONFIG_FSL_DPA_CHECKING
143596 + if ((dqrr->cmode != qm_dqrr_cdc) &&
143597 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
143598 + pr_crit("Ignoring completed DQRR entries\n");
143599 +#endif
143600 +}
143601 +
143602 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
143603 + struct qm_portal *portal)
143604 +{
143605 + register struct qm_dqrr *dqrr = &portal->dqrr;
143606 + if (!dqrr->fill)
143607 + return NULL;
143608 + return dqrr->cursor;
143609 +}
143610 +
143611 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
143612 +{
143613 + register struct qm_dqrr *dqrr = &portal->dqrr;
143614 + return DQRR_PTR2IDX(dqrr->cursor);
143615 +}
143616 +
143617 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
143618 +{
143619 + register struct qm_dqrr *dqrr = &portal->dqrr;
143620 + DPA_ASSERT(dqrr->fill);
143621 + dqrr->cursor = DQRR_INC(dqrr->cursor);
143622 + return --dqrr->fill;
143623 +}
143624 +
143625 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
143626 +{
143627 + register struct qm_dqrr *dqrr = &portal->dqrr;
143628 + u8 diff, old_pi = dqrr->pi;
143629 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
143630 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
143631 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
143632 + dqrr->fill += diff;
143633 + return diff;
143634 +}
143635 +
143636 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
143637 +{
143638 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143639 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
143640 + qm_cl_invalidate(DQRR_PI);
143641 + qm_cl_touch_ro(DQRR_PI);
143642 +}
143643 +
143644 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
143645 +{
143646 + register struct qm_dqrr *dqrr = &portal->dqrr;
143647 + u8 diff, old_pi = dqrr->pi;
143648 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
143649 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
143650 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
143651 + dqrr->fill += diff;
143652 + return diff;
143653 +}
143654 +
143655 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
143656 +{
143657 + register struct qm_dqrr *dqrr = &portal->dqrr;
143658 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
143659 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
143660 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
143661 + /*
143662 + * On PowerPC platforms if PAMU is not available we need to
143663 + * manually invalidate the cache. When PAMU is available the
143664 + * cache is updated by stashing operations generated by QMan
143665 + */
143666 + dcbi(res);
143667 + dcbt_ro(res);
143668 +#endif
143669 +
143670 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
143671 + * inlining doesn't try to optimise out "excess reads". */
143672 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
143673 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
143674 + if (!dqrr->pi)
143675 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
143676 + dqrr->fill++;
143677 + }
143678 +}
143679 +
143680 +
143681 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
143682 +{
143683 + register struct qm_dqrr *dqrr = &portal->dqrr;
143684 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
143685 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
143686 + qm_out(DQRR_CI_CINH, dqrr->ci);
143687 +}
143688 +
143689 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
143690 +{
143691 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143692 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
143693 + qm_cl_invalidate(DQRR_CI);
143694 + qm_cl_touch_rw(DQRR_CI);
143695 +}
143696 +
143697 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
143698 +{
143699 + register struct qm_dqrr *dqrr = &portal->dqrr;
143700 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
143701 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
143702 + qm_cl_out(DQRR_CI, dqrr->ci);
143703 +}
143704 +
143705 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
143706 + int park)
143707 +{
143708 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143709 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143710 + DPA_ASSERT(idx < QM_DQRR_SIZE);
143711 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
143712 + ((park ? 1 : 0) << 6) | /* PK */
143713 + idx); /* DCAP_CI */
143714 +}
143715 +
143716 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
143717 + const struct qm_dqrr_entry *dq,
143718 + int park)
143719 +{
143720 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143721 + u8 idx = DQRR_PTR2IDX(dq);
143722 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143723 + DPA_ASSERT((dqrr->ring + idx) == dq);
143724 + DPA_ASSERT(idx < QM_DQRR_SIZE);
143725 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
143726 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
143727 + idx); /* DQRR_DCAP::DCAP_CI */
143728 +}
143729 +
143730 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
143731 +{
143732 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143733 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143734 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
143735 +}
143736 +
143737 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
143738 +{
143739 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143740 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143741 + qm_cl_invalidate(DQRR_CI);
143742 + qm_cl_touch_ro(DQRR_CI);
143743 +}
143744 +
143745 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
143746 +{
143747 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143748 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143749 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
143750 +}
143751 +
143752 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
143753 +{
143754 + register struct qm_dqrr *dqrr = &portal->dqrr;
143755 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
143756 + return dqrr->ci;
143757 +}
143758 +
143759 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
143760 +{
143761 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143762 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
143763 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
143764 + (1 << 6) | /* PK */
143765 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
143766 +}
143767 +
143768 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
143769 +{
143770 + register struct qm_dqrr *dqrr = &portal->dqrr;
143771 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
143772 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
143773 + (1 << 6) | /* PK */
143774 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
143775 +}
143776 +
143777 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
143778 +{
143779 + qm_out(DQRR_SDQCR, sdqcr);
143780 +}
143781 +
143782 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
143783 +{
143784 + return qm_in(DQRR_SDQCR);
143785 +}
143786 +
143787 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
143788 +{
143789 + qm_out(DQRR_VDQCR, vdqcr);
143790 +}
143791 +
143792 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
143793 +{
143794 + return qm_in(DQRR_VDQCR);
143795 +}
143796 +
143797 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
143798 +{
143799 + qm_out(DQRR_PDQCR, pdqcr);
143800 +}
143801 +
143802 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
143803 +{
143804 + return qm_in(DQRR_PDQCR);
143805 +}
143806 +
143807 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
143808 +{
143809 + register struct qm_dqrr *dqrr = &portal->dqrr;
143810 + return dqrr->ithresh;
143811 +}
143812 +
143813 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
143814 +{
143815 + qm_out(DQRR_ITR, ithresh);
143816 +}
143817 +
143818 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
143819 +{
143820 + return (qm_in(CFG) & 0x00f00000) >> 20;
143821 +}
143822 +
143823 +
143824 +/* -------------- */
143825 +/* --- MR API --- */
143826 +
143827 +#define MR_CARRYCLEAR(p) \
143828 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
143829 +
143830 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
143831 +{
143832 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
143833 +}
143834 +
143835 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
143836 +{
143837 + return MR_CARRYCLEAR(e + 1);
143838 +}
143839 +
143840 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
143841 + enum qm_mr_cmode cmode)
143842 +{
143843 + register struct qm_mr *mr = &portal->mr;
143844 + u32 cfg;
143845 +
143846 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
143847 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
143848 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
143849 + mr->cursor = mr->ring + mr->ci;
143850 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
143851 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
143852 + mr->ithresh = qm_in(MR_ITR);
143853 +#ifdef CONFIG_FSL_DPA_CHECKING
143854 + mr->pmode = pmode;
143855 + mr->cmode = cmode;
143856 +#endif
143857 + cfg = (qm_in(CFG) & 0xfffff0ff) |
143858 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
143859 + qm_out(CFG, cfg);
143860 + return 0;
143861 +}
143862 +
143863 +static inline void qm_mr_finish(struct qm_portal *portal)
143864 +{
143865 + register struct qm_mr *mr = &portal->mr;
143866 + if (mr->ci != MR_PTR2IDX(mr->cursor))
143867 + pr_crit("Ignoring completed MR entries\n");
143868 +}
143869 +
143870 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
143871 +{
143872 + register struct qm_mr *mr = &portal->mr;
143873 + if (!mr->fill)
143874 + return NULL;
143875 + return mr->cursor;
143876 +}
143877 +
143878 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
143879 +{
143880 + register struct qm_mr *mr = &portal->mr;
143881 + return MR_PTR2IDX(mr->cursor);
143882 +}
143883 +
143884 +static inline u8 qm_mr_next(struct qm_portal *portal)
143885 +{
143886 + register struct qm_mr *mr = &portal->mr;
143887 + DPA_ASSERT(mr->fill);
143888 + mr->cursor = MR_INC(mr->cursor);
143889 + return --mr->fill;
143890 +}
143891 +
143892 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
143893 +{
143894 + register struct qm_mr *mr = &portal->mr;
143895 + u8 diff, old_pi = mr->pi;
143896 + DPA_ASSERT(mr->pmode == qm_mr_pci);
143897 + mr->pi = qm_in(MR_PI_CINH);
143898 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
143899 + mr->fill += diff;
143900 + return diff;
143901 +}
143902 +
143903 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
143904 +{
143905 + __maybe_unused register struct qm_mr *mr = &portal->mr;
143906 + DPA_ASSERT(mr->pmode == qm_mr_pce);
143907 + qm_cl_invalidate(MR_PI);
143908 + qm_cl_touch_ro(MR_PI);
143909 +}
143910 +
143911 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
143912 +{
143913 + register struct qm_mr *mr = &portal->mr;
143914 + u8 diff, old_pi = mr->pi;
143915 + DPA_ASSERT(mr->pmode == qm_mr_pce);
143916 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
143917 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
143918 + mr->fill += diff;
143919 + return diff;
143920 +}
143921 +
143922 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
143923 +{
143924 + register struct qm_mr *mr = &portal->mr;
143925 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
143926 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
143927 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
143928 + * inlining doesn't try to optimise out "excess reads". */
143929 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
143930 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
143931 + if (!mr->pi)
143932 + mr->vbit ^= QM_MR_VERB_VBIT;
143933 + mr->fill++;
143934 + res = MR_INC(res);
143935 + }
143936 + dcbit_ro(res);
143937 +}
143938 +
143939 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
143940 +{
143941 + register struct qm_mr *mr = &portal->mr;
143942 + DPA_ASSERT(mr->cmode == qm_mr_cci);
143943 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
143944 + qm_out(MR_CI_CINH, mr->ci);
143945 +}
143946 +
143947 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
143948 +{
143949 + register struct qm_mr *mr = &portal->mr;
143950 + DPA_ASSERT(mr->cmode == qm_mr_cci);
143951 + mr->ci = MR_PTR2IDX(mr->cursor);
143952 + qm_out(MR_CI_CINH, mr->ci);
143953 +}
143954 +
143955 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
143956 +{
143957 + __maybe_unused register struct qm_mr *mr = &portal->mr;
143958 + DPA_ASSERT(mr->cmode == qm_mr_cce);
143959 + qm_cl_invalidate(MR_CI);
143960 + qm_cl_touch_rw(MR_CI);
143961 +}
143962 +
143963 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
143964 +{
143965 + register struct qm_mr *mr = &portal->mr;
143966 + DPA_ASSERT(mr->cmode == qm_mr_cce);
143967 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
143968 + qm_cl_out(MR_CI, mr->ci);
143969 +}
143970 +
143971 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
143972 +{
143973 + register struct qm_mr *mr = &portal->mr;
143974 + DPA_ASSERT(mr->cmode == qm_mr_cce);
143975 + mr->ci = MR_PTR2IDX(mr->cursor);
143976 + qm_cl_out(MR_CI, mr->ci);
143977 +}
143978 +
143979 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
143980 +{
143981 + register struct qm_mr *mr = &portal->mr;
143982 + return mr->ci;
143983 +}
143984 +
143985 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
143986 +{
143987 + register struct qm_mr *mr = &portal->mr;
143988 + return mr->ithresh;
143989 +}
143990 +
143991 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
143992 +{
143993 + qm_out(MR_ITR, ithresh);
143994 +}
143995 +
143996 +
143997 +/* ------------------------------ */
143998 +/* --- Management command API --- */
143999 +
144000 +static inline int qm_mc_init(struct qm_portal *portal)
144001 +{
144002 + u8 rr0, rr1;
144003 + register struct qm_mc *mc = &portal->mc;
144004 +
144005 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
144006 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
144007 +
144008 + /*
144009 + * The expected valid bit polarity for the next CR command is 0
144010 + * if RR1 contains a valid response, and is 1 if RR0 contains a
144011 + * valid response. If both RR contain all 0, this indicates either
144012 + * that no command has been executed since reset (in which case the
144013 + * expected valid bit polarity is 1)
144014 + */
144015 + rr0 = __raw_readb(&mc->rr->verb);
144016 + rr1 = __raw_readb(&(mc->rr+1)->verb);
144017 + if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
144018 + mc->rridx = 1;
144019 + else
144020 + mc->rridx = 0;
144021 +
144022 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
144023 +#ifdef CONFIG_FSL_DPA_CHECKING
144024 + mc->state = qman_mc_idle;
144025 +#endif
144026 + return 0;
144027 +}
144028 +
144029 +static inline void qm_mc_finish(struct qm_portal *portal)
144030 +{
144031 + __maybe_unused register struct qm_mc *mc = &portal->mc;
144032 + DPA_ASSERT(mc->state == qman_mc_idle);
144033 +#ifdef CONFIG_FSL_DPA_CHECKING
144034 + if (mc->state != qman_mc_idle)
144035 + pr_crit("Losing incomplete MC command\n");
144036 +#endif
144037 +}
144038 +
144039 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
144040 +{
144041 + register struct qm_mc *mc = &portal->mc;
144042 + DPA_ASSERT(mc->state == qman_mc_idle);
144043 +#ifdef CONFIG_FSL_DPA_CHECKING
144044 + mc->state = qman_mc_user;
144045 +#endif
144046 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
144047 + dcbz_64(mc->cr);
144048 +#endif
144049 + return mc->cr;
144050 +}
144051 +
144052 +static inline void qm_mc_abort(struct qm_portal *portal)
144053 +{
144054 + __maybe_unused register struct qm_mc *mc = &portal->mc;
144055 + DPA_ASSERT(mc->state == qman_mc_user);
144056 +#ifdef CONFIG_FSL_DPA_CHECKING
144057 + mc->state = qman_mc_idle;
144058 +#endif
144059 +}
144060 +
144061 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
144062 +{
144063 + register struct qm_mc *mc = &portal->mc;
144064 + struct qm_mc_result *rr = mc->rr + mc->rridx;
144065 + DPA_ASSERT(mc->state == qman_mc_user);
144066 + lwsync();
144067 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
144068 + dcbf(mc->cr);
144069 + dcbit_ro(rr);
144070 +#ifdef CONFIG_FSL_DPA_CHECKING
144071 + mc->state = qman_mc_hw;
144072 +#endif
144073 +}
144074 +
144075 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
144076 +{
144077 + register struct qm_mc *mc = &portal->mc;
144078 + struct qm_mc_result *rr = mc->rr + mc->rridx;
144079 + DPA_ASSERT(mc->state == qman_mc_hw);
144080 + /* The inactive response register's verb byte always returns zero until
144081 + * its command is submitted and completed. This includes the valid-bit,
144082 + * in case you were wondering... */
144083 + if (!__raw_readb(&rr->verb)) {
144084 + dcbit_ro(rr);
144085 + return NULL;
144086 + }
144087 + mc->rridx ^= 1;
144088 + mc->vbit ^= QM_MCC_VERB_VBIT;
144089 +#ifdef CONFIG_FSL_DPA_CHECKING
144090 + mc->state = qman_mc_idle;
144091 +#endif
144092 + return rr;
144093 +}
144094 +
144095 +
144096 +/* ------------------------------------- */
144097 +/* --- Portal interrupt register API --- */
144098 +
144099 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
144100 +{
144101 + return 0;
144102 +}
144103 +
144104 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
144105 +{
144106 +}
144107 +
144108 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
144109 +{
144110 + qm_out(ITPR, iperiod);
144111 +}
144112 +
144113 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
144114 +{
144115 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
144116 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
144117 +#else
144118 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
144119 +#endif
144120 +}
144121 +
144122 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
144123 + u32 val)
144124 +{
144125 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
144126 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
144127 +#else
144128 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
144129 +#endif
144130 +}
144131 +
144132 +/* Cleanup FQs */
144133 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
144134 + u32 fqid)
144135 +{
144136 +
144137 + struct qm_mc_command *mcc;
144138 + struct qm_mc_result *mcr;
144139 + u8 state;
144140 + int orl_empty, fq_empty, i, drain = 0;
144141 + u32 result;
144142 + u32 channel, wq;
144143 + u16 dest_wq;
144144 +
144145 + /* Determine the state of the FQID */
144146 + mcc = qm_mc_start(portal[0]);
144147 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
144148 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
144149 + while (!(mcr = qm_mc_result(portal[0])))
144150 + cpu_relax();
144151 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
144152 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
144153 + if (state == QM_MCR_NP_STATE_OOS)
144154 + return 0; /* Already OOS, no need to do anymore checks */
144155 +
144156 + /* Query which channel the FQ is using */
144157 + mcc = qm_mc_start(portal[0]);
144158 + mcc->queryfq.fqid = cpu_to_be32(fqid);
144159 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
144160 + while (!(mcr = qm_mc_result(portal[0])))
144161 + cpu_relax();
144162 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
144163 +
144164 + /* Need to store these since the MCR gets reused */
144165 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
144166 + wq = dest_wq & 0x7;
144167 + channel = dest_wq>>3;
144168 +
144169 + switch (state) {
144170 + case QM_MCR_NP_STATE_TEN_SCHED:
144171 + case QM_MCR_NP_STATE_TRU_SCHED:
144172 + case QM_MCR_NP_STATE_ACTIVE:
144173 + case QM_MCR_NP_STATE_PARKED:
144174 + orl_empty = 0;
144175 + mcc = qm_mc_start(portal[0]);
144176 + mcc->alterfq.fqid = cpu_to_be32(fqid);
144177 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
144178 + while (!(mcr = qm_mc_result(portal[0])))
144179 + cpu_relax();
144180 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
144181 + QM_MCR_VERB_ALTER_RETIRE);
144182 + result = mcr->result; /* Make a copy as we reuse MCR below */
144183 +
144184 + if (result == QM_MCR_RESULT_PENDING) {
144185 + /* Need to wait for the FQRN in the message ring, which
144186 + will only occur once the FQ has been drained. In
144187 + order for the FQ to drain the portal needs to be set
144188 + to dequeue from the channel the FQ is scheduled on */
144189 + const struct qm_mr_entry *msg;
144190 + const struct qm_dqrr_entry *dqrr = NULL;
144191 + int found_fqrn = 0;
144192 + u16 dequeue_wq = 0;
144193 +
144194 + /* Flag that we need to drain FQ */
144195 + drain = 1;
144196 +
144197 + if (channel >= qm_channel_pool1 &&
144198 + channel < (qm_channel_pool1 + 15)) {
144199 + /* Pool channel, enable the bit in the portal */
144200 + dequeue_wq = (channel -
144201 + qm_channel_pool1 + 1)<<4 | wq;
144202 + } else if (channel < qm_channel_pool1) {
144203 + /* Dedicated channel */
144204 + dequeue_wq = wq;
144205 + } else {
144206 + pr_info("Cannot recover FQ 0x%x, it is "
144207 + "scheduled on channel 0x%x",
144208 + fqid, channel);
144209 + return -EBUSY;
144210 + }
144211 + /* Set the sdqcr to drain this channel */
144212 + if (channel < qm_channel_pool1)
144213 + for (i = 0; i < portal_count; i++)
144214 + qm_dqrr_sdqcr_set(portal[i],
144215 + QM_SDQCR_TYPE_ACTIVE |
144216 + QM_SDQCR_CHANNELS_DEDICATED);
144217 + else
144218 + for (i = 0; i < portal_count; i++)
144219 + qm_dqrr_sdqcr_set(
144220 + portal[i],
144221 + QM_SDQCR_TYPE_ACTIVE |
144222 + QM_SDQCR_CHANNELS_POOL_CONV
144223 + (channel));
144224 + while (!found_fqrn) {
144225 + /* Keep draining DQRR while checking the MR*/
144226 + for (i = 0; i < portal_count; i++) {
144227 + qm_dqrr_pvb_update(portal[i]);
144228 + dqrr = qm_dqrr_current(portal[i]);
144229 + while (dqrr) {
144230 + qm_dqrr_cdc_consume_1ptr(
144231 + portal[i], dqrr, 0);
144232 + qm_dqrr_pvb_update(portal[i]);
144233 + qm_dqrr_next(portal[i]);
144234 + dqrr = qm_dqrr_current(
144235 + portal[i]);
144236 + }
144237 + /* Process message ring too */
144238 + qm_mr_pvb_update(portal[i]);
144239 + msg = qm_mr_current(portal[i]);
144240 + while (msg) {
144241 + if ((msg->verb &
144242 + QM_MR_VERB_TYPE_MASK)
144243 + == QM_MR_VERB_FQRN)
144244 + found_fqrn = 1;
144245 + qm_mr_next(portal[i]);
144246 + qm_mr_cci_consume_to_current(
144247 + portal[i]);
144248 + qm_mr_pvb_update(portal[i]);
144249 + msg = qm_mr_current(portal[i]);
144250 + }
144251 + cpu_relax();
144252 + }
144253 + }
144254 + }
144255 + if (result != QM_MCR_RESULT_OK &&
144256 + result != QM_MCR_RESULT_PENDING) {
144257 + /* error */
144258 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
144259 + fqid, result);
144260 + return -1;
144261 + }
144262 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
144263 + /* ORL had no entries, no need to wait until the
144264 + ERNs come in */
144265 + orl_empty = 1;
144266 + }
144267 + /* Retirement succeeded, check to see if FQ needs
144268 + to be drained */
144269 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
144270 + /* FQ is Not Empty, drain using volatile DQ commands */
144271 + fq_empty = 0;
144272 + do {
144273 + const struct qm_dqrr_entry *dqrr = NULL;
144274 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
144275 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
144276 +
144277 + /* Wait for a dequeue to occur */
144278 + while (dqrr == NULL) {
144279 + qm_dqrr_pvb_update(portal[0]);
144280 + dqrr = qm_dqrr_current(portal[0]);
144281 + if (!dqrr)
144282 + cpu_relax();
144283 + }
144284 + /* Process the dequeues, making sure to
144285 + empty the ring completely */
144286 + while (dqrr) {
144287 + if (be32_to_cpu(dqrr->fqid) == fqid &&
144288 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
144289 + fq_empty = 1;
144290 + qm_dqrr_cdc_consume_1ptr(portal[0],
144291 + dqrr, 0);
144292 + qm_dqrr_pvb_update(portal[0]);
144293 + qm_dqrr_next(portal[0]);
144294 + dqrr = qm_dqrr_current(portal[0]);
144295 + }
144296 + } while (fq_empty == 0);
144297 + }
144298 + for (i = 0; i < portal_count; i++)
144299 + qm_dqrr_sdqcr_set(portal[i], 0);
144300 +
144301 + /* Wait for the ORL to have been completely drained */
144302 + while (orl_empty == 0) {
144303 + const struct qm_mr_entry *msg;
144304 + qm_mr_pvb_update(portal[0]);
144305 + msg = qm_mr_current(portal[0]);
144306 + while (msg) {
144307 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
144308 + QM_MR_VERB_FQRL)
144309 + orl_empty = 1;
144310 + qm_mr_next(portal[0]);
144311 + qm_mr_cci_consume_to_current(portal[0]);
144312 + qm_mr_pvb_update(portal[0]);
144313 + msg = qm_mr_current(portal[0]);
144314 + }
144315 + cpu_relax();
144316 + }
144317 + mcc = qm_mc_start(portal[0]);
144318 + mcc->alterfq.fqid = cpu_to_be32(fqid);
144319 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
144320 + while (!(mcr = qm_mc_result(portal[0])))
144321 + cpu_relax();
144322 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
144323 + QM_MCR_VERB_ALTER_OOS);
144324 + if (mcr->result != QM_MCR_RESULT_OK) {
144325 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
144326 + fqid, mcr->result);
144327 + return -1;
144328 + }
144329 + return 0;
144330 + case QM_MCR_NP_STATE_RETIRED:
144331 + /* Send OOS Command */
144332 + mcc = qm_mc_start(portal[0]);
144333 + mcc->alterfq.fqid = cpu_to_be32(fqid);
144334 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
144335 + while (!(mcr = qm_mc_result(portal[0])))
144336 + cpu_relax();
144337 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
144338 + QM_MCR_VERB_ALTER_OOS);
144339 + if (mcr->result) {
144340 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
144341 + return -1;
144342 + }
144343 + return 0;
144344 + }
144345 + return -1;
144346 +}
144347 --- /dev/null
144348 +++ b/drivers/staging/fsl_qbman/qman_private.h
144349 @@ -0,0 +1,398 @@
144350 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144351 + *
144352 + * Redistribution and use in source and binary forms, with or without
144353 + * modification, are permitted provided that the following conditions are met:
144354 + * * Redistributions of source code must retain the above copyright
144355 + * notice, this list of conditions and the following disclaimer.
144356 + * * Redistributions in binary form must reproduce the above copyright
144357 + * notice, this list of conditions and the following disclaimer in the
144358 + * documentation and/or other materials provided with the distribution.
144359 + * * Neither the name of Freescale Semiconductor nor the
144360 + * names of its contributors may be used to endorse or promote products
144361 + * derived from this software without specific prior written permission.
144362 + *
144363 + *
144364 + * ALTERNATIVELY, this software may be distributed under the terms of the
144365 + * GNU General Public License ("GPL") as published by the Free Software
144366 + * Foundation, either version 2 of that License or (at your option) any
144367 + * later version.
144368 + *
144369 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144370 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144371 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144372 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144373 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144374 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144375 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144376 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144377 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144378 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144379 + */
144380 +
144381 +#include "dpa_sys.h"
144382 +#include <linux/fsl_qman.h>
144383 +#include <linux/iommu.h>
144384 +
144385 +#if defined(CONFIG_FSL_PAMU)
144386 +#include <asm/fsl_pamu_stash.h>
144387 +#endif
144388 +
144389 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
144390 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
144391 +#endif
144392 +
144393 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
144394 + /* ----------------- */
144395 + /* Congestion Groups */
144396 + /* ----------------- */
144397 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
144398 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
144399 + * those that don't concern us. We harness the structure and accessor details
144400 + * already used in the management command to query congestion groups. */
144401 +struct qman_cgrs {
144402 + struct __qm_mcr_querycongestion q;
144403 +};
144404 +static inline void qman_cgrs_init(struct qman_cgrs *c)
144405 +{
144406 + memset(c, 0, sizeof(*c));
144407 +}
144408 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
144409 +{
144410 + memset(c, 0xff, sizeof(*c));
144411 +}
144412 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
144413 +{
144414 + return QM_MCR_QUERYCONGESTION(&c->q, num);
144415 +}
144416 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
144417 +{
144418 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
144419 +}
144420 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
144421 +{
144422 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
144423 +}
144424 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
144425 +{
144426 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
144427 + ;
144428 + return num;
144429 +}
144430 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
144431 + const struct qman_cgrs *src)
144432 +{
144433 + *dest = *src;
144434 +}
144435 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
144436 + const struct qman_cgrs *a, const struct qman_cgrs *b)
144437 +{
144438 + int ret;
144439 + u32 *_d = dest->q.__state;
144440 + const u32 *_a = a->q.__state;
144441 + const u32 *_b = b->q.__state;
144442 + for (ret = 0; ret < 8; ret++)
144443 + *(_d++) = *(_a++) & *(_b++);
144444 +}
144445 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
144446 + const struct qman_cgrs *a, const struct qman_cgrs *b)
144447 +{
144448 + int ret;
144449 + u32 *_d = dest->q.__state;
144450 + const u32 *_a = a->q.__state;
144451 + const u32 *_b = b->q.__state;
144452 + for (ret = 0; ret < 8; ret++)
144453 + *(_d++) = *(_a++) ^ *(_b++);
144454 +}
144455 +
144456 + /* ----------------------- */
144457 + /* CEETM Congestion Groups */
144458 + /* ----------------------- */
144459 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
144460 + * congestion groups.
144461 + */
144462 +struct qman_ccgrs {
144463 + struct __qm_mcr_querycongestion q[2];
144464 +};
144465 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
144466 +{
144467 + memset(c, 0, sizeof(*c));
144468 +}
144469 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
144470 +{
144471 + memset(c, 0xff, sizeof(*c));
144472 +}
144473 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
144474 +{
144475 + if (num < __CGR_NUM)
144476 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
144477 + else
144478 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
144479 +}
144480 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
144481 +{
144482 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
144483 + ;
144484 + return num;
144485 +}
144486 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
144487 + const struct qman_ccgrs *src)
144488 +{
144489 + *dest = *src;
144490 +}
144491 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
144492 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
144493 +{
144494 + int ret, i;
144495 + u32 *_d;
144496 + const u32 *_a, *_b;
144497 + for (i = 0; i < 2; i++) {
144498 + _d = dest->q[i].__state;
144499 + _a = a->q[i].__state;
144500 + _b = b->q[i].__state;
144501 + for (ret = 0; ret < 8; ret++)
144502 + *(_d++) = *(_a++) & *(_b++);
144503 + }
144504 +}
144505 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
144506 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
144507 +{
144508 + int ret, i;
144509 + u32 *_d;
144510 + const u32 *_a, *_b;
144511 + for (i = 0; i < 2; i++) {
144512 + _d = dest->q[i].__state;
144513 + _a = a->q[i].__state;
144514 + _b = b->q[i].__state;
144515 + for (ret = 0; ret < 8; ret++)
144516 + *(_d++) = *(_a++) ^ *(_b++);
144517 + }
144518 +}
144519 +
144520 +/* used by CCSR and portal interrupt code */
144521 +enum qm_isr_reg {
144522 + qm_isr_status = 0,
144523 + qm_isr_enable = 1,
144524 + qm_isr_disable = 2,
144525 + qm_isr_inhibit = 3
144526 +};
144527 +
144528 +struct qm_portal_config {
144529 + /* Corenet portal addresses;
144530 + * [0]==cache-enabled, [1]==cache-inhibited. */
144531 + __iomem void *addr_virt[2];
144532 + struct resource addr_phys[2];
144533 + struct device dev;
144534 + struct iommu_domain *iommu_domain;
144535 + /* Allow these to be joined in lists */
144536 + struct list_head list;
144537 + /* User-visible portal configuration settings */
144538 + struct qman_portal_config public_cfg;
144539 + /* power management saved data */
144540 + u32 saved_isdr;
144541 +};
144542 +
144543 +/* Revision info (for errata and feature handling) */
144544 +#define QMAN_REV11 0x0101
144545 +#define QMAN_REV12 0x0102
144546 +#define QMAN_REV20 0x0200
144547 +#define QMAN_REV30 0x0300
144548 +#define QMAN_REV31 0x0301
144549 +#define QMAN_REV32 0x0302
144550 +
144551 +/* QMan REV_2 register contains the Cfg option */
144552 +#define QMAN_REV_CFG_0 0x0
144553 +#define QMAN_REV_CFG_1 0x1
144554 +#define QMAN_REV_CFG_2 0x2
144555 +#define QMAN_REV_CFG_3 0x3
144556 +
144557 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
144558 +extern u8 qman_ip_cfg;
144559 +extern u32 qman_clk;
144560 +extern u16 qman_portal_max;
144561 +
144562 +#ifdef CONFIG_FSL_QMAN_CONFIG
144563 +/* Hooks from qman_driver.c to qman_config.c */
144564 +int qman_init_ccsr(struct device_node *node);
144565 +void qman_liodn_fixup(u16 channel);
144566 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
144567 +size_t get_qman_fqd_size(void);
144568 +#else
144569 +static inline size_t get_qman_fqd_size(void)
144570 +{
144571 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
144572 +}
144573 +#endif
144574 +
144575 +int qm_set_wpm(int wpm);
144576 +int qm_get_wpm(int *wpm);
144577 +
144578 +/* Hooks from qman_driver.c in to qman_high.c */
144579 +struct qman_portal *qman_create_portal(
144580 + struct qman_portal *portal,
144581 + const struct qm_portal_config *config,
144582 + const struct qman_cgrs *cgrs);
144583 +
144584 +struct qman_portal *qman_create_affine_portal(
144585 + const struct qm_portal_config *config,
144586 + const struct qman_cgrs *cgrs);
144587 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
144588 + int cpu);
144589 +const struct qm_portal_config *qman_destroy_affine_portal(void);
144590 +void qman_destroy_portal(struct qman_portal *qm);
144591 +
144592 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
144593 +struct qm_portal_config *qm_get_unused_portal(void);
144594 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
144595 +
144596 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
144597 +void qm_set_liodns(struct qm_portal_config *pcfg);
144598 +
144599 +/* This CGR feature is supported by h/w and required by unit-tests and the
144600 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
144601 + * corruption of h/w fields by s/w that are usually incorruptible (because the
144602 + * counters are usually maintained entirely within h/w). As such, we declare
144603 + * this API internally. */
144604 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
144605 + struct qm_mcr_cgrtestwrite *result);
144606 +
144607 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
144608 +/* If the fq object pointer is greater than the size of context_b field,
144609 + * than a lookup table is required. */
144610 +int qman_setup_fq_lookup_table(size_t num_entries);
144611 +#endif
144612 +
144613 +
144614 +/*************************************************/
144615 +/* QMan s/w corenet portal, low-level i/face */
144616 +/*************************************************/
144617 +
144618 +/* Note: most functions are only used by the high-level interface, so are
144619 + * inlined from qman_low.h. The stuff below is for use by other parts of the
144620 + * driver. */
144621 +
144622 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
144623 + * dequeue TYPE. Choose TOKEN (8-bit).
144624 + * If SOURCE == CHANNELS,
144625 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
144626 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
144627 + * priority.
144628 + * If SOURCE == SPECIFICWQ,
144629 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
144630 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
144631 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
144632 + * same value.
144633 + */
144634 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
144635 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
144636 +#define QM_SDQCR_COUNT_EXACT1 0x0
144637 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
144638 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
144639 +#define QM_SDQCR_TYPE_MASK 0x03000000
144640 +#define QM_SDQCR_TYPE_NULL 0x0
144641 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
144642 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
144643 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
144644 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
144645 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
144646 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
144647 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
144648 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
144649 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
144650 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
144651 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
144652 +
144653 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
144654 +#define QM_VDQCR_FQID_MASK 0x00ffffff
144655 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
144656 +
144657 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
144658 + * If MODE==SCHEDULED
144659 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
144660 + * If CHANNELS,
144661 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
144662 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
144663 + * priority.
144664 + * If SPECIFICWQ,
144665 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
144666 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
144667 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
144668 + * same value.
144669 + * If MODE==UNSCHEDULED
144670 + * Choose FQID().
144671 + */
144672 +#define QM_PDQCR_MODE_SCHEDULED 0x0
144673 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
144674 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
144675 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
144676 +#define QM_PDQCR_COUNT_EXACT1 0x0
144677 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
144678 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
144679 +#define QM_PDQCR_TYPE_MASK 0x03000000
144680 +#define QM_PDQCR_TYPE_NULL 0x0
144681 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
144682 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
144683 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
144684 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
144685 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
144686 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
144687 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
144688 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
144689 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
144690 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
144691 +
144692 +/* Used by all portal interrupt registers except 'inhibit'
144693 + * Channels with frame availability
144694 + */
144695 +#define QM_PIRQ_DQAVAIL 0x0000ffff
144696 +
144697 +/* The DQAVAIL interrupt fields break down into these bits; */
144698 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
144699 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
144700 +#define QM_DQAVAIL_MASK 0xffff
144701 +/* This mask contains all the "irqsource" bits visible to API users */
144702 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
144703 +
144704 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
144705 + * the disable register" rather than "disable the ability to write". */
144706 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
144707 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
144708 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
144709 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
144710 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
144711 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
144712 +/* TODO: unfortunate name-clash here, reword? */
144713 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
144714 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
144715 +
144716 +#ifdef CONFIG_FSL_QMAN_CONFIG
144717 +int qman_have_ccsr(void);
144718 +#else
144719 +#define qman_have_ccsr 0
144720 +#endif
144721 +
144722 +__init int qman_init(void);
144723 +__init int qman_resource_init(void);
144724 +
144725 +/* CEETM related */
144726 +#define QMAN_CEETM_MAX 2
144727 +extern u8 num_ceetms;
144728 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
144729 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
144730 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
144731 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
144732 +int qman_ceetm_get_prescaler(u16 *pres);
144733 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
144734 + struct qm_mcr_ceetm_cq_query *cq_query);
144735 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
144736 + struct qm_mcr_ceetm_ccgr_query *response);
144737 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
144738 +
144739 +extern void *affine_portals[NR_CPUS];
144740 +const struct qm_portal_config *qman_get_qm_portal_config(
144741 + struct qman_portal *portal);
144742 +
144743 +/* power management */
144744 +#ifdef CONFIG_SUSPEND
144745 +void suspend_unused_qportal(void);
144746 +void resume_unused_qportal(void);
144747 +#endif
144748 --- /dev/null
144749 +++ b/drivers/staging/fsl_qbman/qman_test.c
144750 @@ -0,0 +1,57 @@
144751 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144752 + *
144753 + * Redistribution and use in source and binary forms, with or without
144754 + * modification, are permitted provided that the following conditions are met:
144755 + * * Redistributions of source code must retain the above copyright
144756 + * notice, this list of conditions and the following disclaimer.
144757 + * * Redistributions in binary form must reproduce the above copyright
144758 + * notice, this list of conditions and the following disclaimer in the
144759 + * documentation and/or other materials provided with the distribution.
144760 + * * Neither the name of Freescale Semiconductor nor the
144761 + * names of its contributors may be used to endorse or promote products
144762 + * derived from this software without specific prior written permission.
144763 + *
144764 + *
144765 + * ALTERNATIVELY, this software may be distributed under the terms of the
144766 + * GNU General Public License ("GPL") as published by the Free Software
144767 + * Foundation, either version 2 of that License or (at your option) any
144768 + * later version.
144769 + *
144770 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144771 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144772 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144773 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144774 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144775 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144776 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144777 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144778 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144779 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144780 + */
144781 +
144782 +#include "qman_test.h"
144783 +
144784 +MODULE_AUTHOR("Geoff Thorpe");
144785 +MODULE_LICENSE("Dual BSD/GPL");
144786 +MODULE_DESCRIPTION("Qman testing");
144787 +
144788 +static int test_init(void)
144789 +{
144790 + int loop = 1;
144791 + while (loop--) {
144792 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
144793 + qman_test_hotpotato();
144794 +#endif
144795 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
144796 + qman_test_high();
144797 +#endif
144798 + }
144799 + return 0;
144800 +}
144801 +
144802 +static void test_exit(void)
144803 +{
144804 +}
144805 +
144806 +module_init(test_init);
144807 +module_exit(test_exit);
144808 --- /dev/null
144809 +++ b/drivers/staging/fsl_qbman/qman_test.h
144810 @@ -0,0 +1,45 @@
144811 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144812 + *
144813 + * Redistribution and use in source and binary forms, with or without
144814 + * modification, are permitted provided that the following conditions are met:
144815 + * * Redistributions of source code must retain the above copyright
144816 + * notice, this list of conditions and the following disclaimer.
144817 + * * Redistributions in binary form must reproduce the above copyright
144818 + * notice, this list of conditions and the following disclaimer in the
144819 + * documentation and/or other materials provided with the distribution.
144820 + * * Neither the name of Freescale Semiconductor nor the
144821 + * names of its contributors may be used to endorse or promote products
144822 + * derived from this software without specific prior written permission.
144823 + *
144824 + *
144825 + * ALTERNATIVELY, this software may be distributed under the terms of the
144826 + * GNU General Public License ("GPL") as published by the Free Software
144827 + * Foundation, either version 2 of that License or (at your option) any
144828 + * later version.
144829 + *
144830 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144831 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144832 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144833 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144834 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144835 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144836 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144837 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144838 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144839 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144840 + */
144841 +
144842 +#include <linux/kernel.h>
144843 +#include <linux/errno.h>
144844 +#include <linux/io.h>
144845 +#include <linux/slab.h>
144846 +#include <linux/module.h>
144847 +#include <linux/interrupt.h>
144848 +#include <linux/delay.h>
144849 +#include <linux/sched.h>
144850 +
144851 +#include <linux/fsl_qman.h>
144852 +
144853 +void qman_test_hotpotato(void);
144854 +void qman_test_high(void);
144855 +
144856 --- /dev/null
144857 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
144858 @@ -0,0 +1,216 @@
144859 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144860 + *
144861 + * Redistribution and use in source and binary forms, with or without
144862 + * modification, are permitted provided that the following conditions are met:
144863 + * * Redistributions of source code must retain the above copyright
144864 + * notice, this list of conditions and the following disclaimer.
144865 + * * Redistributions in binary form must reproduce the above copyright
144866 + * notice, this list of conditions and the following disclaimer in the
144867 + * documentation and/or other materials provided with the distribution.
144868 + * * Neither the name of Freescale Semiconductor nor the
144869 + * names of its contributors may be used to endorse or promote products
144870 + * derived from this software without specific prior written permission.
144871 + *
144872 + *
144873 + * ALTERNATIVELY, this software may be distributed under the terms of the
144874 + * GNU General Public License ("GPL") as published by the Free Software
144875 + * Foundation, either version 2 of that License or (at your option) any
144876 + * later version.
144877 + *
144878 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144879 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144880 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144881 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144882 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144883 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144884 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144885 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144886 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144887 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144888 + */
144889 +
144890 +#include "qman_test.h"
144891 +
144892 +/*************/
144893 +/* constants */
144894 +/*************/
144895 +
144896 +#define CGR_ID 27
144897 +#define POOL_ID 2
144898 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
144899 +#define NUM_ENQUEUES 10
144900 +#define NUM_PARTIAL 4
144901 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
144902 + QM_SDQCR_TYPE_PRIO_QOS | \
144903 + QM_SDQCR_TOKEN_SET(0x98) | \
144904 + QM_SDQCR_CHANNELS_DEDICATED | \
144905 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
144906 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
144907 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
144908 +
144909 +/*************************************/
144910 +/* Predeclarations (eg. for fq_base) */
144911 +/*************************************/
144912 +
144913 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
144914 + struct qman_fq *,
144915 + const struct qm_dqrr_entry *);
144916 +static void cb_ern(struct qman_portal *, struct qman_fq *,
144917 + const struct qm_mr_entry *);
144918 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
144919 + const struct qm_mr_entry *);
144920 +
144921 +/***************/
144922 +/* global vars */
144923 +/***************/
144924 +
144925 +static struct qm_fd fd, fd_dq;
144926 +static struct qman_fq fq_base = {
144927 + .cb.dqrr = cb_dqrr,
144928 + .cb.ern = cb_ern,
144929 + .cb.fqs = cb_fqs
144930 +};
144931 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
144932 +static int retire_complete, sdqcr_complete;
144933 +
144934 +/**********************/
144935 +/* internal functions */
144936 +/**********************/
144937 +
144938 +/* Helpers for initialising and "incrementing" a frame descriptor */
144939 +static void fd_init(struct qm_fd *__fd)
144940 +{
144941 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
144942 + __fd->format = qm_fd_contig_big;
144943 + __fd->length29 = 0x0000ffff;
144944 + __fd->cmd = 0xfeedf00d;
144945 +}
144946 +
144947 +static void fd_inc(struct qm_fd *__fd)
144948 +{
144949 + u64 t = qm_fd_addr_get64(__fd);
144950 + int z = t >> 40;
144951 + t <<= 1;
144952 + if (z)
144953 + t |= 1;
144954 + qm_fd_addr_set64(__fd, t);
144955 + __fd->length29--;
144956 + __fd->cmd++;
144957 +}
144958 +
144959 +/* The only part of the 'fd' we can't memcmp() is the ppid */
144960 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
144961 +{
144962 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
144963 + if (!r)
144964 + r = a->format - b->format;
144965 + if (!r)
144966 + r = a->opaque - b->opaque;
144967 + if (!r)
144968 + r = a->cmd - b->cmd;
144969 + return r;
144970 +}
144971 +
144972 +/********/
144973 +/* test */
144974 +/********/
144975 +
144976 +static void do_enqueues(struct qman_fq *fq)
144977 +{
144978 + unsigned int loop;
144979 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
144980 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
144981 + (((loop + 1) == NUM_ENQUEUES) ?
144982 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
144983 + panic("qman_enqueue() failed\n");
144984 + fd_inc(&fd);
144985 + }
144986 +}
144987 +
144988 +void qman_test_high(void)
144989 +{
144990 + unsigned int flags;
144991 + int res;
144992 + struct qman_fq *fq = &fq_base;
144993 +
144994 + pr_info("qman_test_high starting\n");
144995 + fd_init(&fd);
144996 + fd_init(&fd_dq);
144997 +
144998 + /* Initialise (parked) FQ */
144999 + if (qman_create_fq(0, FQ_FLAGS, fq))
145000 + panic("qman_create_fq() failed\n");
145001 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
145002 + panic("qman_init_fq() failed\n");
145003 +
145004 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
145005 + do_enqueues(fq);
145006 + pr_info("VDQCR (till-empty);\n");
145007 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
145008 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
145009 + panic("qman_volatile_dequeue() failed\n");
145010 + do_enqueues(fq);
145011 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
145012 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
145013 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
145014 + panic("qman_volatile_dequeue() failed\n");
145015 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
145016 + NUM_ENQUEUES);
145017 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
145018 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
145019 + panic("qman_volatile_dequeue() failed\n");
145020 +
145021 + do_enqueues(fq);
145022 + pr_info("scheduled dequeue (till-empty)\n");
145023 + if (qman_schedule_fq(fq))
145024 + panic("qman_schedule_fq() failed\n");
145025 + wait_event(waitqueue, sdqcr_complete);
145026 +
145027 + /* Retire and OOS the FQ */
145028 + res = qman_retire_fq(fq, &flags);
145029 + if (res < 0)
145030 + panic("qman_retire_fq() failed\n");
145031 + wait_event(waitqueue, retire_complete);
145032 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
145033 + panic("leaking frames\n");
145034 + if (qman_oos_fq(fq))
145035 + panic("qman_oos_fq() failed\n");
145036 + qman_destroy_fq(fq, 0);
145037 + pr_info("qman_test_high finished\n");
145038 +}
145039 +
145040 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
145041 + struct qman_fq *fq,
145042 + const struct qm_dqrr_entry *dq)
145043 +{
145044 + if (fd_cmp(&fd_dq, &dq->fd)) {
145045 + pr_err("BADNESS: dequeued frame doesn't match;\n");
145046 + pr_err("Expected 0x%llx, got 0x%llx\n",
145047 + (unsigned long long)fd_dq.length29,
145048 + (unsigned long long)dq->fd.length29);
145049 + BUG();
145050 + }
145051 + fd_inc(&fd_dq);
145052 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
145053 + sdqcr_complete = 1;
145054 + wake_up(&waitqueue);
145055 + }
145056 + return qman_cb_dqrr_consume;
145057 +}
145058 +
145059 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
145060 + const struct qm_mr_entry *msg)
145061 +{
145062 + panic("cb_ern() unimplemented");
145063 +}
145064 +
145065 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
145066 + const struct qm_mr_entry *msg)
145067 +{
145068 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
145069 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
145070 + panic("unexpected FQS message");
145071 + pr_info("Retirement message received\n");
145072 + retire_complete = 1;
145073 + wake_up(&waitqueue);
145074 +}
145075 --- /dev/null
145076 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
145077 @@ -0,0 +1,502 @@
145078 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
145079 + *
145080 + * Redistribution and use in source and binary forms, with or without
145081 + * modification, are permitted provided that the following conditions are met:
145082 + * * Redistributions of source code must retain the above copyright
145083 + * notice, this list of conditions and the following disclaimer.
145084 + * * Redistributions in binary form must reproduce the above copyright
145085 + * notice, this list of conditions and the following disclaimer in the
145086 + * documentation and/or other materials provided with the distribution.
145087 + * * Neither the name of Freescale Semiconductor nor the
145088 + * names of its contributors may be used to endorse or promote products
145089 + * derived from this software without specific prior written permission.
145090 + *
145091 + *
145092 + * ALTERNATIVELY, this software may be distributed under the terms of the
145093 + * GNU General Public License ("GPL") as published by the Free Software
145094 + * Foundation, either version 2 of that License or (at your option) any
145095 + * later version.
145096 + *
145097 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145098 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145099 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145100 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145101 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145102 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145103 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145104 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145105 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145106 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145107 + */
145108 +
145109 +#include <linux/kthread.h>
145110 +#include <linux/platform_device.h>
145111 +#include <linux/dma-mapping.h>
145112 +#include "qman_test.h"
145113 +
145114 +/* Algorithm:
145115 + *
145116 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
145117 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
145118 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
145119 + * shuttle a "hot potato" frame around them such that every forwarding action
145120 + * moves it from one cpu to another. (The use of more than one handler per cpu
145121 + * is to allow enough handlers/FQs to truly test the significance of caching -
145122 + * ie. when cache-expiries are occurring.)
145123 + *
145124 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
145125 + * first and last words of the frame data will undergo a transformation step on
145126 + * each forwarding action. To achieve this, each handler will be assigned a
145127 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
145128 + * received by a handler, the mixer of the expected sender is XOR'd into all
145129 + * words of the entire frame, which is then validated against the original
145130 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
145131 + * the current handler. Apart from validating that the frame is taking the
145132 + * expected path, this also provides some quasi-realistic overheads to each
145133 + * forwarding action - dereferencing *all* the frame data, computation, and
145134 + * conditional branching. There is a "special" handler designated to act as the
145135 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
145136 + * to determine when the test has completed by counting HP_LOOPS iterations.
145137 + *
145138 + * Init phases:
145139 + *
145140 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
145141 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
145142 + * handlers and link-list them (but do no other handler setup).
145143 + *
145144 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
145145 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
145146 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
145147 + * and advance the iterator for the next loop. This includes a final fixup,
145148 + * which connects the last handler to the first (and which is why phase 2
145149 + * and 3 are separate).
145150 + *
145151 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
145152 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
145153 + * initialise FQ objects and advance the iterator for the next loop.
145154 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
145155 + * initialisation targets the correct cpu.
145156 + */
145157 +
145158 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
145159 + * the fn from irq context, which is too restrictive). */
145160 +struct bstrap {
145161 + void (*fn)(void);
145162 + atomic_t started;
145163 +};
145164 +static int bstrap_fn(void *__bstrap)
145165 +{
145166 + struct bstrap *bstrap = __bstrap;
145167 + atomic_inc(&bstrap->started);
145168 + bstrap->fn();
145169 + while (!kthread_should_stop())
145170 + msleep(1);
145171 + return 0;
145172 +}
145173 +static int on_all_cpus(void (*fn)(void))
145174 +{
145175 + int cpu;
145176 + for_each_cpu(cpu, cpu_online_mask) {
145177 + struct bstrap bstrap = {
145178 + .fn = fn,
145179 + .started = ATOMIC_INIT(0)
145180 + };
145181 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
145182 + "hotpotato%d", cpu);
145183 + int ret;
145184 + if (IS_ERR(k))
145185 + return -ENOMEM;
145186 + kthread_bind(k, cpu);
145187 + wake_up_process(k);
145188 + /* If we call kthread_stop() before the "wake up" has had an
145189 + * effect, then the thread may exit with -EINTR without ever
145190 + * running the function. So poll until it's started before
145191 + * requesting it to stop. */
145192 + while (!atomic_read(&bstrap.started))
145193 + msleep(10);
145194 + ret = kthread_stop(k);
145195 + if (ret)
145196 + return ret;
145197 + }
145198 + return 0;
145199 +}
145200 +
145201 +struct hp_handler {
145202 +
145203 + /* The following data is stashed when 'rx' is dequeued; */
145204 + /* -------------- */
145205 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
145206 + struct qman_fq rx;
145207 + /* The Tx FQ we should forward to */
145208 + struct qman_fq tx;
145209 + /* The value we XOR post-dequeue, prior to validating */
145210 + u32 rx_mixer;
145211 + /* The value we XOR pre-enqueue, after validating */
145212 + u32 tx_mixer;
145213 + /* what the hotpotato address should be on dequeue */
145214 + dma_addr_t addr;
145215 + u32 *frame_ptr;
145216 +
145217 + /* The following data isn't (necessarily) stashed on dequeue; */
145218 + /* -------------- */
145219 + u32 fqid_rx, fqid_tx;
145220 + /* list node for linking us into 'hp_cpu' */
145221 + struct list_head node;
145222 + /* Just to check ... */
145223 + unsigned int processor_id;
145224 +} ____cacheline_aligned;
145225 +
145226 +struct hp_cpu {
145227 + /* identify the cpu we run on; */
145228 + unsigned int processor_id;
145229 + /* root node for the per-cpu list of handlers */
145230 + struct list_head handlers;
145231 + /* list node for linking us into 'hp_cpu_list' */
145232 + struct list_head node;
145233 + /* when repeatedly scanning 'hp_list', each time linking the n'th
145234 + * handlers together, this is used as per-cpu iterator state */
145235 + struct hp_handler *iterator;
145236 +};
145237 +
145238 +/* Each cpu has one of these */
145239 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
145240 +
145241 +/* links together the hp_cpu structs, in first-come first-serve order. */
145242 +static LIST_HEAD(hp_cpu_list);
145243 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
145244 +
145245 +static unsigned int hp_cpu_list_length;
145246 +
145247 +/* the "special" handler, that starts and terminates the test. */
145248 +static struct hp_handler *special_handler;
145249 +static int loop_counter;
145250 +
145251 +/* handlers are allocated out of this, so they're properly aligned. */
145252 +static struct kmem_cache *hp_handler_slab;
145253 +
145254 +/* this is the frame data */
145255 +static void *__frame_ptr;
145256 +static u32 *frame_ptr;
145257 +static dma_addr_t frame_dma;
145258 +
145259 +/* the main function waits on this */
145260 +static DECLARE_WAIT_QUEUE_HEAD(queue);
145261 +
145262 +#define HP_PER_CPU 2
145263 +#define HP_LOOPS 8
145264 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
145265 +#define HP_NUM_WORDS 80
145266 +/* First word of the LFSR-based frame data */
145267 +#define HP_FIRST_WORD 0xabbaf00d
145268 +
145269 +static inline u32 do_lfsr(u32 prev)
145270 +{
145271 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
145272 +}
145273 +
145274 +static void allocate_frame_data(void)
145275 +{
145276 + u32 lfsr = HP_FIRST_WORD;
145277 + int loop;
145278 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
145279 + if (!pdev)
145280 + panic("platform_device_alloc() failed");
145281 + if (platform_device_add(pdev))
145282 + panic("platform_device_add() failed");
145283 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
145284 + if (!__frame_ptr)
145285 + panic("kmalloc() failed");
145286 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
145287 + ~(unsigned long)63);
145288 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
145289 + frame_ptr[loop] = lfsr;
145290 + lfsr = do_lfsr(lfsr);
145291 + }
145292 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
145293 + DMA_BIDIRECTIONAL);
145294 + platform_device_del(pdev);
145295 + platform_device_put(pdev);
145296 +}
145297 +
145298 +static void deallocate_frame_data(void)
145299 +{
145300 + kfree(__frame_ptr);
145301 +}
145302 +
145303 +static inline void process_frame_data(struct hp_handler *handler,
145304 + const struct qm_fd *fd)
145305 +{
145306 + u32 *p = handler->frame_ptr;
145307 + u32 lfsr = HP_FIRST_WORD;
145308 + int loop;
145309 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
145310 + pr_err("Got 0x%llx expected 0x%llx\n",
145311 + qm_fd_addr_get64(fd), handler->addr);
145312 + panic("bad frame address");
145313 + }
145314 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
145315 + *p ^= handler->rx_mixer;
145316 + if (*p != lfsr)
145317 + panic("corrupt frame data");
145318 + *p ^= handler->tx_mixer;
145319 + lfsr = do_lfsr(lfsr);
145320 + }
145321 +}
145322 +
145323 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
145324 + struct qman_fq *fq,
145325 + const struct qm_dqrr_entry *dqrr)
145326 +{
145327 + struct hp_handler *handler = (struct hp_handler *)fq;
145328 +
145329 + process_frame_data(handler, &dqrr->fd);
145330 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
145331 + panic("qman_enqueue() failed");
145332 + return qman_cb_dqrr_consume;
145333 +}
145334 +
145335 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
145336 + struct qman_fq *fq,
145337 + const struct qm_dqrr_entry *dqrr)
145338 +{
145339 + struct hp_handler *handler = (struct hp_handler *)fq;
145340 +
145341 + process_frame_data(handler, &dqrr->fd);
145342 + if (++loop_counter < HP_LOOPS) {
145343 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
145344 + panic("qman_enqueue() failed");
145345 + } else {
145346 + pr_info("Received final (%dth) frame\n", loop_counter);
145347 + wake_up(&queue);
145348 + }
145349 + return qman_cb_dqrr_consume;
145350 +}
145351 +
145352 +static void create_per_cpu_handlers(void)
145353 +{
145354 + struct hp_handler *handler;
145355 + int loop;
145356 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
145357 +
145358 + hp_cpu->processor_id = smp_processor_id();
145359 + spin_lock(&hp_lock);
145360 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
145361 + hp_cpu_list_length++;
145362 + spin_unlock(&hp_lock);
145363 + INIT_LIST_HEAD(&hp_cpu->handlers);
145364 + for (loop = 0; loop < HP_PER_CPU; loop++) {
145365 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
145366 + if (!handler)
145367 + panic("kmem_cache_alloc() failed");
145368 + handler->processor_id = hp_cpu->processor_id;
145369 + handler->addr = frame_dma;
145370 + handler->frame_ptr = frame_ptr;
145371 + list_add_tail(&handler->node, &hp_cpu->handlers);
145372 + }
145373 + put_cpu_var(hp_cpus);
145374 +}
145375 +
145376 +static void destroy_per_cpu_handlers(void)
145377 +{
145378 + struct list_head *loop, *tmp;
145379 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
145380 +
145381 + spin_lock(&hp_lock);
145382 + list_del(&hp_cpu->node);
145383 + spin_unlock(&hp_lock);
145384 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
145385 + u32 flags;
145386 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
145387 + node);
145388 + if (qman_retire_fq(&handler->rx, &flags))
145389 + panic("qman_retire_fq(rx) failed");
145390 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
145391 + if (qman_oos_fq(&handler->rx))
145392 + panic("qman_oos_fq(rx) failed");
145393 + qman_destroy_fq(&handler->rx, 0);
145394 + qman_destroy_fq(&handler->tx, 0);
145395 + qman_release_fqid(handler->fqid_rx);
145396 + list_del(&handler->node);
145397 + kmem_cache_free(hp_handler_slab, handler);
145398 + }
145399 + put_cpu_var(hp_cpus);
145400 +}
145401 +
145402 +static inline u8 num_cachelines(u32 offset)
145403 +{
145404 + u8 res = (offset + (L1_CACHE_BYTES - 1))
145405 + / (L1_CACHE_BYTES);
145406 + if (res > 3)
145407 + return 3;
145408 + return res;
145409 +}
145410 +#define STASH_DATA_CL \
145411 + num_cachelines(HP_NUM_WORDS * 4)
145412 +#define STASH_CTX_CL \
145413 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
145414 +
145415 +static void init_handler(void *__handler)
145416 +{
145417 + struct qm_mcc_initfq opts;
145418 + struct hp_handler *handler = __handler;
145419 + BUG_ON(handler->processor_id != smp_processor_id());
145420 + /* Set up rx */
145421 + memset(&handler->rx, 0, sizeof(handler->rx));
145422 + if (handler == special_handler)
145423 + handler->rx.cb.dqrr = special_dqrr;
145424 + else
145425 + handler->rx.cb.dqrr = normal_dqrr;
145426 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
145427 + panic("qman_create_fq(rx) failed");
145428 + memset(&opts, 0, sizeof(opts));
145429 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
145430 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
145431 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
145432 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
145433 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
145434 + QMAN_INITFQ_FLAG_LOCAL, &opts))
145435 + panic("qman_init_fq(rx) failed");
145436 + /* Set up tx */
145437 + memset(&handler->tx, 0, sizeof(handler->tx));
145438 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
145439 + &handler->tx))
145440 + panic("qman_create_fq(tx) failed");
145441 +}
145442 +
145443 +static void init_phase2(void)
145444 +{
145445 + int loop;
145446 + u32 fqid = 0;
145447 + u32 lfsr = 0xdeadbeef;
145448 + struct hp_cpu *hp_cpu;
145449 + struct hp_handler *handler;
145450 +
145451 + for (loop = 0; loop < HP_PER_CPU; loop++) {
145452 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
145453 + int ret;
145454 + if (!loop)
145455 + hp_cpu->iterator = list_first_entry(
145456 + &hp_cpu->handlers,
145457 + struct hp_handler, node);
145458 + else
145459 + hp_cpu->iterator = list_entry(
145460 + hp_cpu->iterator->node.next,
145461 + struct hp_handler, node);
145462 + /* Rx FQID is the previous handler's Tx FQID */
145463 + hp_cpu->iterator->fqid_rx = fqid;
145464 + /* Allocate new FQID for Tx */
145465 + ret = qman_alloc_fqid(&fqid);
145466 + if (ret)
145467 + panic("qman_alloc_fqid() failed");
145468 + hp_cpu->iterator->fqid_tx = fqid;
145469 + /* Rx mixer is the previous handler's Tx mixer */
145470 + hp_cpu->iterator->rx_mixer = lfsr;
145471 + /* Get new mixer for Tx */
145472 + lfsr = do_lfsr(lfsr);
145473 + hp_cpu->iterator->tx_mixer = lfsr;
145474 + }
145475 + }
145476 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
145477 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
145478 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
145479 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
145480 + handler->fqid_rx = fqid;
145481 + handler->rx_mixer = lfsr;
145482 + /* and tag it as our "special" handler */
145483 + special_handler = handler;
145484 +}
145485 +
145486 +static void init_phase3(void)
145487 +{
145488 + int loop;
145489 + struct hp_cpu *hp_cpu;
145490 +
145491 + for (loop = 0; loop < HP_PER_CPU; loop++) {
145492 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
145493 + if (!loop)
145494 + hp_cpu->iterator = list_first_entry(
145495 + &hp_cpu->handlers,
145496 + struct hp_handler, node);
145497 + else
145498 + hp_cpu->iterator = list_entry(
145499 + hp_cpu->iterator->node.next,
145500 + struct hp_handler, node);
145501 + preempt_disable();
145502 + if (hp_cpu->processor_id == smp_processor_id())
145503 + init_handler(hp_cpu->iterator);
145504 + else
145505 + smp_call_function_single(hp_cpu->processor_id,
145506 + init_handler, hp_cpu->iterator, 1);
145507 + preempt_enable();
145508 + }
145509 + }
145510 +}
145511 +
145512 +static void send_first_frame(void *ignore)
145513 +{
145514 + u32 *p = special_handler->frame_ptr;
145515 + u32 lfsr = HP_FIRST_WORD;
145516 + int loop;
145517 + struct qm_fd fd;
145518 +
145519 + BUG_ON(special_handler->processor_id != smp_processor_id());
145520 + memset(&fd, 0, sizeof(fd));
145521 + qm_fd_addr_set64(&fd, special_handler->addr);
145522 + fd.format = qm_fd_contig_big;
145523 + fd.length29 = HP_NUM_WORDS * 4;
145524 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
145525 + if (*p != lfsr)
145526 + panic("corrupt frame data");
145527 + *p ^= special_handler->tx_mixer;
145528 + lfsr = do_lfsr(lfsr);
145529 + }
145530 + pr_info("Sending first frame\n");
145531 + if (qman_enqueue(&special_handler->tx, &fd, 0))
145532 + panic("qman_enqueue() failed");
145533 +}
145534 +
145535 +void qman_test_hotpotato(void)
145536 +{
145537 + if (cpumask_weight(cpu_online_mask) < 2) {
145538 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
145539 + return;
145540 + }
145541 +
145542 + pr_info("qman_test_hotpotato starting\n");
145543 +
145544 + hp_cpu_list_length = 0;
145545 + loop_counter = 0;
145546 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
145547 + sizeof(struct hp_handler), L1_CACHE_BYTES,
145548 + SLAB_HWCACHE_ALIGN, NULL);
145549 + if (!hp_handler_slab)
145550 + panic("kmem_cache_create() failed");
145551 +
145552 + allocate_frame_data();
145553 +
145554 + /* Init phase 1 */
145555 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
145556 + if (on_all_cpus(create_per_cpu_handlers))
145557 + panic("on_each_cpu() failed");
145558 + pr_info("Number of cpus: %d, total of %d handlers\n",
145559 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
145560 +
145561 + init_phase2();
145562 +
145563 + init_phase3();
145564 +
145565 + preempt_disable();
145566 + if (special_handler->processor_id == smp_processor_id())
145567 + send_first_frame(NULL);
145568 + else
145569 + smp_call_function_single(special_handler->processor_id,
145570 + send_first_frame, NULL, 1);
145571 + preempt_enable();
145572 +
145573 + wait_event(queue, loop_counter == HP_LOOPS);
145574 + deallocate_frame_data();
145575 + if (on_all_cpus(destroy_per_cpu_handlers))
145576 + panic("on_each_cpu() failed");
145577 + kmem_cache_destroy(hp_handler_slab);
145578 + pr_info("qman_test_hotpotato finished\n");
145579 +}
145580 --- /dev/null
145581 +++ b/drivers/staging/fsl_qbman/qman_utility.c
145582 @@ -0,0 +1,129 @@
145583 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
145584 + *
145585 + * Redistribution and use in source and binary forms, with or without
145586 + * modification, are permitted provided that the following conditions are met:
145587 + * * Redistributions of source code must retain the above copyright
145588 + * notice, this list of conditions and the following disclaimer.
145589 + * * Redistributions in binary form must reproduce the above copyright
145590 + * notice, this list of conditions and the following disclaimer in the
145591 + * documentation and/or other materials provided with the distribution.
145592 + * * Neither the name of Freescale Semiconductor nor the
145593 + * names of its contributors may be used to endorse or promote products
145594 + * derived from this software without specific prior written permission.
145595 + *
145596 + *
145597 + * ALTERNATIVELY, this software may be distributed under the terms of the
145598 + * GNU General Public License ("GPL") as published by the Free Software
145599 + * Foundation, either version 2 of that License or (at your option) any
145600 + * later version.
145601 + *
145602 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145603 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145604 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145605 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145606 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145607 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145608 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145609 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145610 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145611 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145612 + */
145613 +
145614 +#include "qman_private.h"
145615 +
145616 +/* ----------------- */
145617 +/* --- FQID Pool --- */
145618 +
145619 +struct qman_fqid_pool {
145620 + /* Base and size of the FQID range */
145621 + u32 fqid_base;
145622 + u32 total;
145623 + /* Number of FQIDs currently "allocated" */
145624 + u32 used;
145625 + /* Allocation optimisation. When 'used<total', it is the index of an
145626 + * available FQID. Otherwise there are no available FQIDs, and this
145627 + * will be set when the next deallocation occurs. */
145628 + u32 next;
145629 + /* A bit-field representation of the FQID range. */
145630 + unsigned long *bits;
145631 +};
145632 +
145633 +#define QLONG_BYTES sizeof(unsigned long)
145634 +#define QLONG_BITS (QLONG_BYTES * 8)
145635 +/* Number of 'longs' required for the given number of bits */
145636 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
145637 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
145638 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
145639 +/* And in bits */
145640 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
145641 +
145642 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
145643 +{
145644 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
145645 + unsigned int i;
145646 +
145647 + BUG_ON(!num);
145648 + if (!pool)
145649 + return NULL;
145650 + pool->fqid_base = fqid_start;
145651 + pool->total = num;
145652 + pool->used = 0;
145653 + pool->next = 0;
145654 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
145655 + if (!pool->bits) {
145656 + kfree(pool);
145657 + return NULL;
145658 + }
145659 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
145660 + * byte-oriented searching) then we fill the trailing bits with 1, to
145661 + * make them look allocated (permanently). */
145662 + for (i = num + 1; i < QNUM_BITS(num); i++)
145663 + set_bit(i, pool->bits);
145664 + return pool;
145665 +}
145666 +EXPORT_SYMBOL(qman_fqid_pool_create);
145667 +
145668 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
145669 +{
145670 + int ret = pool->used;
145671 + kfree(pool->bits);
145672 + kfree(pool);
145673 + return ret;
145674 +}
145675 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
145676 +
145677 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
145678 +{
145679 + int ret;
145680 + if (pool->used == pool->total)
145681 + return -ENOMEM;
145682 + *fqid = pool->fqid_base + pool->next;
145683 + ret = test_and_set_bit(pool->next, pool->bits);
145684 + BUG_ON(ret);
145685 + if (++pool->used == pool->total)
145686 + return 0;
145687 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
145688 + if (pool->next >= pool->total)
145689 + pool->next = find_first_zero_bit(pool->bits, pool->total);
145690 + BUG_ON(pool->next >= pool->total);
145691 + return 0;
145692 +}
145693 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
145694 +
145695 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
145696 +{
145697 + int ret;
145698 +
145699 + fqid -= pool->fqid_base;
145700 + ret = test_and_clear_bit(fqid, pool->bits);
145701 + BUG_ON(!ret);
145702 + if (pool->used-- == pool->total)
145703 + pool->next = fqid;
145704 +}
145705 +EXPORT_SYMBOL(qman_fqid_pool_free);
145706 +
145707 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
145708 +{
145709 + return pool->used;
145710 +}
145711 +EXPORT_SYMBOL(qman_fqid_pool_used);
145712 --- /dev/null
145713 +++ b/include/linux/fsl/svr.h
145714 @@ -0,0 +1,97 @@
145715 +/*
145716 + * MPC85xx cpu type detection
145717 + *
145718 + * Copyright 2011-2012 Freescale Semiconductor, Inc.
145719 + *
145720 + * This is free software; you can redistribute it and/or modify
145721 + * it under the terms of the GNU General Public License as published by
145722 + * the Free Software Foundation; either version 2 of the License, or
145723 + * (at your option) any later version.
145724 + */
145725 +
145726 +#ifndef FSL_SVR_H
145727 +#define FSL_SVR_H
145728 +
145729 +#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */
145730 +#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/
145731 +#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/
145732 +
145733 +/* Some parts define SVR[0:23] as the SOC version */
145734 +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */
145735 +
145736 +#define SVR_8533 0x803400
145737 +#define SVR_8535 0x803701
145738 +#define SVR_8536 0x803700
145739 +#define SVR_8540 0x803000
145740 +#define SVR_8541 0x807200
145741 +#define SVR_8543 0x803200
145742 +#define SVR_8544 0x803401
145743 +#define SVR_8545 0x803102
145744 +#define SVR_8547 0x803101
145745 +#define SVR_8548 0x803100
145746 +#define SVR_8555 0x807100
145747 +#define SVR_8560 0x807000
145748 +#define SVR_8567 0x807501
145749 +#define SVR_8568 0x807500
145750 +#define SVR_8569 0x808000
145751 +#define SVR_8572 0x80E000
145752 +#define SVR_P1010 0x80F100
145753 +#define SVR_P1011 0x80E500
145754 +#define SVR_P1012 0x80E501
145755 +#define SVR_P1013 0x80E700
145756 +#define SVR_P1014 0x80F101
145757 +#define SVR_P1017 0x80F700
145758 +#define SVR_P1020 0x80E400
145759 +#define SVR_P1021 0x80E401
145760 +#define SVR_P1022 0x80E600
145761 +#define SVR_P1023 0x80F600
145762 +#define SVR_P1024 0x80E402
145763 +#define SVR_P1025 0x80E403
145764 +#define SVR_P2010 0x80E300
145765 +#define SVR_P2020 0x80E200
145766 +#define SVR_P2040 0x821000
145767 +#define SVR_P2041 0x821001
145768 +#define SVR_P3041 0x821103
145769 +#define SVR_P4040 0x820100
145770 +#define SVR_P4080 0x820000
145771 +#define SVR_P5010 0x822100
145772 +#define SVR_P5020 0x822000
145773 +#define SVR_P5021 0X820500
145774 +#define SVR_P5040 0x820400
145775 +#define SVR_T4240 0x824000
145776 +#define SVR_T4120 0x824001
145777 +#define SVR_T4160 0x824100
145778 +#define SVR_T4080 0x824102
145779 +#define SVR_C291 0x850000
145780 +#define SVR_C292 0x850020
145781 +#define SVR_C293 0x850030
145782 +#define SVR_B4860 0X868000
145783 +#define SVR_G4860 0x868001
145784 +#define SVR_G4060 0x868003
145785 +#define SVR_B4440 0x868100
145786 +#define SVR_G4440 0x868101
145787 +#define SVR_B4420 0x868102
145788 +#define SVR_B4220 0x868103
145789 +#define SVR_T1040 0x852000
145790 +#define SVR_T1041 0x852001
145791 +#define SVR_T1042 0x852002
145792 +#define SVR_T1020 0x852100
145793 +#define SVR_T1021 0x852101
145794 +#define SVR_T1022 0x852102
145795 +#define SVR_T1023 0x854100
145796 +#define SVR_T1024 0x854000
145797 +#define SVR_T2080 0x853000
145798 +#define SVR_T2081 0x853100
145799 +
145800 +#define SVR_8610 0x80A000
145801 +#define SVR_8641 0x809000
145802 +#define SVR_8641D 0x809001
145803 +
145804 +#define SVR_9130 0x860001
145805 +#define SVR_9131 0x860000
145806 +#define SVR_9132 0x861000
145807 +#define SVR_9232 0x861400
145808 +
145809 +#define SVR_Unknown 0xFFFFFF
145810 +
145811 +#endif
145812 --- /dev/null
145813 +++ b/include/linux/fsl_bman.h
145814 @@ -0,0 +1,532 @@
145815 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
145816 + *
145817 + * Redistribution and use in source and binary forms, with or without
145818 + * modification, are permitted provided that the following conditions are met:
145819 + * * Redistributions of source code must retain the above copyright
145820 + * notice, this list of conditions and the following disclaimer.
145821 + * * Redistributions in binary form must reproduce the above copyright
145822 + * notice, this list of conditions and the following disclaimer in the
145823 + * documentation and/or other materials provided with the distribution.
145824 + * * Neither the name of Freescale Semiconductor nor the
145825 + * names of its contributors may be used to endorse or promote products
145826 + * derived from this software without specific prior written permission.
145827 + *
145828 + *
145829 + * ALTERNATIVELY, this software may be distributed under the terms of the
145830 + * GNU General Public License ("GPL") as published by the Free Software
145831 + * Foundation, either version 2 of that License or (at your option) any
145832 + * later version.
145833 + *
145834 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145835 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145836 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145837 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145838 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145839 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145840 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145841 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145842 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145843 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145844 + */
145845 +
145846 +#ifndef FSL_BMAN_H
145847 +#define FSL_BMAN_H
145848 +
145849 +#ifdef __cplusplus
145850 +extern "C" {
145851 +#endif
145852 +
145853 +/* Last updated for v00.79 of the BG */
145854 +
145855 +/* Portal processing (interrupt) sources */
145856 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
145857 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
145858 +
145859 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
145860 + * buffer pools. */
145861 +struct bman_depletion {
145862 + u32 __state[2];
145863 +};
145864 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
145865 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
145866 +#define __bmdep_word(x) ((x) >> 5)
145867 +#define __bmdep_shift(x) ((x) & 0x1f)
145868 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
145869 +static inline void bman_depletion_init(struct bman_depletion *c)
145870 +{
145871 + c->__state[0] = c->__state[1] = 0;
145872 +}
145873 +static inline void bman_depletion_fill(struct bman_depletion *c)
145874 +{
145875 + c->__state[0] = c->__state[1] = ~0;
145876 +}
145877 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
145878 +{
145879 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
145880 +}
145881 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
145882 +{
145883 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
145884 +}
145885 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
145886 +{
145887 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
145888 +}
145889 +
145890 +/* ------------------------------------------------------- */
145891 +/* --- Bman data structures (and associated constants) --- */
145892 +
145893 +/* Represents s/w corenet portal mapped data structures */
145894 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
145895 +struct bm_mc_command; /* MC (Management Command) command */
145896 +struct bm_mc_result; /* MC result */
145897 +
145898 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
145899 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
145900 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
145901 +struct bm_buffer {
145902 + union {
145903 + struct {
145904 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145905 + u8 __reserved1;
145906 + u8 bpid;
145907 + u16 hi; /* High 16-bits of 48-bit address */
145908 + u32 lo; /* Low 32-bits of 48-bit address */
145909 +#else
145910 + u32 lo;
145911 + u16 hi;
145912 + u8 bpid;
145913 + u8 __reserved;
145914 +#endif
145915 + };
145916 + struct {
145917 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145918 + u64 __notaddress:16;
145919 + u64 addr:48;
145920 +#else
145921 + u64 addr:48;
145922 + u64 __notaddress:16;
145923 +#endif
145924 + };
145925 + u64 opaque;
145926 + };
145927 +} __aligned(8);
145928 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
145929 +{
145930 + return buf->addr;
145931 +}
145932 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
145933 +{
145934 + return (dma_addr_t)buf->addr;
145935 +}
145936 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145937 +#define bm_buffer_set64(buf, v) \
145938 + do { \
145939 + struct bm_buffer *__buf931 = (buf); \
145940 + __buf931->hi = upper_32_bits(v); \
145941 + __buf931->lo = lower_32_bits(v); \
145942 + } while (0)
145943 +
145944 +/* See 1.5.3.5.4: "Release Command" */
145945 +struct bm_rcr_entry {
145946 + union {
145947 + struct {
145948 + u8 __dont_write_directly__verb;
145949 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
145950 + u8 __reserved1[62];
145951 + };
145952 + struct bm_buffer bufs[8];
145953 + };
145954 +} __packed;
145955 +#define BM_RCR_VERB_VBIT 0x80
145956 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
145957 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
145958 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
145959 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
145960 +
145961 +/* See 1.5.3.1: "Acquire Command" */
145962 +/* See 1.5.3.2: "Query Command" */
145963 +struct bm_mcc_acquire {
145964 + u8 bpid;
145965 + u8 __reserved1[62];
145966 +} __packed;
145967 +struct bm_mcc_query {
145968 + u8 __reserved2[63];
145969 +} __packed;
145970 +struct bm_mc_command {
145971 + u8 __dont_write_directly__verb;
145972 + union {
145973 + struct bm_mcc_acquire acquire;
145974 + struct bm_mcc_query query;
145975 + };
145976 +} __packed;
145977 +#define BM_MCC_VERB_VBIT 0x80
145978 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
145979 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
145980 +#define BM_MCC_VERB_CMD_QUERY 0x40
145981 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
145982 +
145983 +/* See 1.5.3.3: "Acquire Response" */
145984 +/* See 1.5.3.4: "Query Response" */
145985 +struct bm_pool_state {
145986 + u8 __reserved1[32];
145987 + /* "availability state" and "depletion state" */
145988 + struct {
145989 + u8 __reserved1[8];
145990 + /* Access using bman_depletion_***() */
145991 + struct bman_depletion state;
145992 + } as, ds;
145993 +};
145994 +struct bm_mc_result {
145995 + union {
145996 + struct {
145997 + u8 verb;
145998 + u8 __reserved1[63];
145999 + };
146000 + union {
146001 + struct {
146002 + u8 __reserved1;
146003 + u8 bpid;
146004 + u8 __reserved2[62];
146005 + };
146006 + struct bm_buffer bufs[8];
146007 + } acquire;
146008 + struct bm_pool_state query;
146009 + };
146010 +} __packed;
146011 +#define BM_MCR_VERB_VBIT 0x80
146012 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
146013 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
146014 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
146015 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
146016 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
146017 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
146018 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
146019 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
146020 + bman_depletion_get(&r->query.as.state, p)
146021 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
146022 +#define BM_MCR_QUERY_DEPLETION(r, p) \
146023 + bman_depletion_get(&r->query.ds.state, p)
146024 +
146025 +/*******************************************************************/
146026 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
146027 +/*******************************************************************/
146028 +
146029 + /* Portal and Buffer Pools */
146030 + /* ----------------------- */
146031 +/* Represents a managed portal */
146032 +struct bman_portal;
146033 +
146034 +/* This object type represents Bman buffer pools. */
146035 +struct bman_pool;
146036 +
146037 +struct bman_portal_config {
146038 + /* This is used for any "core-affine" portals, ie. default portals
146039 + * associated to the corresponding cpu. -1 implies that there is no core
146040 + * affinity configured. */
146041 + int cpu;
146042 + /* portal interrupt line */
146043 + int irq;
146044 + /* the unique index of this portal */
146045 + u32 index;
146046 + /* Is this portal shared? (If so, it has coarser locking and demuxes
146047 + * processing on behalf of other CPUs.) */
146048 + int is_shared;
146049 + /* These are the buffer pool IDs that may be used via this portal. */
146050 + struct bman_depletion mask;
146051 +};
146052 +
146053 +/* This callback type is used when handling pool depletion entry/exit. The
146054 + * 'cb_ctx' value is the opaque value associated with the pool object in
146055 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
146056 + * depletion-exit. */
146057 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
146058 + struct bman_pool *pool, void *cb_ctx, int depleted);
146059 +
146060 +/* This struct specifies parameters for a bman_pool object. */
146061 +struct bman_pool_params {
146062 + /* index of the buffer pool to encapsulate (0-63), ignored if
146063 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
146064 + u32 bpid;
146065 + /* bit-mask of BMAN_POOL_FLAG_*** options */
146066 + u32 flags;
146067 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
146068 + bman_cb_depletion cb;
146069 + /* opaque user value passed as a parameter to 'cb' */
146070 + void *cb_ctx;
146071 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
146072 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
146073 + * when run in the control plane (which controls Bman CCSR). This array
146074 + * matches the definition of bm_pool_set(). */
146075 + u32 thresholds[4];
146076 +};
146077 +
146078 +/* Flags to bman_new_pool() */
146079 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
146080 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
146081 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
146082 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
146083 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
146084 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
146085 +
146086 +/* Flags to bman_release() */
146087 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146088 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
146089 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
146090 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
146091 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
146092 +#endif
146093 +#endif
146094 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
146095 +
146096 +/* Flags to bman_acquire() */
146097 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
146098 +
146099 + /* Portal Management */
146100 + /* ----------------- */
146101 +/**
146102 + * bman_get_portal_config - get portal configuration settings
146103 + *
146104 + * This returns a read-only view of the current cpu's affine portal settings.
146105 + */
146106 +const struct bman_portal_config *bman_get_portal_config(void);
146107 +
146108 +/**
146109 + * bman_irqsource_get - return the portal work that is interrupt-driven
146110 + *
146111 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
146112 + * enabled for interrupt handling on the current cpu's affine portal. These
146113 + * sources will trigger the portal interrupt and the interrupt handler (or a
146114 + * tasklet/bottom-half it defers to) will perform the corresponding processing
146115 + * work. The bman_poll_***() functions will only process sources that are not in
146116 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
146117 + * this always returns zero.
146118 + */
146119 +u32 bman_irqsource_get(void);
146120 +
146121 +/**
146122 + * bman_irqsource_add - add processing sources to be interrupt-driven
146123 + * @bits: bitmask of BM_PIRQ_**I processing sources
146124 + *
146125 + * Adds processing sources that should be interrupt-driven (rather than
146126 + * processed via bman_poll_***() functions). Returns zero for success, or
146127 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
146128 +int bman_irqsource_add(u32 bits);
146129 +
146130 +/**
146131 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
146132 + * @bits: bitmask of BM_PIRQ_**I processing sources
146133 + *
146134 + * Removes processing sources from being interrupt-driven, so that they will
146135 + * instead be processed via bman_poll_***() functions. Returns zero for success,
146136 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
146137 +int bman_irqsource_remove(u32 bits);
146138 +
146139 +/**
146140 + * bman_affine_cpus - return a mask of cpus that have affine portals
146141 + */
146142 +const cpumask_t *bman_affine_cpus(void);
146143 +
146144 +/**
146145 + * bman_poll_slow - process anything that isn't interrupt-driven.
146146 + *
146147 + * This function does any portal processing that isn't interrupt-driven. If the
146148 + * current CPU is sharing a portal hosted on another CPU, this function will
146149 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
146150 + * indicating what interrupt sources were actually processed by the call.
146151 + *
146152 + * NB, unlike the legacy wrapper bman_poll(), this function will
146153 + * deterministically check for the presence of portal processing work and do it,
146154 + * which implies some latency even if there's nothing to do. The bman_poll()
146155 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
146156 + * checking for (and doing) portal processing infrequently. Ie. such that
146157 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
146158 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
146159 + * processing.
146160 + */
146161 +u32 bman_poll_slow(void);
146162 +
146163 +/**
146164 + * bman_poll - process anything that isn't interrupt-driven.
146165 + *
146166 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
146167 + * affine portal. This function does whatever processing is not triggered by
146168 + * interrupts. This is a legacy wrapper that can be used in core-processing
146169 + * loops but mitigates the performance overhead of portal processing by
146170 + * adaptively bypassing true portal processing most of the time. (Processing is
146171 + * done once every 10 calls if the previous processing revealed that work needed
146172 + * to be done, or once very 1000 calls if the previous processing revealed no
146173 + * work needed doing.) If you wish to control this yourself, call
146174 + * bman_poll_slow() instead, which always checks for portal processing work.
146175 + */
146176 +void bman_poll(void);
146177 +
146178 +/**
146179 + * bman_rcr_is_empty - Determine if portal's RCR is empty
146180 + *
146181 + * For use in situations where a cpu-affine caller needs to determine when all
146182 + * releases for the local portal have been processed by Bman but can't use the
146183 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
146184 + * The function forces tracking of RCR consumption (which normally doesn't
146185 + * happen until release processing needs to find space to put new release
146186 + * commands), and returns zero if the ring still has unprocessed entries,
146187 + * non-zero if it is empty.
146188 + */
146189 +int bman_rcr_is_empty(void);
146190 +
146191 +/**
146192 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
146193 + * @result: is set by the API to the base BPID of the allocated range
146194 + * @count: the number of BPIDs required
146195 + * @align: required alignment of the allocated range
146196 + * @partial: non-zero if the API can return fewer than @count BPIDs
146197 + *
146198 + * Returns the number of buffer pools allocated, or a negative error code. If
146199 + * @partial is non zero, the allocation request may return a smaller range of
146200 + * BPs than requested (though alignment will be as requested). If @partial is
146201 + * zero, the return value will either be 'count' or negative.
146202 + */
146203 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
146204 +static inline int bman_alloc_bpid(u32 *result)
146205 +{
146206 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
146207 + return (ret > 0) ? 0 : ret;
146208 +}
146209 +
146210 +/**
146211 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
146212 + * @bpid: the base BPID of the range to deallocate
146213 + * @count: the number of BPIDs in the range
146214 + *
146215 + * This function can also be used to seed the allocator with ranges of BPIDs
146216 + * that it can subsequently allocate from.
146217 + */
146218 +void bman_release_bpid_range(u32 bpid, unsigned int count);
146219 +static inline void bman_release_bpid(u32 bpid)
146220 +{
146221 + bman_release_bpid_range(bpid, 1);
146222 +}
146223 +
146224 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
146225 +static inline int bman_reserve_bpid(u32 bpid)
146226 +{
146227 + return bman_reserve_bpid_range(bpid, 1);
146228 +}
146229 +
146230 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
146231 +
146232 +
146233 +int bman_shutdown_pool(u32 bpid);
146234 +
146235 + /* Pool management */
146236 + /* --------------- */
146237 +/**
146238 + * bman_new_pool - Allocates a Buffer Pool object
146239 + * @params: parameters specifying the buffer pool ID and behaviour
146240 + *
146241 + * Creates a pool object for the given @params. A portal and the depletion
146242 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
146243 + * is set. NB, the fields from @params are copied into the new pool object, so
146244 + * the structure provided by the caller can be released or reused after the
146245 + * function returns.
146246 + */
146247 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
146248 +
146249 +/**
146250 + * bman_free_pool - Deallocates a Buffer Pool object
146251 + * @pool: the pool object to release
146252 + *
146253 + */
146254 +void bman_free_pool(struct bman_pool *pool);
146255 +
146256 +/**
146257 + * bman_get_params - Returns a pool object's parameters.
146258 + * @pool: the pool object
146259 + *
146260 + * The returned pointer refers to state within the pool object so must not be
146261 + * modified and can no longer be read once the pool object is destroyed.
146262 + */
146263 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
146264 +
146265 +/**
146266 + * bman_release - Release buffer(s) to the buffer pool
146267 + * @pool: the buffer pool object to release to
146268 + * @bufs: an array of buffers to release
146269 + * @num: the number of buffers in @bufs (1-8)
146270 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
146271 + *
146272 + * Adds the given buffers to RCR entries. If the portal @p was created with the
146273 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
146274 + * utilisation of RCR. As such, these buffers may join an existing ring entry
146275 + * and/or it may not be issued right away so as to allow future releases to join
146276 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
146277 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
146278 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
146279 + * is selected, in which case it will sleep waiting for space to become
146280 + * available in RCR. If the function receives a signal before such time (and
146281 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
146282 + * it returns zero.
146283 + */
146284 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
146285 + u32 flags);
146286 +
146287 +/**
146288 + * bman_acquire - Acquire buffer(s) from a buffer pool
146289 + * @pool: the buffer pool object to acquire from
146290 + * @bufs: array for storing the acquired buffers
146291 + * @num: the number of buffers desired (@bufs is at least this big)
146292 + *
146293 + * Issues an "Acquire" command via the portal's management command interface.
146294 + * The return value will be the number of buffers obtained from the pool, or a
146295 + * negative error code if a h/w error or pool starvation was encountered. In
146296 + * the latter case, the content of @bufs is undefined.
146297 + */
146298 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
146299 + u32 flags);
146300 +
146301 +/**
146302 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
146303 + * @pool: the buffer pool object the stockpile belongs
146304 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
146305 + *
146306 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
146307 + * The return value will be a negative error code if a h/w error occurred.
146308 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
146309 + * -EAGAIN will be returned.
146310 + */
146311 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
146312 +
146313 +/**
146314 + * bman_query_pools - Query all buffer pool states
146315 + * @state: storage for the queried availability and depletion states
146316 + */
146317 +int bman_query_pools(struct bm_pool_state *state);
146318 +
146319 +#ifdef CONFIG_FSL_BMAN_CONFIG
146320 +/**
146321 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
146322 + * @pool: the buffer pool object to query
146323 + *
146324 + * Return the number of the free buffers
146325 + */
146326 +u32 bman_query_free_buffers(struct bman_pool *pool);
146327 +
146328 +/**
146329 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
146330 + * @pool: the buffer pool object to which the thresholds will be set
146331 + * @thresholds: the new thresholds
146332 + */
146333 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
146334 +#endif
146335 +
146336 +/**
146337 + * The below bman_p_***() variant might be called in a situation that the cpu
146338 + * which the portal affine to is not online yet.
146339 + * @bman_portal specifies which portal the API will use.
146340 +*/
146341 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
146342 +#ifdef __cplusplus
146343 +}
146344 +#endif
146345 +
146346 +#endif /* FSL_BMAN_H */
146347 --- /dev/null
146348 +++ b/include/linux/fsl_qman.h
146349 @@ -0,0 +1,3900 @@
146350 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
146351 + *
146352 + * Redistribution and use in source and binary forms, with or without
146353 + * modification, are permitted provided that the following conditions are met:
146354 + * * Redistributions of source code must retain the above copyright
146355 + * notice, this list of conditions and the following disclaimer.
146356 + * * Redistributions in binary form must reproduce the above copyright
146357 + * notice, this list of conditions and the following disclaimer in the
146358 + * documentation and/or other materials provided with the distribution.
146359 + * * Neither the name of Freescale Semiconductor nor the
146360 + * names of its contributors may be used to endorse or promote products
146361 + * derived from this software without specific prior written permission.
146362 + *
146363 + *
146364 + * ALTERNATIVELY, this software may be distributed under the terms of the
146365 + * GNU General Public License ("GPL") as published by the Free Software
146366 + * Foundation, either version 2 of that License or (at your option) any
146367 + * later version.
146368 + *
146369 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
146370 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
146371 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
146372 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
146373 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
146374 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
146375 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
146376 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
146377 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
146378 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146379 + */
146380 +
146381 +#ifndef FSL_QMAN_H
146382 +#define FSL_QMAN_H
146383 +
146384 +#ifdef __cplusplus
146385 +extern "C" {
146386 +#endif
146387 +
146388 +/* Last updated for v00.800 of the BG */
146389 +
146390 +/* Hardware constants */
146391 +#define QM_CHANNEL_SWPORTAL0 0
146392 +#define QMAN_CHANNEL_POOL1 0x21
146393 +#define QMAN_CHANNEL_CAAM 0x80
146394 +#define QMAN_CHANNEL_PME 0xa0
146395 +#define QMAN_CHANNEL_POOL1_REV3 0x401
146396 +#define QMAN_CHANNEL_CAAM_REV3 0x840
146397 +#define QMAN_CHANNEL_PME_REV3 0x860
146398 +#define QMAN_CHANNEL_DCE 0x8a0
146399 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
146400 +extern u16 qm_channel_pool1;
146401 +extern u16 qm_channel_caam;
146402 +extern u16 qm_channel_pme;
146403 +extern u16 qm_channel_dce;
146404 +enum qm_dc_portal {
146405 + qm_dc_portal_fman0 = 0,
146406 + qm_dc_portal_fman1 = 1,
146407 + qm_dc_portal_caam = 2,
146408 + qm_dc_portal_pme = 3,
146409 + qm_dc_portal_rman = 4,
146410 + qm_dc_portal_dce = 5
146411 +};
146412 +
146413 +/* Portal processing (interrupt) sources */
146414 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
146415 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
146416 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
146417 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
146418 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
146419 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
146420 +/* This mask contains all the interrupt sources that need handling except DQRI,
146421 + * ie. that if present should trigger slow-path processing. */
146422 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
146423 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
146424 +
146425 +/* --- Clock speed --- */
146426 +/* A qman driver instance may or may not know the current qman clock speed.
146427 + * However, certain CEETM calculations may not be possible if this is not known.
146428 + * The 'set' function will only succeed (return zero) if the driver did not
146429 + * already know the clock speed. Likewise, the 'get' function will only succeed
146430 + * if the driver does know the clock speed (either because it knew when booting,
146431 + * or was told via 'set'). In cases where software is running on a driver
146432 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
146433 + * and the user can obtain the current qman clock speed by other means (eg. from
146434 + * a message sent from the control-plane), then the 'set' function can be used
146435 + * to enable rate-calculations in a driver where it would otherwise not be
146436 + * possible. */
146437 +int qm_get_clock(u64 *clock_hz);
146438 +int qm_set_clock(u64 clock_hz);
146439 +
146440 +/* For qman_static_dequeue_*** APIs */
146441 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
146442 +/* for n in [1,15] */
146443 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
146444 +/* for conversion from n of qm_channel */
146445 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
146446 +{
146447 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
146448 +}
146449 +
146450 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
146451 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
146452 + * FQID(n) to fill in the frame queue ID. */
146453 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
146454 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
146455 +#define QM_VDQCR_EXACT 0x40000000
146456 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
146457 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
146458 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
146459 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
146460 +
146461 +
146462 +/* ------------------------------------------------------- */
146463 +/* --- Qman data structures (and associated constants) --- */
146464 +
146465 +/* Represents s/w corenet portal mapped data structures */
146466 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
146467 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
146468 +struct qm_mr_entry; /* MR (Message Ring) entries */
146469 +struct qm_mc_command; /* MC (Management Command) command */
146470 +struct qm_mc_result; /* MC result */
146471 +
146472 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
146473 +#define QM_FD_FORMAT_SG 0x4
146474 +#define QM_FD_FORMAT_LONG 0x2
146475 +#define QM_FD_FORMAT_COMPOUND 0x1
146476 +enum qm_fd_format {
146477 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
146478 + * scatter-gather table. 'big' implies a 29-bit length with no offset
146479 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
146480 + * implies a s/g-like table, where each entry itself represents a frame
146481 + * (contiguous or scatter-gather) and the 29-bit "length" is
146482 + * interpreted purely for congestion calculations, ie. a "congestion
146483 + * weight". */
146484 + qm_fd_contig = 0,
146485 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
146486 + qm_fd_sg = QM_FD_FORMAT_SG,
146487 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
146488 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
146489 +};
146490 +
146491 +/* Capitalised versions are un-typed but can be used in static expressions */
146492 +#define QM_FD_CONTIG 0
146493 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
146494 +#define QM_FD_SG QM_FD_FORMAT_SG
146495 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
146496 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
146497 +
146498 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
146499 +struct qm_fd {
146500 + union {
146501 + struct {
146502 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146503 + u8 dd:2; /* dynamic debug */
146504 + u8 liodn_offset:6;
146505 + u8 bpid:8; /* Buffer Pool ID */
146506 + u8 eliodn_offset:4;
146507 + u8 __reserved:4;
146508 + u8 addr_hi; /* high 8-bits of 40-bit address */
146509 + u32 addr_lo; /* low 32-bits of 40-bit address */
146510 +#else
146511 + u32 addr_lo; /* low 32-bits of 40-bit address */
146512 + u8 addr_hi; /* high 8-bits of 40-bit address */
146513 + u8 __reserved:4;
146514 + u8 eliodn_offset:4;
146515 + u8 bpid:8; /* Buffer Pool ID */
146516 + u8 liodn_offset:6;
146517 + u8 dd:2; /* dynamic debug */
146518 +#endif
146519 + };
146520 + struct {
146521 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146522 + u64 __notaddress:24;
146523 + u64 addr:40;
146524 +#else
146525 + u64 addr:40;
146526 + u64 __notaddress:24;
146527 +#endif
146528 + };
146529 + u64 opaque_addr;
146530 + };
146531 + /* The 'format' field indicates the interpretation of the remaining 29
146532 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
146533 + * other union elements. Note, union'd structs are difficult to use with
146534 + * static initialisation under gcc, in which case use the "opaque" form
146535 + * with one of the macros. */
146536 + union {
146537 + /* For easier/faster copying of this part of the fd (eg. from a
146538 + * DQRR entry to an EQCR entry) copy 'opaque' */
146539 + u32 opaque;
146540 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
146541 + struct {
146542 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146543 + enum qm_fd_format format:3;
146544 + u16 offset:9;
146545 + u32 length20:20;
146546 +#else
146547 + u32 length20:20;
146548 + u16 offset:9;
146549 + enum qm_fd_format format:3;
146550 +#endif
146551 + };
146552 + /* If 'format' is _contig_big or _sg_big, 29b length */
146553 + struct {
146554 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146555 + enum qm_fd_format _format1:3;
146556 + u32 length29:29;
146557 +#else
146558 + u32 length29:29;
146559 + enum qm_fd_format _format1:3;
146560 +#endif
146561 + };
146562 + /* If 'format' is _compound, 29b "congestion weight" */
146563 + struct {
146564 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146565 + enum qm_fd_format _format2:3;
146566 + u32 cong_weight:29;
146567 +#else
146568 + u32 cong_weight:29;
146569 + enum qm_fd_format _format2:3;
146570 +#endif
146571 + };
146572 + };
146573 + union {
146574 + u32 cmd;
146575 + u32 status;
146576 + };
146577 +} __aligned(8);
146578 +#define QM_FD_DD_NULL 0x00
146579 +#define QM_FD_PID_MASK 0x3f
146580 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
146581 +{
146582 + return fd->addr;
146583 +}
146584 +
146585 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
146586 +{
146587 + return (dma_addr_t)fd->addr;
146588 +}
146589 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146590 +#define qm_fd_addr_set64(fd, v) \
146591 + do { \
146592 + struct qm_fd *__fd931 = (fd); \
146593 + __fd931->addr = v; \
146594 + } while (0)
146595 +
146596 +/* For static initialisation of FDs (which is complicated by the use of unions
146597 + * in "struct qm_fd"), use the following macros. Note that;
146598 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
146599 + * use-case),
146600 + * - use capitalised QM_FD_*** formats for static initialisation.
146601 + */
146602 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
146603 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
146604 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
146605 + { cmd } }
146606 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
146607 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
146608 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
146609 + { cmd } }
146610 +
146611 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
146612 +#define QM_SG_OFFSET_MASK 0x1FFF
146613 +struct qm_sg_entry {
146614 + union {
146615 + struct {
146616 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146617 + u8 __reserved1[3];
146618 + u8 addr_hi; /* high 8-bits of 40-bit address */
146619 + u32 addr_lo; /* low 32-bits of 40-bit address */
146620 +#else
146621 + u32 addr_lo; /* low 32-bits of 40-bit address */
146622 + u8 addr_hi; /* high 8-bits of 40-bit address */
146623 + u8 __reserved1[3];
146624 +#endif
146625 + };
146626 + struct {
146627 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146628 + u64 __notaddress:24;
146629 + u64 addr:40;
146630 +#else
146631 + u64 addr:40;
146632 + u64 __notaddress:24;
146633 +#endif
146634 + };
146635 + u64 opaque;
146636 + };
146637 + union {
146638 + struct {
146639 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146640 + u32 extension:1; /* Extension bit */
146641 + u32 final:1; /* Final bit */
146642 + u32 length:30;
146643 +#else
146644 + u32 length:30;
146645 + u32 final:1; /* Final bit */
146646 + u32 extension:1; /* Extension bit */
146647 +#endif
146648 + };
146649 + u32 sgt_efl;
146650 + };
146651 + u8 __reserved2;
146652 + u8 bpid;
146653 + union {
146654 + struct {
146655 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146656 + u16 __reserved3:3;
146657 + u16 offset:13;
146658 +#else
146659 + u16 offset:13;
146660 + u16 __reserved3:3;
146661 +#endif
146662 + };
146663 + u16 opaque_offset;
146664 + };
146665 +} __packed;
146666 +union qm_sg_efl {
146667 + struct {
146668 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146669 + u32 extension:1; /* Extension bit */
146670 + u32 final:1; /* Final bit */
146671 + u32 length:30;
146672 +#else
146673 + u32 length:30;
146674 + u32 final:1; /* Final bit */
146675 + u32 extension:1; /* Extension bit */
146676 +#endif
146677 + };
146678 + u32 efl;
146679 +};
146680 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
146681 +{
146682 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
146683 +}
146684 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
146685 +{
146686 + union qm_sg_efl u;
146687 +
146688 + u.efl = be32_to_cpu(sg->sgt_efl);
146689 + return u.extension;
146690 +}
146691 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
146692 +{
146693 + union qm_sg_efl u;
146694 +
146695 + u.efl = be32_to_cpu(sg->sgt_efl);
146696 + return u.final;
146697 +}
146698 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
146699 +{
146700 + union qm_sg_efl u;
146701 +
146702 + u.efl = be32_to_cpu(sg->sgt_efl);
146703 + return u.length;
146704 +}
146705 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
146706 +{
146707 + return sg->bpid;
146708 +}
146709 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
146710 +{
146711 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
146712 +
146713 + return opaque_offset & 0x1fff;
146714 +}
146715 +
146716 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146717 +#define qm_sg_entry_set64(sg, v) \
146718 + do { \
146719 + struct qm_sg_entry *__sg931 = (sg); \
146720 + __sg931->opaque = cpu_to_be64(v); \
146721 + } while (0)
146722 +#define qm_sg_entry_set_ext(sg, v) \
146723 + do { \
146724 + union qm_sg_efl __u932; \
146725 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
146726 + __u932.extension = v; \
146727 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
146728 + } while (0)
146729 +#define qm_sg_entry_set_final(sg, v) \
146730 + do { \
146731 + union qm_sg_efl __u933; \
146732 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
146733 + __u933.final = v; \
146734 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
146735 + } while (0)
146736 +#define qm_sg_entry_set_len(sg, v) \
146737 + do { \
146738 + union qm_sg_efl __u934; \
146739 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
146740 + __u934.length = v; \
146741 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
146742 + } while (0)
146743 +#define qm_sg_entry_set_bpid(sg, v) \
146744 + do { \
146745 + struct qm_sg_entry *__u935 = (sg); \
146746 + __u935->bpid = v; \
146747 + } while (0)
146748 +#define qm_sg_entry_set_offset(sg, v) \
146749 + do { \
146750 + struct qm_sg_entry *__u936 = (sg); \
146751 + __u936->opaque_offset = cpu_to_be16(v); \
146752 + } while (0)
146753 +
146754 +/* See 1.5.8.1: "Enqueue Command" */
146755 +struct qm_eqcr_entry {
146756 + u8 __dont_write_directly__verb;
146757 + u8 dca;
146758 + u16 seqnum;
146759 + u32 orp; /* 24-bit */
146760 + u32 fqid; /* 24-bit */
146761 + u32 tag;
146762 + struct qm_fd fd;
146763 + u8 __reserved3[32];
146764 +} __packed;
146765 +#define QM_EQCR_VERB_VBIT 0x80
146766 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
146767 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
146768 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
146769 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
146770 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
146771 +#define QM_EQCR_VERB_COLOUR_RED 0x10
146772 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
146773 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
146774 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
146775 +#define QM_EQCR_DCA_ENABLE 0x80
146776 +#define QM_EQCR_DCA_PARK 0x40
146777 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
146778 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
146779 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
146780 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
146781 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
146782 +
146783 +/* See 1.5.8.2: "Frame Dequeue Response" */
146784 +struct qm_dqrr_entry {
146785 + u8 verb;
146786 + u8 stat;
146787 + u16 seqnum; /* 15-bit */
146788 + u8 tok;
146789 + u8 __reserved2[3];
146790 + u32 fqid; /* 24-bit */
146791 + u32 contextB;
146792 + struct qm_fd fd;
146793 + u8 __reserved4[32];
146794 +};
146795 +#define QM_DQRR_VERB_VBIT 0x80
146796 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
146797 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
146798 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
146799 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
146800 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
146801 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
146802 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
146803 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
146804 +
146805 +/* See 1.5.8.3: "ERN Message Response" */
146806 +/* See 1.5.8.4: "FQ State Change Notification" */
146807 +struct qm_mr_entry {
146808 + u8 verb;
146809 + union {
146810 + struct {
146811 + u8 dca;
146812 + u16 seqnum;
146813 + u8 rc; /* Rejection Code */
146814 + u32 orp:24;
146815 + u32 fqid; /* 24-bit */
146816 + u32 tag;
146817 + struct qm_fd fd;
146818 + } __packed ern;
146819 + struct {
146820 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146821 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
146822 + u8 __reserved1:3;
146823 + enum qm_dc_portal portal:3;
146824 +#else
146825 + enum qm_dc_portal portal:3;
146826 + u8 __reserved1:3;
146827 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
146828 +#endif
146829 + u16 __reserved2;
146830 + u8 rc; /* Rejection Code */
146831 + u32 __reserved3:24;
146832 + u32 fqid; /* 24-bit */
146833 + u32 tag;
146834 + struct qm_fd fd;
146835 + } __packed dcern;
146836 + struct {
146837 + u8 fqs; /* Frame Queue Status */
146838 + u8 __reserved1[6];
146839 + u32 fqid; /* 24-bit */
146840 + u32 contextB;
146841 + u8 __reserved2[16];
146842 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
146843 + };
146844 + u8 __reserved2[32];
146845 +} __packed;
146846 +#define QM_MR_VERB_VBIT 0x80
146847 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
146848 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
146849 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
146850 + * the other MR types by noting if the 0x20 bit is unset. */
146851 +#define QM_MR_VERB_TYPE_MASK 0x27
146852 +#define QM_MR_VERB_DC_ERN 0x20
146853 +#define QM_MR_VERB_FQRN 0x21
146854 +#define QM_MR_VERB_FQRNI 0x22
146855 +#define QM_MR_VERB_FQRL 0x23
146856 +#define QM_MR_VERB_FQPN 0x24
146857 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
146858 +#define QM_MR_RC_CGR_TAILDROP 0x00
146859 +#define QM_MR_RC_WRED 0x10
146860 +#define QM_MR_RC_ERROR 0x20
146861 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
146862 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
146863 +#define QM_MR_RC_FQ_TAILDROP 0x50
146864 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
146865 +#define QM_MR_RC_ORP_ZERO 0x70
146866 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
146867 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
146868 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
146869 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
146870 +#define QM_MR_DCERN_COLOUR_RED 0x02
146871 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
146872 +
146873 +/* An identical structure of FQD fields is present in the "Init FQ" command and
146874 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
146875 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
146876 + * latter has two inlines to assist with converting to/from the mant+exp
146877 + * representation. */
146878 +struct qm_fqd_stashing {
146879 + /* See QM_STASHING_EXCL_<...> */
146880 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146881 + u8 exclusive;
146882 + u8 __reserved1:2;
146883 + /* Numbers of cachelines */
146884 + u8 annotation_cl:2;
146885 + u8 data_cl:2;
146886 + u8 context_cl:2;
146887 +#else
146888 + u8 context_cl:2;
146889 + u8 data_cl:2;
146890 + u8 annotation_cl:2;
146891 + u8 __reserved1:2;
146892 + u8 exclusive;
146893 +#endif
146894 +} __packed;
146895 +struct qm_fqd_taildrop {
146896 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146897 + u16 __reserved1:3;
146898 + u16 mant:8;
146899 + u16 exp:5;
146900 +#else
146901 + u16 exp:5;
146902 + u16 mant:8;
146903 + u16 __reserved1:3;
146904 +#endif
146905 +} __packed;
146906 +struct qm_fqd_oac {
146907 + /* See QM_OAC_<...> */
146908 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146909 + u8 oac:2; /* "Overhead Accounting Control" */
146910 + u8 __reserved1:6;
146911 +#else
146912 + u8 __reserved1:6;
146913 + u8 oac:2; /* "Overhead Accounting Control" */
146914 +#endif
146915 + /* Two's-complement value (-128 to +127) */
146916 + signed char oal; /* "Overhead Accounting Length" */
146917 +} __packed;
146918 +struct qm_fqd {
146919 + union {
146920 + u8 orpc;
146921 + struct {
146922 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146923 + u8 __reserved1:2;
146924 + u8 orprws:3;
146925 + u8 oa:1;
146926 + u8 olws:2;
146927 +#else
146928 + u8 olws:2;
146929 + u8 oa:1;
146930 + u8 orprws:3;
146931 + u8 __reserved1:2;
146932 +#endif
146933 + } __packed;
146934 + };
146935 + u8 cgid;
146936 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
146937 + union {
146938 + u16 dest_wq;
146939 + struct {
146940 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146941 + u16 channel:13; /* qm_channel */
146942 + u16 wq:3;
146943 +#else
146944 + u16 wq:3;
146945 + u16 channel:13; /* qm_channel */
146946 +#endif
146947 + } __packed dest;
146948 + };
146949 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146950 + u16 __reserved2:1;
146951 + u16 ics_cred:15;
146952 +#else
146953 + u16 __reserved2:1;
146954 + u16 ics_cred:15;
146955 +#endif
146956 + /* For "Initialize Frame Queue" commands, the write-enable mask
146957 + * determines whether 'td' or 'oac_init' is observed. For query
146958 + * commands, this field is always 'td', and 'oac_query' (below) reflects
146959 + * the Overhead ACcounting values. */
146960 + union {
146961 + struct qm_fqd_taildrop td;
146962 + struct qm_fqd_oac oac_init;
146963 + };
146964 + u32 context_b;
146965 + union {
146966 + /* Treat it as 64-bit opaque */
146967 + u64 opaque;
146968 + struct {
146969 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146970 + u32 hi;
146971 + u32 lo;
146972 +#else
146973 + u32 lo;
146974 + u32 hi;
146975 +#endif
146976 + };
146977 + /* Treat it as s/w portal stashing config */
146978 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
146979 + struct {
146980 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146981 + struct qm_fqd_stashing stashing;
146982 + /* 48-bit address of FQ context to
146983 + * stash, must be cacheline-aligned */
146984 + u16 context_hi;
146985 + u32 context_lo;
146986 +#else
146987 + u32 context_lo;
146988 + u16 context_hi;
146989 + struct qm_fqd_stashing stashing;
146990 +#endif
146991 + } __packed;
146992 + } context_a;
146993 + struct qm_fqd_oac oac_query;
146994 +} __packed;
146995 +/* 64-bit converters for context_hi/lo */
146996 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
146997 +{
146998 + return ((u64)fqd->context_a.context_hi << 32) |
146999 + (u64)fqd->context_a.context_lo;
147000 +}
147001 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
147002 +{
147003 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
147004 +}
147005 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
147006 +{
147007 + return ((u64)fqd->context_a.hi << 32) |
147008 + (u64)fqd->context_a.lo;
147009 +}
147010 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
147011 +#define qm_fqd_stashing_set64(fqd, v) \
147012 + do { \
147013 + struct qm_fqd *__fqd931 = (fqd); \
147014 + __fqd931->context_a.context_hi = upper_32_bits(v); \
147015 + __fqd931->context_a.context_lo = lower_32_bits(v); \
147016 + } while (0)
147017 +#define qm_fqd_context_a_set64(fqd, v) \
147018 + do { \
147019 + struct qm_fqd *__fqd931 = (fqd); \
147020 + __fqd931->context_a.hi = upper_32_bits(v); \
147021 + __fqd931->context_a.lo = lower_32_bits(v); \
147022 + } while (0)
147023 +/* convert a threshold value into mant+exp representation */
147024 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
147025 + int roundup)
147026 +{
147027 + u32 e = 0;
147028 + int oddbit = 0;
147029 + if (val > 0xe0000000)
147030 + return -ERANGE;
147031 + while (val > 0xff) {
147032 + oddbit = val & 1;
147033 + val >>= 1;
147034 + e++;
147035 + if (roundup && oddbit)
147036 + val++;
147037 + }
147038 + td->exp = e;
147039 + td->mant = val;
147040 + return 0;
147041 +}
147042 +/* and the other direction */
147043 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
147044 +{
147045 + return (u32)td->mant << td->exp;
147046 +}
147047 +
147048 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
147049 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
147050 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
147051 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
147052 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
147053 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
147054 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
147055 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
147056 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
147057 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
147058 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
147059 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
147060 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
147061 +
147062 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
147063 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
147064 +#define QM_STASHING_EXCL_ANNOTATION 0x04
147065 +#define QM_STASHING_EXCL_DATA 0x02
147066 +#define QM_STASHING_EXCL_CTX 0x01
147067 +
147068 +/* See 1.5.5.3: "Intra Class Scheduling" */
147069 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
147070 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
147071 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
147072 +
147073 +/* See 1.5.8.4: "FQ State Change Notification" */
147074 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
147075 + * and associated commands/responses. The WRED parameters are calculated from
147076 + * these fields as follows;
147077 + * MaxTH = MA * (2 ^ Mn)
147078 + * Slope = SA / (2 ^ Sn)
147079 + * MaxP = 4 * (Pn + 1)
147080 + */
147081 +struct qm_cgr_wr_parm {
147082 + union {
147083 + u32 word;
147084 + struct {
147085 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147086 + u32 MA:8;
147087 + u32 Mn:5;
147088 + u32 SA:7; /* must be between 64-127 */
147089 + u32 Sn:6;
147090 + u32 Pn:6;
147091 +#else
147092 + u32 Pn:6;
147093 + u32 Sn:6;
147094 + u32 SA:7; /* must be between 64-127 */
147095 + u32 Mn:5;
147096 + u32 MA:8;
147097 +#endif
147098 + } __packed;
147099 + };
147100 +} __packed;
147101 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
147102 + * management commands, this is padded to a 16-bit structure field, so that's
147103 + * how we represent it here. The congestion state threshold is calculated from
147104 + * these fields as follows;
147105 + * CS threshold = TA * (2 ^ Tn)
147106 + */
147107 +struct qm_cgr_cs_thres {
147108 + union {
147109 + u16 hword;
147110 + struct {
147111 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147112 + u16 __reserved:3;
147113 + u16 TA:8;
147114 + u16 Tn:5;
147115 +#else
147116 + u16 Tn:5;
147117 + u16 TA:8;
147118 + u16 __reserved:3;
147119 +#endif
147120 + } __packed;
147121 + };
147122 +} __packed;
147123 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
147124 + * commands and the "Query CGR" result. It's suctioned out here into its own
147125 + * struct. */
147126 +struct __qm_mc_cgr {
147127 + struct qm_cgr_wr_parm wr_parm_g;
147128 + struct qm_cgr_wr_parm wr_parm_y;
147129 + struct qm_cgr_wr_parm wr_parm_r;
147130 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
147131 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
147132 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
147133 + u8 cscn_en; /* boolean, use QM_CGR_EN */
147134 + union {
147135 + struct {
147136 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147137 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
147138 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
147139 +#else
147140 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
147141 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
147142 +#endif
147143 + };
147144 + u32 cscn_targ; /* use QM_CGR_TARG_* */
147145 + };
147146 + u8 cstd_en; /* boolean, use QM_CGR_EN */
147147 + u8 cs; /* boolean, only used in query response */
147148 + union {
147149 + /* use qm_cgr_cs_thres_set64() */
147150 + struct qm_cgr_cs_thres cs_thres;
147151 + u16 __cs_thres;
147152 + };
147153 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
147154 +} __packed;
147155 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
147156 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
147157 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
147158 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
147159 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
147160 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
147161 +/* Convert CGR thresholds to/from "cs_thres" format */
147162 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
147163 +{
147164 + return (u64)th->TA << th->Tn;
147165 +}
147166 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
147167 + int roundup)
147168 +{
147169 + u32 e = 0;
147170 + int oddbit = 0;
147171 + while (val > 0xff) {
147172 + oddbit = val & 1;
147173 + val >>= 1;
147174 + e++;
147175 + if (roundup && oddbit)
147176 + val++;
147177 + }
147178 + th->Tn = e;
147179 + th->TA = val;
147180 + return 0;
147181 +}
147182 +
147183 +/* See 1.5.8.5.1: "Initialize FQ" */
147184 +/* See 1.5.8.5.2: "Query FQ" */
147185 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
147186 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
147187 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
147188 +/* See 1.5.8.6.2: "CGR Test Write" */
147189 +/* See 1.5.8.6.3: "Query CGR" */
147190 +/* See 1.5.8.6.4: "Query Congestion Group State" */
147191 +struct qm_mcc_initfq {
147192 + u8 __reserved1;
147193 + u16 we_mask; /* Write Enable Mask */
147194 + u32 fqid; /* 24-bit */
147195 + u16 count; /* Initialises 'count+1' FQDs */
147196 + struct qm_fqd fqd; /* the FQD fields go here */
147197 + u8 __reserved3[30];
147198 +} __packed;
147199 +struct qm_mcc_queryfq {
147200 + u8 __reserved1[3];
147201 + u32 fqid; /* 24-bit */
147202 + u8 __reserved2[56];
147203 +} __packed;
147204 +struct qm_mcc_queryfq_np {
147205 + u8 __reserved1[3];
147206 + u32 fqid; /* 24-bit */
147207 + u8 __reserved2[56];
147208 +} __packed;
147209 +struct qm_mcc_alterfq {
147210 + u8 __reserved1[3];
147211 + u32 fqid; /* 24-bit */
147212 + u8 __reserved2;
147213 + u8 count; /* number of consecutive FQID */
147214 + u8 __reserved3[10];
147215 + u32 context_b; /* frame queue context b */
147216 + u8 __reserved4[40];
147217 +} __packed;
147218 +struct qm_mcc_initcgr {
147219 + u8 __reserved1;
147220 + u16 we_mask; /* Write Enable Mask */
147221 + struct __qm_mc_cgr cgr; /* CGR fields */
147222 + u8 __reserved2[2];
147223 + u8 cgid;
147224 + u8 __reserved4[32];
147225 +} __packed;
147226 +struct qm_mcc_cgrtestwrite {
147227 + u8 __reserved1[2];
147228 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
147229 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
147230 + u8 __reserved2[23];
147231 + u8 cgid;
147232 + u8 __reserved3[32];
147233 +} __packed;
147234 +struct qm_mcc_querycgr {
147235 + u8 __reserved1[30];
147236 + u8 cgid;
147237 + u8 __reserved2[32];
147238 +} __packed;
147239 +struct qm_mcc_querycongestion {
147240 + u8 __reserved[63];
147241 +} __packed;
147242 +struct qm_mcc_querywq {
147243 + u8 __reserved;
147244 + /* select channel if verb != QUERYWQ_DEDICATED */
147245 + union {
147246 + u16 channel_wq; /* ignores wq (3 lsbits) */
147247 + struct {
147248 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147249 + u16 id:13; /* qm_channel */
147250 + u16 __reserved1:3;
147251 +#else
147252 + u16 __reserved1:3;
147253 + u16 id:13; /* qm_channel */
147254 +#endif
147255 + } __packed channel;
147256 + };
147257 + u8 __reserved2[60];
147258 +} __packed;
147259 +
147260 +struct qm_mcc_ceetm_lfqmt_config {
147261 + u8 __reserved1[4];
147262 + u32 lfqid:24;
147263 + u8 __reserved2[2];
147264 + u16 cqid;
147265 + u8 __reserved3[2];
147266 + u16 dctidx;
147267 + u8 __reserved4[48];
147268 +} __packed;
147269 +
147270 +struct qm_mcc_ceetm_lfqmt_query {
147271 + u8 __reserved1[4];
147272 + u32 lfqid:24;
147273 + u8 __reserved2[56];
147274 +} __packed;
147275 +
147276 +struct qm_mcc_ceetm_cq_config {
147277 + u8 __reserved1;
147278 + u16 cqid;
147279 + u8 dcpid;
147280 + u8 __reserved2;
147281 + u16 ccgid;
147282 + u8 __reserved3[56];
147283 +} __packed;
147284 +
147285 +struct qm_mcc_ceetm_cq_query {
147286 + u8 __reserved1;
147287 + u16 cqid;
147288 + u8 dcpid;
147289 + u8 __reserved2[59];
147290 +} __packed;
147291 +
147292 +struct qm_mcc_ceetm_dct_config {
147293 + u8 __reserved1;
147294 + u16 dctidx;
147295 + u8 dcpid;
147296 + u8 __reserved2[15];
147297 + u32 context_b;
147298 + u64 context_a;
147299 + u8 __reserved3[32];
147300 +} __packed;
147301 +
147302 +struct qm_mcc_ceetm_dct_query {
147303 + u8 __reserved1;
147304 + u16 dctidx;
147305 + u8 dcpid;
147306 + u8 __reserved2[59];
147307 +} __packed;
147308 +
147309 +struct qm_mcc_ceetm_class_scheduler_config {
147310 + u8 __reserved1;
147311 + u16 cqcid;
147312 + u8 dcpid;
147313 + u8 __reserved2[6];
147314 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147315 + u8 gpc_reserved:1;
147316 + u8 gpc_combine_flag:1;
147317 + u8 gpc_prio_b:3;
147318 + u8 gpc_prio_a:3;
147319 +#else
147320 + u8 gpc_prio_a:3;
147321 + u8 gpc_prio_b:3;
147322 + u8 gpc_combine_flag:1;
147323 + u8 gpc_reserved:1;
147324 +#endif
147325 + u16 crem;
147326 + u16 erem;
147327 + u8 w[8];
147328 + u8 __reserved3[40];
147329 +} __packed;
147330 +
147331 +struct qm_mcc_ceetm_class_scheduler_query {
147332 + u8 __reserved1;
147333 + u16 cqcid;
147334 + u8 dcpid;
147335 + u8 __reserved2[59];
147336 +} __packed;
147337 +
147338 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
147339 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
147340 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
147341 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
147342 +#define CEETM_COMMAND_TCFC (4 << 12)
147343 +
147344 +#define CEETM_CCGRID_MASK 0x01FF
147345 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
147346 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
147347 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
147348 +#define CEETM_CCGR_CM_QUERY (0 << 14)
147349 +#define CEETM_CCGR_DN_QUERY (1 << 14)
147350 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
147351 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
147352 +
147353 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
147354 + u8 __reserved1;
147355 + u16 cid;
147356 + u8 dcpid;
147357 + union {
147358 + struct {
147359 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147360 + u8 map_shaped:1;
147361 + u8 map_reserved:4;
147362 + u8 map_lni_id:3;
147363 +#else
147364 + u8 map_lni_id:3;
147365 + u8 map_reserved:4;
147366 + u8 map_shaped:1;
147367 +#endif
147368 + u8 __reserved2[58];
147369 + } __packed channel_mapping;
147370 + struct {
147371 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147372 + u8 map_reserved:5;
147373 + u8 map_lni_id:3;
147374 +#else
147375 + u8 map_lni_id:3;
147376 + u8 map_reserved:5;
147377 +#endif
147378 + u8 __reserved2[58];
147379 + } __packed sp_mapping;
147380 + struct {
147381 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147382 + u8 cpl:1;
147383 + u8 cpl_reserved:2;
147384 + u8 oal:5;
147385 +#else
147386 + u8 oal:5;
147387 + u8 cpl_reserved:2;
147388 + u8 cpl:1;
147389 +#endif
147390 + u32 crtcr:24;
147391 + u32 ertcr:24;
147392 + u16 crtbl;
147393 + u16 ertbl;
147394 + u8 mps; /* This will be hardcoded by driver with 60 */
147395 + u8 __reserved2[47];
147396 + } __packed shaper_config;
147397 + struct {
147398 + u8 __reserved2[11];
147399 + u64 lnitcfcc;
147400 + u8 __reserved3[40];
147401 + } __packed tcfc_config;
147402 + };
147403 +} __packed;
147404 +
147405 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
147406 + u8 __reserved1;
147407 + u16 cid;
147408 + u8 dcpid;
147409 + u8 __reserved2[59];
147410 +} __packed;
147411 +
147412 +struct qm_mcc_ceetm_ccgr_config {
147413 + u8 __reserved1;
147414 + u16 ccgrid;
147415 + u8 dcpid;
147416 + u8 __reserved2;
147417 + u16 we_mask;
147418 + union {
147419 + struct {
147420 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147421 + u8 ctl_reserved:1;
147422 + u8 ctl_wr_en_g:1;
147423 + u8 ctl_wr_en_y:1;
147424 + u8 ctl_wr_en_r:1;
147425 + u8 ctl_td_en:1;
147426 + u8 ctl_td_mode:1;
147427 + u8 ctl_cscn_en:1;
147428 + u8 ctl_mode:1;
147429 +#else
147430 + u8 ctl_mode:1;
147431 + u8 ctl_cscn_en:1;
147432 + u8 ctl_td_mode:1;
147433 + u8 ctl_td_en:1;
147434 + u8 ctl_wr_en_r:1;
147435 + u8 ctl_wr_en_y:1;
147436 + u8 ctl_wr_en_g:1;
147437 + u8 ctl_reserved:1;
147438 +#endif
147439 + u8 cdv;
147440 + u16 cscn_tupd;
147441 + u8 oal;
147442 + u8 __reserved3;
147443 + struct qm_cgr_cs_thres cs_thres;
147444 + struct qm_cgr_cs_thres cs_thres_x;
147445 + struct qm_cgr_cs_thres td_thres;
147446 + struct qm_cgr_wr_parm wr_parm_g;
147447 + struct qm_cgr_wr_parm wr_parm_y;
147448 + struct qm_cgr_wr_parm wr_parm_r;
147449 + } __packed cm_config;
147450 + struct {
147451 + u8 dnc;
147452 + u8 dn0;
147453 + u8 dn1;
147454 + u64 dnba:40;
147455 + u8 __reserved3[2];
147456 + u16 dnth_0;
147457 + u8 __reserved4[2];
147458 + u16 dnth_1;
147459 + u8 __reserved5[8];
147460 + } __packed dn_config;
147461 + struct {
147462 + u8 __reserved3[3];
147463 + u64 i_cnt:40;
147464 + u8 __reserved4[16];
147465 + } __packed test_write;
147466 + };
147467 + u8 __reserved5[32];
147468 +} __packed;
147469 +
147470 +struct qm_mcc_ceetm_ccgr_query {
147471 + u8 __reserved1;
147472 + u16 ccgrid;
147473 + u8 dcpid;
147474 + u8 __reserved2[59];
147475 +} __packed;
147476 +
147477 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
147478 + u8 __reserved1;
147479 + u16 cqid;
147480 + u8 dcpid;
147481 + u8 ct;
147482 + u16 xsfdr;
147483 + u8 __reserved2[56];
147484 +} __packed;
147485 +
147486 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
147487 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
147488 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
147489 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
147490 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
147491 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
147492 +struct qm_mcc_ceetm_statistics_query_write {
147493 + u8 __reserved1;
147494 + u16 cid;
147495 + u8 dcpid;
147496 + u8 ct;
147497 + u8 __reserved2[13];
147498 + u64 frm_cnt:40;
147499 + u8 __reserved3[2];
147500 + u64 byte_cnt:48;
147501 + u8 __reserved[32];
147502 +} __packed;
147503 +
147504 +struct qm_mc_command {
147505 + u8 __dont_write_directly__verb;
147506 + union {
147507 + struct qm_mcc_initfq initfq;
147508 + struct qm_mcc_queryfq queryfq;
147509 + struct qm_mcc_queryfq_np queryfq_np;
147510 + struct qm_mcc_alterfq alterfq;
147511 + struct qm_mcc_initcgr initcgr;
147512 + struct qm_mcc_cgrtestwrite cgrtestwrite;
147513 + struct qm_mcc_querycgr querycgr;
147514 + struct qm_mcc_querycongestion querycongestion;
147515 + struct qm_mcc_querywq querywq;
147516 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
147517 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
147518 + struct qm_mcc_ceetm_cq_config cq_config;
147519 + struct qm_mcc_ceetm_cq_query cq_query;
147520 + struct qm_mcc_ceetm_dct_config dct_config;
147521 + struct qm_mcc_ceetm_dct_query dct_query;
147522 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
147523 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
147524 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
147525 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
147526 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
147527 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
147528 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
147529 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
147530 + };
147531 +} __packed;
147532 +#define QM_MCC_VERB_VBIT 0x80
147533 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
147534 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
147535 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
147536 +#define QM_MCC_VERB_QUERYFQ 0x44
147537 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
147538 +#define QM_MCC_VERB_QUERYWQ 0x46
147539 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
147540 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
147541 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
147542 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
147543 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
147544 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
147545 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
147546 +#define QM_MCC_VERB_INITCGR 0x50
147547 +#define QM_MCC_VERB_MODIFYCGR 0x51
147548 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
147549 +#define QM_MCC_VERB_QUERYCGR 0x58
147550 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
147551 +/* INITFQ-specific flags */
147552 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
147553 +#define QM_INITFQ_WE_OAC 0x0100
147554 +#define QM_INITFQ_WE_ORPC 0x0080
147555 +#define QM_INITFQ_WE_CGID 0x0040
147556 +#define QM_INITFQ_WE_FQCTRL 0x0020
147557 +#define QM_INITFQ_WE_DESTWQ 0x0010
147558 +#define QM_INITFQ_WE_ICSCRED 0x0008
147559 +#define QM_INITFQ_WE_TDTHRESH 0x0004
147560 +#define QM_INITFQ_WE_CONTEXTB 0x0002
147561 +#define QM_INITFQ_WE_CONTEXTA 0x0001
147562 +/* INITCGR/MODIFYCGR-specific flags */
147563 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
147564 +#define QM_CGR_WE_WR_PARM_G 0x0400
147565 +#define QM_CGR_WE_WR_PARM_Y 0x0200
147566 +#define QM_CGR_WE_WR_PARM_R 0x0100
147567 +#define QM_CGR_WE_WR_EN_G 0x0080
147568 +#define QM_CGR_WE_WR_EN_Y 0x0040
147569 +#define QM_CGR_WE_WR_EN_R 0x0020
147570 +#define QM_CGR_WE_CSCN_EN 0x0010
147571 +#define QM_CGR_WE_CSCN_TARG 0x0008
147572 +#define QM_CGR_WE_CSTD_EN 0x0004
147573 +#define QM_CGR_WE_CS_THRES 0x0002
147574 +#define QM_CGR_WE_MODE 0x0001
147575 +
147576 +/* See 1.5.9.7 CEETM Management Commands */
147577 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
147578 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
147579 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
147580 +#define QM_CEETM_VERB_CQ_QUERY 0x73
147581 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
147582 +#define QM_CEETM_VERB_DCT_QUERY 0x75
147583 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
147584 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
147585 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
147586 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
147587 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
147588 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
147589 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
147590 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
147591 +
147592 +/* See 1.5.8.5.1: "Initialize FQ" */
147593 +/* See 1.5.8.5.2: "Query FQ" */
147594 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
147595 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
147596 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
147597 +/* See 1.5.8.6.2: "CGR Test Write" */
147598 +/* See 1.5.8.6.3: "Query CGR" */
147599 +/* See 1.5.8.6.4: "Query Congestion Group State" */
147600 +struct qm_mcr_initfq {
147601 + u8 __reserved1[62];
147602 +} __packed;
147603 +struct qm_mcr_queryfq {
147604 + u8 __reserved1[8];
147605 + struct qm_fqd fqd; /* the FQD fields are here */
147606 + u8 __reserved2[30];
147607 +} __packed;
147608 +struct qm_mcr_queryfq_np {
147609 + u8 __reserved1;
147610 + u8 state; /* QM_MCR_NP_STATE_*** */
147611 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147612 + u8 __reserved2;
147613 + u32 fqd_link:24;
147614 + u16 __reserved3:2;
147615 + u16 odp_seq:14;
147616 + u16 __reserved4:2;
147617 + u16 orp_nesn:14;
147618 + u16 __reserved5:1;
147619 + u16 orp_ea_hseq:15;
147620 + u16 __reserved6:1;
147621 + u16 orp_ea_tseq:15;
147622 + u8 __reserved7;
147623 + u32 orp_ea_hptr:24;
147624 + u8 __reserved8;
147625 + u32 orp_ea_tptr:24;
147626 + u8 __reserved9;
147627 + u32 pfdr_hptr:24;
147628 + u8 __reserved10;
147629 + u32 pfdr_tptr:24;
147630 + u8 __reserved11[5];
147631 + u8 __reserved12:7;
147632 + u8 is:1;
147633 + u16 ics_surp;
147634 + u32 byte_cnt;
147635 + u8 __reserved13;
147636 + u32 frm_cnt:24;
147637 + u32 __reserved14;
147638 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
147639 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
147640 + u16 __reserved15;
147641 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
147642 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
147643 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
147644 +#else
147645 + u8 __reserved2;
147646 + u32 fqd_link:24;
147647 +
147648 + u16 odp_seq:14;
147649 + u16 __reserved3:2;
147650 +
147651 + u16 orp_nesn:14;
147652 + u16 __reserved4:2;
147653 +
147654 + u16 orp_ea_hseq:15;
147655 + u16 __reserved5:1;
147656 +
147657 + u16 orp_ea_tseq:15;
147658 + u16 __reserved6:1;
147659 +
147660 + u8 __reserved7;
147661 + u32 orp_ea_hptr:24;
147662 +
147663 + u8 __reserved8;
147664 + u32 orp_ea_tptr:24;
147665 +
147666 + u8 __reserved9;
147667 + u32 pfdr_hptr:24;
147668 +
147669 + u8 __reserved10;
147670 + u32 pfdr_tptr:24;
147671 +
147672 + u8 __reserved11[5];
147673 + u8 is:1;
147674 + u8 __reserved12:7;
147675 + u16 ics_surp;
147676 + u32 byte_cnt;
147677 + u8 __reserved13;
147678 + u32 frm_cnt:24;
147679 + u32 __reserved14;
147680 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
147681 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
147682 + u16 __reserved15;
147683 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
147684 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
147685 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
147686 +#endif
147687 +} __packed;
147688 +
147689 +
147690 +struct qm_mcr_alterfq {
147691 + u8 fqs; /* Frame Queue Status */
147692 + u8 __reserved1[61];
147693 +} __packed;
147694 +struct qm_mcr_initcgr {
147695 + u8 __reserved1[62];
147696 +} __packed;
147697 +struct qm_mcr_cgrtestwrite {
147698 + u16 __reserved1;
147699 + struct __qm_mc_cgr cgr; /* CGR fields */
147700 + u8 __reserved2[3];
147701 + u32 __reserved3:24;
147702 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
147703 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
147704 + u32 __reserved4:24;
147705 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
147706 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
147707 + u16 lgt; /* Last Group Tick */
147708 + u16 wr_prob_g;
147709 + u16 wr_prob_y;
147710 + u16 wr_prob_r;
147711 + u8 __reserved5[8];
147712 +} __packed;
147713 +struct qm_mcr_querycgr {
147714 + u16 __reserved1;
147715 + struct __qm_mc_cgr cgr; /* CGR fields */
147716 + u8 __reserved2[3];
147717 + union {
147718 + struct {
147719 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147720 + u32 __reserved3:24;
147721 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
147722 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
147723 +#else
147724 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
147725 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
147726 + u32 __reserved3:24;
147727 +#endif
147728 + };
147729 + u64 i_bcnt;
147730 + };
147731 + union {
147732 + struct {
147733 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147734 + u32 __reserved4:24;
147735 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
147736 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
147737 +#else
147738 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
147739 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
147740 + u32 __reserved4:24;
147741 +#endif
147742 + };
147743 + u64 a_bcnt;
147744 + };
147745 + union {
147746 + u32 cscn_targ_swp[4];
147747 + u8 __reserved5[16];
147748 + };
147749 +} __packed;
147750 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
147751 +{
147752 + return be64_to_cpu(q->i_bcnt);
147753 +}
147754 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
147755 +{
147756 + return be64_to_cpu(q->a_bcnt);
147757 +}
147758 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
147759 + const struct qm_mcr_cgrtestwrite *q)
147760 +{
147761 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
147762 +}
147763 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
147764 + const struct qm_mcr_cgrtestwrite *q)
147765 +{
147766 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
147767 +}
147768 +/* Macro, so we compile better if 'v' isn't always 64-bit */
147769 +#define qm_mcr_querycgr_i_set64(q, v) \
147770 + do { \
147771 + struct qm_mcr_querycgr *__q931 = (fd); \
147772 + __q931->i_bcnt_hi = upper_32_bits(v); \
147773 + __q931->i_bcnt_lo = lower_32_bits(v); \
147774 + } while (0)
147775 +#define qm_mcr_querycgr_a_set64(q, v) \
147776 + do { \
147777 + struct qm_mcr_querycgr *__q931 = (fd); \
147778 + __q931->a_bcnt_hi = upper_32_bits(v); \
147779 + __q931->a_bcnt_lo = lower_32_bits(v); \
147780 + } while (0)
147781 +struct __qm_mcr_querycongestion {
147782 + u32 __state[8];
147783 +};
147784 +struct qm_mcr_querycongestion {
147785 + u8 __reserved[30];
147786 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
147787 + struct __qm_mcr_querycongestion state;
147788 +} __packed;
147789 +struct qm_mcr_querywq {
147790 + union {
147791 + u16 channel_wq; /* ignores wq (3 lsbits) */
147792 + struct {
147793 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147794 + u16 id:13; /* qm_channel */
147795 + u16 __reserved:3;
147796 +#else
147797 + u16 __reserved:3;
147798 + u16 id:13; /* qm_channel */
147799 +#endif
147800 + } __packed channel;
147801 + };
147802 + u8 __reserved[28];
147803 + u32 wq_len[8];
147804 +} __packed;
147805 +
147806 +/* QMAN CEETM Management Command Response */
147807 +struct qm_mcr_ceetm_lfqmt_config {
147808 + u8 __reserved1[62];
147809 +} __packed;
147810 +struct qm_mcr_ceetm_lfqmt_query {
147811 + u8 __reserved1[8];
147812 + u16 cqid;
147813 + u8 __reserved2[2];
147814 + u16 dctidx;
147815 + u8 __reserved3[2];
147816 + u16 ccgid;
147817 + u8 __reserved4[44];
147818 +} __packed;
147819 +
147820 +struct qm_mcr_ceetm_cq_config {
147821 + u8 __reserved1[62];
147822 +} __packed;
147823 +
147824 +struct qm_mcr_ceetm_cq_query {
147825 + u8 __reserved1[4];
147826 + u16 ccgid;
147827 + u16 state;
147828 + u32 pfdr_hptr:24;
147829 + u32 pfdr_tptr:24;
147830 + u16 od1_xsfdr;
147831 + u16 od2_xsfdr;
147832 + u16 od3_xsfdr;
147833 + u16 od4_xsfdr;
147834 + u16 od5_xsfdr;
147835 + u16 od6_xsfdr;
147836 + u16 ra1_xsfdr;
147837 + u16 ra2_xsfdr;
147838 + u8 __reserved2;
147839 + u32 frm_cnt:24;
147840 + u8 __reserved333[28];
147841 +} __packed;
147842 +
147843 +struct qm_mcr_ceetm_dct_config {
147844 + u8 __reserved1[62];
147845 +} __packed;
147846 +
147847 +struct qm_mcr_ceetm_dct_query {
147848 + u8 __reserved1[18];
147849 + u32 context_b;
147850 + u64 context_a;
147851 + u8 __reserved2[32];
147852 +} __packed;
147853 +
147854 +struct qm_mcr_ceetm_class_scheduler_config {
147855 + u8 __reserved1[62];
147856 +} __packed;
147857 +
147858 +struct qm_mcr_ceetm_class_scheduler_query {
147859 + u8 __reserved1[9];
147860 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147861 + u8 gpc_reserved:1;
147862 + u8 gpc_combine_flag:1;
147863 + u8 gpc_prio_b:3;
147864 + u8 gpc_prio_a:3;
147865 +#else
147866 + u8 gpc_prio_a:3;
147867 + u8 gpc_prio_b:3;
147868 + u8 gpc_combine_flag:1;
147869 + u8 gpc_reserved:1;
147870 +#endif
147871 + u16 crem;
147872 + u16 erem;
147873 + u8 w[8];
147874 + u8 __reserved2[5];
147875 + u32 wbfslist:24;
147876 + u32 d8;
147877 + u32 d9;
147878 + u32 d10;
147879 + u32 d11;
147880 + u32 d12;
147881 + u32 d13;
147882 + u32 d14;
147883 + u32 d15;
147884 +} __packed;
147885 +
147886 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
147887 + u16 cid;
147888 + u8 __reserved2[60];
147889 +} __packed;
147890 +
147891 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
147892 + u16 cid;
147893 + u8 __reserved1;
147894 + union {
147895 + struct {
147896 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147897 + u8 map_shaped:1;
147898 + u8 map_reserved:4;
147899 + u8 map_lni_id:3;
147900 +#else
147901 + u8 map_lni_id:3;
147902 + u8 map_reserved:4;
147903 + u8 map_shaped:1;
147904 +#endif
147905 + u8 __reserved2[58];
147906 + } __packed channel_mapping_query;
147907 + struct {
147908 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147909 + u8 map_reserved:5;
147910 + u8 map_lni_id:3;
147911 +#else
147912 + u8 map_lni_id:3;
147913 + u8 map_reserved:5;
147914 +#endif
147915 + u8 __reserved2[58];
147916 + } __packed sp_mapping_query;
147917 + struct {
147918 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147919 + u8 cpl:1;
147920 + u8 cpl_reserved:2;
147921 + u8 oal:5;
147922 +#else
147923 + u8 oal:5;
147924 + u8 cpl_reserved:2;
147925 + u8 cpl:1;
147926 +#endif
147927 + u32 crtcr:24;
147928 + u32 ertcr:24;
147929 + u16 crtbl;
147930 + u16 ertbl;
147931 + u8 mps;
147932 + u8 __reserved2[15];
147933 + u32 crat;
147934 + u32 erat;
147935 + u8 __reserved3[24];
147936 + } __packed shaper_query;
147937 + struct {
147938 + u8 __reserved1[11];
147939 + u64 lnitcfcc;
147940 + u8 __reserved3[40];
147941 + } __packed tcfc_query;
147942 + };
147943 +} __packed;
147944 +
147945 +struct qm_mcr_ceetm_ccgr_config {
147946 + u8 __reserved1[46];
147947 + union {
147948 + u8 __reserved2[8];
147949 + struct {
147950 + u16 timestamp;
147951 + u16 wr_porb_g;
147952 + u16 wr_prob_y;
147953 + u16 wr_prob_r;
147954 + } __packed test_write;
147955 + };
147956 + u8 __reserved3[8];
147957 +} __packed;
147958 +
147959 +struct qm_mcr_ceetm_ccgr_query {
147960 + u8 __reserved1[6];
147961 + union {
147962 + struct {
147963 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147964 + u8 ctl_reserved:1;
147965 + u8 ctl_wr_en_g:1;
147966 + u8 ctl_wr_en_y:1;
147967 + u8 ctl_wr_en_r:1;
147968 + u8 ctl_td_en:1;
147969 + u8 ctl_td_mode:1;
147970 + u8 ctl_cscn_en:1;
147971 + u8 ctl_mode:1;
147972 +#else
147973 + u8 ctl_mode:1;
147974 + u8 ctl_cscn_en:1;
147975 + u8 ctl_td_mode:1;
147976 + u8 ctl_td_en:1;
147977 + u8 ctl_wr_en_r:1;
147978 + u8 ctl_wr_en_y:1;
147979 + u8 ctl_wr_en_g:1;
147980 + u8 ctl_reserved:1;
147981 +#endif
147982 + u8 cdv;
147983 + u8 __reserved2[2];
147984 + u8 oal;
147985 + u8 __reserved3;
147986 + struct qm_cgr_cs_thres cs_thres;
147987 + struct qm_cgr_cs_thres cs_thres_x;
147988 + struct qm_cgr_cs_thres td_thres;
147989 + struct qm_cgr_wr_parm wr_parm_g;
147990 + struct qm_cgr_wr_parm wr_parm_y;
147991 + struct qm_cgr_wr_parm wr_parm_r;
147992 + u16 cscn_targ_dcp;
147993 + u8 dcp_lsn;
147994 + u64 i_cnt:40;
147995 + u8 __reserved4[3];
147996 + u64 a_cnt:40;
147997 + u32 cscn_targ_swp[4];
147998 + } __packed cm_query;
147999 + struct {
148000 + u8 dnc;
148001 + u8 dn0;
148002 + u8 dn1;
148003 + u64 dnba:40;
148004 + u8 __reserved2[2];
148005 + u16 dnth_0;
148006 + u8 __reserved3[2];
148007 + u16 dnth_1;
148008 + u8 __reserved4[10];
148009 + u16 dnacc_0;
148010 + u8 __reserved5[2];
148011 + u16 dnacc_1;
148012 + u8 __reserved6[24];
148013 + } __packed dn_query;
148014 + struct {
148015 + u8 __reserved2[24];
148016 + struct __qm_mcr_querycongestion state;
148017 + } __packed congestion_state;
148018 +
148019 + };
148020 +} __packed;
148021 +
148022 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
148023 + u8 stat;
148024 + u8 __reserved1[11];
148025 + u16 dctidx;
148026 + struct qm_fd fd;
148027 + u8 __reserved2[32];
148028 +} __packed;
148029 +
148030 +struct qm_mcr_ceetm_statistics_query {
148031 + u8 __reserved1[17];
148032 + u64 frm_cnt:40;
148033 + u8 __reserved2[2];
148034 + u64 byte_cnt:48;
148035 + u8 __reserved3[32];
148036 +} __packed;
148037 +
148038 +struct qm_mc_result {
148039 + u8 verb;
148040 + u8 result;
148041 + union {
148042 + struct qm_mcr_initfq initfq;
148043 + struct qm_mcr_queryfq queryfq;
148044 + struct qm_mcr_queryfq_np queryfq_np;
148045 + struct qm_mcr_alterfq alterfq;
148046 + struct qm_mcr_initcgr initcgr;
148047 + struct qm_mcr_cgrtestwrite cgrtestwrite;
148048 + struct qm_mcr_querycgr querycgr;
148049 + struct qm_mcr_querycongestion querycongestion;
148050 + struct qm_mcr_querywq querywq;
148051 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
148052 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
148053 + struct qm_mcr_ceetm_cq_config cq_config;
148054 + struct qm_mcr_ceetm_cq_query cq_query;
148055 + struct qm_mcr_ceetm_dct_config dct_config;
148056 + struct qm_mcr_ceetm_dct_query dct_query;
148057 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
148058 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
148059 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
148060 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
148061 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
148062 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
148063 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
148064 + struct qm_mcr_ceetm_statistics_query stats_query;
148065 + };
148066 +} __packed;
148067 +
148068 +#define QM_MCR_VERB_RRID 0x80
148069 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
148070 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
148071 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
148072 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
148073 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
148074 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
148075 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
148076 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
148077 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
148078 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
148079 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
148080 +#define QM_MCR_RESULT_NULL 0x00
148081 +#define QM_MCR_RESULT_OK 0xf0
148082 +#define QM_MCR_RESULT_ERR_FQID 0xf1
148083 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
148084 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
148085 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
148086 +#define QM_MCR_RESULT_PENDING 0xf8
148087 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
148088 +#define QM_MCR_NP_STATE_FE 0x10
148089 +#define QM_MCR_NP_STATE_R 0x08
148090 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
148091 +#define QM_MCR_NP_STATE_OOS 0x00
148092 +#define QM_MCR_NP_STATE_RETIRED 0x01
148093 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
148094 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
148095 +#define QM_MCR_NP_STATE_PARKED 0x04
148096 +#define QM_MCR_NP_STATE_ACTIVE 0x05
148097 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
148098 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
148099 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
148100 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
148101 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
148102 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
148103 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
148104 +/* This extracts the state for congestion group 'n' from a query response.
148105 + * Eg.
148106 + * u8 cgr = [...];
148107 + * struct qm_mc_result *res = [...];
148108 + * printf("congestion group %d congestion state: %d\n", cgr,
148109 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
148110 + */
148111 +#define __CGR_WORD(num) (num >> 5)
148112 +#define __CGR_SHIFT(num) (num & 0x1f)
148113 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
148114 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
148115 + u8 cgr)
148116 +{
148117 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
148118 +}
148119 +
148120 +
148121 +/*********************/
148122 +/* Utility interface */
148123 +/*********************/
148124 +
148125 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
148126 + * spinlock them yourself if needed. */
148127 +struct qman_fqid_pool;
148128 +
148129 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
148130 + * always succeeds, but returns non-zero if there were "leaked" FQID
148131 + * allocations. */
148132 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
148133 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
148134 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
148135 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
148136 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
148137 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
148138 +
148139 +/*******************************************************************/
148140 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
148141 +/*******************************************************************/
148142 +
148143 + /* Portal and Frame Queues */
148144 + /* ----------------------- */
148145 +/* Represents a managed portal */
148146 +struct qman_portal;
148147 +
148148 +/* This object type represents Qman frame queue descriptors (FQD), it is
148149 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
148150 + * defined further down. */
148151 +struct qman_fq;
148152 +
148153 +/* This object type represents a Qman congestion group, it is defined further
148154 + * down. */
148155 +struct qman_cgr;
148156 +
148157 +struct qman_portal_config {
148158 + /* If the caller enables DQRR stashing (and thus wishes to operate the
148159 + * portal from only one cpu), this is the logical CPU that the portal
148160 + * will stash to. Whether stashing is enabled or not, this setting is
148161 + * also used for any "core-affine" portals, ie. default portals
148162 + * associated to the corresponding cpu. -1 implies that there is no core
148163 + * affinity configured. */
148164 + int cpu;
148165 + /* portal interrupt line */
148166 + int irq;
148167 + /* the unique index of this portal */
148168 + u32 index;
148169 + /* Is this portal shared? (If so, it has coarser locking and demuxes
148170 + * processing on behalf of other CPUs.) */
148171 + int is_shared;
148172 + /* The portal's dedicated channel id, use this value for initialising
148173 + * frame queues to target this portal when scheduled. */
148174 + u16 channel;
148175 + /* A mask of which pool channels this portal has dequeue access to
148176 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
148177 + u32 pools;
148178 +};
148179 +
148180 +/* This enum, and the callback type that returns it, are used when handling
148181 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
148182 + * portal object (for handling dequeues that do not demux because contextB is
148183 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
148184 +enum qman_cb_dqrr_result {
148185 + /* DQRR entry can be consumed */
148186 + qman_cb_dqrr_consume,
148187 + /* Like _consume, but requests parking - FQ must be held-active */
148188 + qman_cb_dqrr_park,
148189 + /* Does not consume, for DCA mode only. This allows out-of-order
148190 + * consumes by explicit calls to qman_dca() and/or the use of implicit
148191 + * DCA via EQCR entries. */
148192 + qman_cb_dqrr_defer,
148193 + /* Stop processing without consuming this ring entry. Exits the current
148194 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
148195 + * interrupt handler, the callback would typically call
148196 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
148197 + * otherwise the interrupt will reassert immediately. */
148198 + qman_cb_dqrr_stop,
148199 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
148200 + qman_cb_dqrr_consume_stop
148201 +};
148202 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
148203 + struct qman_fq *fq,
148204 + const struct qm_dqrr_entry *dqrr);
148205 +
148206 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
148207 + * are always consumed after the callback returns. */
148208 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
148209 + const struct qm_mr_entry *msg);
148210 +
148211 +/* This callback type is used when handling DCP ERNs */
148212 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
148213 + const struct qm_mr_entry *msg);
148214 +
148215 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
148216 + * held-active + held-suspended are just "sched". Things like "retired" will not
148217 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
148218 + * then, to indicate it's completing and to gate attempts to retry the retire
148219 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
148220 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
148221 + * index rather than the FQ that ring entry corresponds to), so repeated park
148222 + * commands are allowed (if you're silly enough to try) but won't change FQ
148223 + * state, and the resulting park notifications move FQs from "sched" to
148224 + * "parked". */
148225 +enum qman_fq_state {
148226 + qman_fq_state_oos,
148227 + qman_fq_state_parked,
148228 + qman_fq_state_sched,
148229 + qman_fq_state_retired
148230 +};
148231 +
148232 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
148233 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
148234 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
148235 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
148236 + * they should;
148237 + *
148238 + * (a) extend the qman_fq structure with their state; eg.
148239 + *
148240 + * // myfq is allocated and driver_fq callbacks filled in;
148241 + * struct my_fq {
148242 + * struct qman_fq base;
148243 + * int an_extra_field;
148244 + * [ ... add other fields to be associated with each FQ ...]
148245 + * } *myfq = some_my_fq_allocator();
148246 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
148247 + *
148248 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
148249 + * struct my_fq *myfq = (struct my_fq *)fq;
148250 + * do_something_with(myfq->an_extra_field);
148251 + * [...]
148252 + *
148253 + * (b) when and if configuring the FQ for context stashing, specify how ever
148254 + * many cachelines are required to stash 'struct my_fq', to accelerate not
148255 + * only the Qman driver but the callback as well.
148256 + */
148257 +
148258 +struct qman_fq_cb {
148259 + qman_cb_dqrr dqrr; /* for dequeued frames */
148260 + qman_cb_mr ern; /* for s/w ERNs */
148261 + qman_cb_mr fqs; /* frame-queue state changes*/
148262 +};
148263 +
148264 +struct qman_fq {
148265 + /* Caller of qman_create_fq() provides these demux callbacks */
148266 + struct qman_fq_cb cb;
148267 + /* These are internal to the driver, don't touch. In particular, they
148268 + * may change, be removed, or extended (so you shouldn't rely on
148269 + * sizeof(qman_fq) being a constant). */
148270 + spinlock_t fqlock;
148271 + u32 fqid;
148272 + volatile unsigned long flags;
148273 + enum qman_fq_state state;
148274 + int cgr_groupid;
148275 + struct rb_node node;
148276 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
148277 + u32 key;
148278 +#endif
148279 +};
148280 +
148281 +/* This callback type is used when handling congestion group entry/exit.
148282 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
148283 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
148284 + struct qman_cgr *cgr, int congested);
148285 +
148286 +struct qman_cgr {
148287 + /* Set these prior to qman_create_cgr() */
148288 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
148289 + qman_cb_cgr cb;
148290 + /* These are private to the driver */
148291 + u16 chan; /* portal channel this object is created on */
148292 + struct list_head node;
148293 +};
148294 +
148295 +/* Flags to qman_create_fq() */
148296 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
148297 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
148298 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
148299 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
148300 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
148301 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
148302 +
148303 +/* Flags to qman_destroy_fq() */
148304 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
148305 +
148306 +/* Flags from qman_fq_state() */
148307 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
148308 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
148309 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
148310 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
148311 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
148312 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
148313 +
148314 +/* Flags to qman_init_fq() */
148315 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
148316 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
148317 +
148318 +/* Flags to qman_volatile_dequeue() */
148319 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
148320 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
148321 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
148322 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
148323 +#endif
148324 +
148325 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
148326 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
148327 + * any change here should be audited in PME.) */
148328 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
148329 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
148330 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
148331 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
148332 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
148333 +#endif
148334 +#endif
148335 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
148336 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
148337 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
148338 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
148339 + (((u32)(p) << 2) & 0x00000f00)
148340 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
148341 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
148342 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
148343 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
148344 +/* For the ORP-specific qman_enqueue_orp() variant;
148345 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
148346 + * of a frame. */
148347 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
148348 +/* - this flag performs no enqueue but fills in an ORP sequence number that
148349 + * would otherwise block it (eg. if a frame has been dropped). */
148350 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
148351 +/* - this flag performs no enqueue but advances NESN to the given sequence
148352 + * number. */
148353 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
148354 +
148355 +/* Flags to qman_modify_cgr() */
148356 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
148357 +#define QMAN_CGR_MODE_FRAME 0x00000001
148358 +
148359 + /* Portal Management */
148360 + /* ----------------- */
148361 +/**
148362 + * qman_get_portal_config - get portal configuration settings
148363 + *
148364 + * This returns a read-only view of the current cpu's affine portal settings.
148365 + */
148366 +const struct qman_portal_config *qman_get_portal_config(void);
148367 +
148368 +/**
148369 + * qman_irqsource_get - return the portal work that is interrupt-driven
148370 + *
148371 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
148372 + * enabled for interrupt handling on the current cpu's affine portal. These
148373 + * sources will trigger the portal interrupt and the interrupt handler (or a
148374 + * tasklet/bottom-half it defers to) will perform the corresponding processing
148375 + * work. The qman_poll_***() functions will only process sources that are not in
148376 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
148377 + * this always returns zero.
148378 + */
148379 +u32 qman_irqsource_get(void);
148380 +
148381 +/**
148382 + * qman_irqsource_add - add processing sources to be interrupt-driven
148383 + * @bits: bitmask of QM_PIRQ_**I processing sources
148384 + *
148385 + * Adds processing sources that should be interrupt-driven (rather than
148386 + * processed via qman_poll_***() functions). Returns zero for success, or
148387 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
148388 + */
148389 +int qman_irqsource_add(u32 bits);
148390 +
148391 +/**
148392 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
148393 + * @bits: bitmask of QM_PIRQ_**I processing sources
148394 + *
148395 + * Removes processing sources from being interrupt-driven, so that they will
148396 + * instead be processed via qman_poll_***() functions. Returns zero for success,
148397 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
148398 + */
148399 +int qman_irqsource_remove(u32 bits);
148400 +
148401 +/**
148402 + * qman_affine_cpus - return a mask of cpus that have affine portals
148403 + */
148404 +const cpumask_t *qman_affine_cpus(void);
148405 +
148406 +/**
148407 + * qman_affine_channel - return the channel ID of an portal
148408 + * @cpu: the cpu whose affine portal is the subject of the query
148409 + *
148410 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
148411 + * bug to call this function for any value of @cpu (other than -1) that is not a
148412 + * member of the mask returned from qman_affine_cpus().
148413 + */
148414 +u16 qman_affine_channel(int cpu);
148415 +
148416 +/**
148417 + * qman_get_affine_portal - return the portal pointer affine to cpu
148418 + * @cpu: the cpu whose affine portal is the subject of the query
148419 + *
148420 + */
148421 +void *qman_get_affine_portal(int cpu);
148422 +
148423 +/**
148424 + * qman_poll_dqrr - process DQRR (fast-path) entries
148425 + * @limit: the maximum number of DQRR entries to process
148426 + *
148427 + * Use of this function requires that DQRR processing not be interrupt-driven.
148428 + * Ie. the value returned by qman_irqsource_get() should not include
148429 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
148430 + * this function will return -EINVAL, otherwise the return value is >=0 and
148431 + * represents the number of DQRR entries processed.
148432 + */
148433 +int qman_poll_dqrr(unsigned int limit);
148434 +
148435 +/**
148436 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
148437 + *
148438 + * This function does any portal processing that isn't interrupt-driven. If the
148439 + * current CPU is sharing a portal hosted on another CPU, this function will
148440 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
148441 + * indicating what interrupt sources were actually processed by the call.
148442 + */
148443 +u32 qman_poll_slow(void);
148444 +
148445 +/**
148446 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
148447 + *
148448 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
148449 + * affine portal. There are two classes of portal processing in question;
148450 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
148451 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
148452 + * thresholds, congestion state changes, etc). This function does whatever
148453 + * processing is not triggered by interrupts.
148454 + *
148455 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
148456 + * interrupt-driven) then this function uses a heuristic to determine how often
148457 + * to run slow-path processing - as slow-path processing introduces at least a
148458 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
148459 + * close to zero-cost if there is no work to be done. Applications can tune this
148460 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
148461 + * rather than going via this wrapper.
148462 + */
148463 +void qman_poll(void);
148464 +
148465 +/**
148466 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
148467 + *
148468 + * Disables DQRR processing of the portal. This is reference-counted, so
148469 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
148470 + * truly re-enable dequeuing.
148471 + */
148472 +void qman_stop_dequeues(void);
148473 +
148474 +/**
148475 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
148476 + *
148477 + * Enables DQRR processing of the portal. This is reference-counted, so
148478 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
148479 + * truly re-enable dequeuing.
148480 + */
148481 +void qman_start_dequeues(void);
148482 +
148483 +/**
148484 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
148485 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
148486 + *
148487 + * Adds a set of pool channels to the portal's static dequeue command register
148488 + * (SDQCR). The requested pools are limited to those the portal has dequeue
148489 + * access to.
148490 + */
148491 +void qman_static_dequeue_add(u32 pools);
148492 +
148493 +/**
148494 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
148495 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
148496 + *
148497 + * Removes a set of pool channels from the portal's static dequeue command
148498 + * register (SDQCR). The requested pools are limited to those the portal has
148499 + * dequeue access to.
148500 + */
148501 +void qman_static_dequeue_del(u32 pools);
148502 +
148503 +/**
148504 + * qman_static_dequeue_get - return the portal's current SDQCR
148505 + *
148506 + * Returns the portal's current static dequeue command register (SDQCR). The
148507 + * entire register is returned, so if only the currently-enabled pool channels
148508 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
148509 + */
148510 +u32 qman_static_dequeue_get(void);
148511 +
148512 +/**
148513 + * qman_dca - Perform a Discrete Consumption Acknowledgement
148514 + * @dq: the DQRR entry to be consumed
148515 + * @park_request: indicates whether the held-active @fq should be parked
148516 + *
148517 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
148518 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
148519 + * does not take a 'portal' argument but implies the core affine portal from the
148520 + * cpu that is currently executing the function. For reasons of locking, this
148521 + * function must be called from the same CPU as that which processed the DQRR
148522 + * entry in the first place.
148523 + */
148524 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
148525 +
148526 +/**
148527 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
148528 + *
148529 + * For use in situations where a cpu-affine caller needs to determine when all
148530 + * enqueues for the local portal have been processed by Qman but can't use the
148531 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
148532 + * The function forces tracking of EQCR consumption (which normally doesn't
148533 + * happen until enqueue processing needs to find space to put new enqueue
148534 + * commands), and returns zero if the ring still has unprocessed entries,
148535 + * non-zero if it is empty.
148536 + */
148537 +int qman_eqcr_is_empty(void);
148538 +
148539 +/**
148540 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
148541 + * @handler: callback for processing DCP ERNs
148542 + * @affine: whether this handler is specific to the locally affine portal
148543 + *
148544 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
148545 + * DCP) is configured not to receive enqueue rejections, then any enqueues
148546 + * through that DCP that are rejected will be sent to a given software portal.
148547 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
148548 + * received on the portal affine to the current CPU. If multiple CPUs share a
148549 + * portal and they all call this function, they will be setting the handler for
148550 + * the same portal! If @affine is zero, then this handler will be global to all
148551 + * portals handled by this instance of the driver. Only those portals that do
148552 + * not have their own affine handler will use the global handler.
148553 + */
148554 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
148555 +
148556 + /* FQ management */
148557 + /* ------------- */
148558 +/**
148559 + * qman_create_fq - Allocates a FQ
148560 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
148561 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
148562 + * @fq: memory for storing the 'fq', with callbacks filled in
148563 + *
148564 + * Creates a frame queue object for the given @fqid, unless the
148565 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
148566 + * dynamically allocated (or the function fails if none are available). Once
148567 + * created, the caller should not touch the memory at 'fq' except as extended to
148568 + * adjacent memory for user-defined fields (see the definition of "struct
148569 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
148570 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
148571 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
148572 + * causes the driver to honour any contextB modifications requested in the
148573 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
148574 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
148575 + * software portals, the contextB field is controlled by the driver and can't be
148576 + * modified by the caller. If the AS_IS flag is specified, management commands
148577 + * will be used on portal @p to query state for frame queue @fqid and construct
148578 + * a frame queue object based on that, rather than assuming/requiring that it be
148579 + * Out of Service.
148580 + */
148581 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
148582 +
148583 +/**
148584 + * qman_destroy_fq - Deallocates a FQ
148585 + * @fq: the frame queue object to release
148586 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
148587 + *
148588 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
148589 + * not deallocated but the caller regains ownership, to do with as desired. The
148590 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
148591 + * is specified, in which case it may also be in the 'parked' state.
148592 + */
148593 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
148594 +
148595 +/**
148596 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
148597 + * @fq: the frame queue object to query
148598 + */
148599 +u32 qman_fq_fqid(struct qman_fq *fq);
148600 +
148601 +/**
148602 + * qman_fq_state - Queries the state of a FQ object
148603 + * @fq: the frame queue object to query
148604 + * @state: pointer to state enum to return the FQ scheduling state
148605 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
148606 + *
148607 + * Queries the state of the FQ object, without performing any h/w commands.
148608 + * This captures the state, as seen by the driver, at the time the function
148609 + * executes.
148610 + */
148611 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
148612 +
148613 +/**
148614 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
148615 + * @fq: the frame queue object to modify, must be 'parked' or new.
148616 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
148617 + * @opts: the FQ-modification settings, as defined in the low-level API
148618 + *
148619 + * The @opts parameter comes from the low-level portal API. Select
148620 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
148621 + * rather than parked. NB, @opts can be NULL.
148622 + *
148623 + * Note that some fields and options within @opts may be ignored or overwritten
148624 + * by the driver;
148625 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
148626 + * affects one frame queue: @fq).
148627 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
148628 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
148629 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
148630 + * initialised to a value used by the driver for demux.
148631 + * - if context_b is initialised for demux, so is context_a in case stashing
148632 + * is requested (see item 4).
148633 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
148634 + * objects.)
148635 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
148636 + * 'dest::channel' field will be overwritten to match the portal used to issue
148637 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
148638 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
148639 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
148640 + * isn't set, the destination channel/workqueue fields and the write-enable bit
148641 + * are left as-is.
148642 + * 4. if the driver overwrites context_a/b for demux, then if
148643 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
148644 + * context_a.address fields and will leave the stashing fields provided by the
148645 + * user alone, otherwise it will zero out the context_a.stashing fields.
148646 + */
148647 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
148648 +
148649 +/**
148650 + * qman_schedule_fq - Schedules a FQ
148651 + * @fq: the frame queue object to schedule, must be 'parked'
148652 + *
148653 + * Schedules the frame queue, which must be Parked, which takes it to
148654 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
148655 + */
148656 +int qman_schedule_fq(struct qman_fq *fq);
148657 +
148658 +/**
148659 + * qman_retire_fq - Retires a FQ
148660 + * @fq: the frame queue object to retire
148661 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
148662 + *
148663 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
148664 + * the retirement was started asynchronously, otherwise it returns negative for
148665 + * failure. When this function returns zero, @flags is set to indicate whether
148666 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
148667 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
148668 + * FQRN message shows up on the portal's message ring.
148669 + *
148670 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
148671 + * Active state), the completion will be via the message ring as a FQRN - but
148672 + * the corresponding callback may occur before this function returns!! Ie. the
148673 + * caller should be prepared to accept the callback as the function is called,
148674 + * not only once it has returned.
148675 + */
148676 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
148677 +
148678 +/**
148679 + * qman_oos_fq - Puts a FQ "out of service"
148680 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
148681 + *
148682 + * The frame queue must be retired and empty, and if any order restoration list
148683 + * was released as ERNs at the time of retirement, they must all be consumed.
148684 + */
148685 +int qman_oos_fq(struct qman_fq *fq);
148686 +
148687 +/**
148688 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
148689 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
148690 + * or 'retired' or 'parked' state
148691 + * @xon: boolean to set fq in XON or XOFF state
148692 + *
148693 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
148694 + * otherwise the IFSI interrupt will be asserted.
148695 + */
148696 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
148697 +
148698 +/**
148699 + * qman_query_fq - Queries FQD fields (via h/w query command)
148700 + * @fq: the frame queue object to be queried
148701 + * @fqd: storage for the queried FQD fields
148702 + */
148703 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
148704 +
148705 +/**
148706 + * qman_query_fq_np - Queries non-programmable FQD fields
148707 + * @fq: the frame queue object to be queried
148708 + * @np: storage for the queried FQD fields
148709 + */
148710 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
148711 +
148712 +/**
148713 + * qman_query_wq - Queries work queue lengths
148714 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
148715 + * to this software portal. Otherwise, query length of WQs in a
148716 + * channel specified in wq.
148717 + * @wq: storage for the queried WQs lengths. Also specified the channel to
148718 + * to query if query_dedicated is zero.
148719 + */
148720 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
148721 +
148722 +/**
148723 + * qman_volatile_dequeue - Issue a volatile dequeue command
148724 + * @fq: the frame queue object to dequeue from
148725 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
148726 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
148727 + *
148728 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
148729 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
148730 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
148731 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
148732 + * the VDQCR command has finished executing (ie. once the callback for the last
148733 + * DQRR entry resulting from the VDQCR command has been called). If not using
148734 + * the FINISH flag, completion can be determined either by detecting the
148735 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
148736 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
148737 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
148738 + * "flags" retrieved from qman_fq_state().
148739 + */
148740 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
148741 +
148742 +/**
148743 + * qman_enqueue - Enqueue a frame to a frame queue
148744 + * @fq: the frame queue object to enqueue to
148745 + * @fd: a descriptor of the frame to be enqueued
148746 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
148747 + *
148748 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
148749 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
148750 + * field is ignored. The return value is non-zero on error, such as ring full
148751 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
148752 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
148753 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
148754 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
148755 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
148756 + * perform an implied "discrete consumption acknowledgement" on the dequeue
148757 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
148758 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
148759 + * this implicit DCA can delay the release of a "held active" frame queue
148760 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
148761 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
148762 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
148763 + * acknowledgement should "park request" the "held active" frame queue. Ie.
148764 + * when the portal eventually releases that frame queue, it will be left in the
148765 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
148766 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
148767 + * is requested, and the FQ is a member of a congestion group, then this
148768 + * function returns -EAGAIN if the congestion group is currently congested.
148769 + * Note, this does not eliminate ERNs, as the async interface means we can be
148770 + * sending enqueue commands to an un-congested FQ that becomes congested before
148771 + * the enqueue commands are processed, but it does minimise needless thrashing
148772 + * of an already busy hardware resource by throttling many of the to-be-dropped
148773 + * enqueues "at the source".
148774 + */
148775 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
148776 +
148777 +typedef int (*qman_cb_precommit) (void *arg);
148778 +/**
148779 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
148780 + * @fq: the frame queue object to enqueue to
148781 + * @fd: a descriptor of the frame to be enqueued
148782 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
148783 + * @cb: user supplied callback function to invoke before writing commit verb.
148784 + * @cb_arg: callback function argument
148785 + *
148786 + * This is similar to qman_enqueue except that it will invoke a user supplied
148787 + * callback function just before writng the commit verb. This is useful
148788 + * when the user want to do something *just before* enqueuing the request and
148789 + * the enqueue can't fail.
148790 + */
148791 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
148792 + u32 flags, qman_cb_precommit cb, void *cb_arg);
148793 +
148794 +/**
148795 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
148796 + * @fq: the frame queue object to enqueue to
148797 + * @fd: a descriptor of the frame to be enqueued
148798 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
148799 + * @orp: the frame queue object used as an order restoration point.
148800 + * @orp_seqnum: the sequence number of this frame in the order restoration path
148801 + *
148802 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
148803 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
148804 + * enqueue operation to employ order restoration. Each frame queue object acts
148805 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
148806 + * with an incrementing sequence number, this value is generally ignored unless
148807 + * that sequence of dequeued frames will need order restoration later. Each
148808 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
148809 + * is a re-assembly context for re-ordering frames relative to their sequence
148810 + * numbers as they are enqueued. The ORP does not have to be within the frame
148811 + * queue that receives the enqueued frame, in fact it is usually the frame
148812 + * queue from which the frames were originally dequeued. For the purposes of
148813 + * order restoration, multiple frames (or "fragments") can be enqueued for a
148814 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
148815 + * enqueues except the final fragment of a given sequence number. Ordering
148816 + * between sequence numbers is guaranteed, even if fragments of different
148817 + * sequence numbers are interlaced with one another. Fragments of the same
148818 + * sequence number will retain the order in which they are enqueued. If no
148819 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
148820 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
148821 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
148822 + * sequence number should become the ORP's "Next Expected Sequence Number".
148823 + *
148824 + * Side note: a frame queue object can be used purely as an ORP, without
148825 + * carrying any frames at all. Care should be taken not to deallocate a frame
148826 + * queue object that is being actively used as an ORP, as a future allocation
148827 + * of the frame queue object may start using the internal ORP before the
148828 + * previous use has finished.
148829 + */
148830 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
148831 + struct qman_fq *orp, u16 orp_seqnum);
148832 +
148833 +/**
148834 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
148835 + * @result: is set by the API to the base FQID of the allocated range
148836 + * @count: the number of FQIDs required
148837 + * @align: required alignment of the allocated range
148838 + * @partial: non-zero if the API can return fewer than @count FQIDs
148839 + *
148840 + * Returns the number of frame queues allocated, or a negative error code. If
148841 + * @partial is non zero, the allocation request may return a smaller range of
148842 + * FQs than requested (though alignment will be as requested). If @partial is
148843 + * zero, the return value will either be 'count' or negative.
148844 + */
148845 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
148846 +static inline int qman_alloc_fqid(u32 *result)
148847 +{
148848 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
148849 + return (ret > 0) ? 0 : ret;
148850 +}
148851 +
148852 +/**
148853 + * qman_release_fqid_range - Release the specified range of frame queue IDs
148854 + * @fqid: the base FQID of the range to deallocate
148855 + * @count: the number of FQIDs in the range
148856 + *
148857 + * This function can also be used to seed the allocator with ranges of FQIDs
148858 + * that it can subsequently allocate from.
148859 + */
148860 +void qman_release_fqid_range(u32 fqid, unsigned int count);
148861 +static inline void qman_release_fqid(u32 fqid)
148862 +{
148863 + qman_release_fqid_range(fqid, 1);
148864 +}
148865 +
148866 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
148867 +
148868 +
148869 +int qman_shutdown_fq(u32 fqid);
148870 +
148871 +/**
148872 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
148873 + * @fqid: the base FQID of the range to deallocate
148874 + * @count: the number of FQIDs in the range
148875 + */
148876 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
148877 +static inline int qman_reserve_fqid(u32 fqid)
148878 +{
148879 + return qman_reserve_fqid_range(fqid, 1);
148880 +}
148881 +
148882 + /* Pool-channel management */
148883 + /* ----------------------- */
148884 +/**
148885 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
148886 + * @result: is set by the API to the base pool-channel ID of the allocated range
148887 + * @count: the number of pool-channel IDs required
148888 + * @align: required alignment of the allocated range
148889 + * @partial: non-zero if the API can return fewer than @count
148890 + *
148891 + * Returns the number of pool-channel IDs allocated, or a negative error code.
148892 + * If @partial is non zero, the allocation request may return a smaller range of
148893 + * than requested (though alignment will be as requested). If @partial is zero,
148894 + * the return value will either be 'count' or negative.
148895 + */
148896 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
148897 +static inline int qman_alloc_pool(u32 *result)
148898 +{
148899 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
148900 + return (ret > 0) ? 0 : ret;
148901 +}
148902 +
148903 +/**
148904 + * qman_release_pool_range - Release the specified range of pool-channel IDs
148905 + * @id: the base pool-channel ID of the range to deallocate
148906 + * @count: the number of pool-channel IDs in the range
148907 + */
148908 +void qman_release_pool_range(u32 id, unsigned int count);
148909 +static inline void qman_release_pool(u32 id)
148910 +{
148911 + qman_release_pool_range(id, 1);
148912 +}
148913 +
148914 +/**
148915 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
148916 + * @id: the base pool-channel ID of the range to reserve
148917 + * @count: the number of pool-channel IDs in the range
148918 + */
148919 +int qman_reserve_pool_range(u32 id, unsigned int count);
148920 +static inline int qman_reserve_pool(u32 id)
148921 +{
148922 + return qman_reserve_pool_range(id, 1);
148923 +}
148924 +
148925 +void qman_seed_pool_range(u32 id, unsigned int count);
148926 +
148927 + /* CGR management */
148928 + /* -------------- */
148929 +/**
148930 + * qman_create_cgr - Register a congestion group object
148931 + * @cgr: the 'cgr' object, with fields filled in
148932 + * @flags: QMAN_CGR_FLAG_* values
148933 + * @opts: optional state of CGR settings
148934 + *
148935 + * Registers this object to receiving congestion entry/exit callbacks on the
148936 + * portal affine to the cpu portal on which this API is executed. If opts is
148937 + * NULL then only the callback (cgr->cb) function is registered. If @flags
148938 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
148939 + * any unspecified parameters) will be used rather than a modify hw hardware
148940 + * (which only modifies the specified parameters).
148941 + */
148942 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
148943 + struct qm_mcc_initcgr *opts);
148944 +
148945 +/**
148946 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
148947 + * @cgr: the 'cgr' object, with fields filled in
148948 + * @flags: QMAN_CGR_FLAG_* values
148949 + * @dcp_portal: the DCP portal to which the cgr object is registered.
148950 + * @opts: optional state of CGR settings
148951 + *
148952 + */
148953 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
148954 + struct qm_mcc_initcgr *opts);
148955 +
148956 +/**
148957 + * qman_delete_cgr - Deregisters a congestion group object
148958 + * @cgr: the 'cgr' object to deregister
148959 + *
148960 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
148961 + * is executed. This must be excuted on the same affine portal on which it was
148962 + * created.
148963 + */
148964 +int qman_delete_cgr(struct qman_cgr *cgr);
148965 +
148966 +/**
148967 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
148968 + * @cgr: the 'cgr' object to deregister
148969 + *
148970 + * This will select the proper CPU and run there qman_delete_cgr().
148971 + */
148972 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
148973 +
148974 +/**
148975 + * qman_modify_cgr - Modify CGR fields
148976 + * @cgr: the 'cgr' object to modify
148977 + * @flags: QMAN_CGR_FLAG_* values
148978 + * @opts: the CGR-modification settings
148979 + *
148980 + * The @opts parameter comes from the low-level portal API, and can be NULL.
148981 + * Note that some fields and options within @opts may be ignored or overwritten
148982 + * by the driver, in particular the 'cgrid' field is ignored (this operation
148983 + * only affects the given CGR object). If @flags contains
148984 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
148985 + * unspecified parameters) will be used rather than a modify hw hardware (which
148986 + * only modifies the specified parameters).
148987 + */
148988 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
148989 + struct qm_mcc_initcgr *opts);
148990 +
148991 +/**
148992 +* qman_query_cgr - Queries CGR fields
148993 +* @cgr: the 'cgr' object to query
148994 +* @result: storage for the queried congestion group record
148995 +*/
148996 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
148997 +
148998 +/**
148999 + * qman_query_congestion - Queries the state of all congestion groups
149000 + * @congestion: storage for the queried state of all congestion groups
149001 + */
149002 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
149003 +
149004 +/**
149005 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
149006 + * @result: is set by the API to the base CGR ID of the allocated range
149007 + * @count: the number of CGR IDs required
149008 + * @align: required alignment of the allocated range
149009 + * @partial: non-zero if the API can return fewer than @count
149010 + *
149011 + * Returns the number of CGR IDs allocated, or a negative error code.
149012 + * If @partial is non zero, the allocation request may return a smaller range of
149013 + * than requested (though alignment will be as requested). If @partial is zero,
149014 + * the return value will either be 'count' or negative.
149015 + */
149016 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
149017 +static inline int qman_alloc_cgrid(u32 *result)
149018 +{
149019 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
149020 + return (ret > 0) ? 0 : ret;
149021 +}
149022 +
149023 +/**
149024 + * qman_release_cgrid_range - Release the specified range of CGR IDs
149025 + * @id: the base CGR ID of the range to deallocate
149026 + * @count: the number of CGR IDs in the range
149027 + */
149028 +void qman_release_cgrid_range(u32 id, unsigned int count);
149029 +static inline void qman_release_cgrid(u32 id)
149030 +{
149031 + qman_release_cgrid_range(id, 1);
149032 +}
149033 +
149034 +/**
149035 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
149036 + * @id: the base CGR ID of the range to reserve
149037 + * @count: the number of CGR IDs in the range
149038 + */
149039 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
149040 +static inline int qman_reserve_cgrid(u32 id)
149041 +{
149042 + return qman_reserve_cgrid_range(id, 1);
149043 +}
149044 +
149045 +void qman_seed_cgrid_range(u32 id, unsigned int count);
149046 +
149047 +
149048 + /* Helpers */
149049 + /* ------- */
149050 +/**
149051 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
149052 + * @fqid: the FQID that will be initialised by other s/w
149053 + *
149054 + * In many situations, a FQID is provided for communication between s/w
149055 + * entities, and whilst the consumer is responsible for initialising and
149056 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
149057 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
149058 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
149059 + * However, data can not be enqueued to the FQ until it is initialised out of
149060 + * the OOS state - this function polls for that condition. It is particularly
149061 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
149062 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
149063 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
149064 + * synchronise. The function returns zero for success, +1 if the FQ is still in
149065 + * the OOS state, or negative if there was an error.
149066 + */
149067 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
149068 +{
149069 + struct qm_mcr_queryfq_np np;
149070 + int err;
149071 + err = qman_query_fq_np(fq, &np);
149072 + if (err)
149073 + return err;
149074 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
149075 + return 1;
149076 + return 0;
149077 +}
149078 +
149079 + /* -------------- */
149080 + /* CEETM :: types */
149081 + /* -------------- */
149082 +/**
149083 + * Token Rate Structure
149084 + * Shaping rates are based on a "credit" system and a pre-configured h/w
149085 + * internal timer. The following type represents a shaper "rate" parameter as a
149086 + * fractional number of "tokens". Here's how it works. This (fractional) number
149087 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
149088 + * (up to a limit which is set by another shaper parameter). Every time a frame
149089 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
149090 + * bytes of data in the enqueued frame. A shaper will not allow itself to
149091 + * enqueue any frames if its token count is negative. As such;
149092 + *
149093 + * The rate at which data is enqueued is limited by the
149094 + * rate at which tokens are added.
149095 + *
149096 + * Therefore if the user knows the period between these h/w timer updates in
149097 + * seconds, they can calculate the maximum traffic rate of the shaper (in
149098 + * bytes-per-second) from the token rate. And vice versa, they can calculate
149099 + * the token rate to use in order to achieve a given traffic rate.
149100 + */
149101 +struct qm_ceetm_rate {
149102 + /* The token rate is; whole + (fraction/8192) */
149103 + u32 whole:11; /* 0..2047 */
149104 + u32 fraction:13; /* 0..8191 */
149105 +};
149106 +
149107 +struct qm_ceetm_weight_code {
149108 + /* The weight code is; 5 msbits + 3 lsbits */
149109 + u8 y:5;
149110 + u8 x:3;
149111 +};
149112 +
149113 +struct qm_ceetm {
149114 + unsigned int idx;
149115 + struct list_head sub_portals;
149116 + struct list_head lnis;
149117 + unsigned int sp_range[2];
149118 + unsigned int lni_range[2];
149119 +};
149120 +
149121 +struct qm_ceetm_sp {
149122 + struct list_head node;
149123 + unsigned int idx;
149124 + unsigned int dcp_idx;
149125 + int is_claimed;
149126 + struct qm_ceetm_lni *lni;
149127 +};
149128 +
149129 +/* Logical Network Interface */
149130 +struct qm_ceetm_lni {
149131 + struct list_head node;
149132 + unsigned int idx;
149133 + unsigned int dcp_idx;
149134 + int is_claimed;
149135 + struct qm_ceetm_sp *sp;
149136 + struct list_head channels;
149137 + int shaper_enable;
149138 + int shaper_couple;
149139 + int oal;
149140 + struct qm_ceetm_rate cr_token_rate;
149141 + struct qm_ceetm_rate er_token_rate;
149142 + u16 cr_token_bucket_limit;
149143 + u16 er_token_bucket_limit;
149144 +};
149145 +
149146 +/* Class Queue Channel */
149147 +struct qm_ceetm_channel {
149148 + struct list_head node;
149149 + unsigned int idx;
149150 + unsigned int lni_idx;
149151 + unsigned int dcp_idx;
149152 + struct list_head class_queues;
149153 + struct list_head ccgs;
149154 + u8 shaper_enable;
149155 + u8 shaper_couple;
149156 + struct qm_ceetm_rate cr_token_rate;
149157 + struct qm_ceetm_rate er_token_rate;
149158 + u16 cr_token_bucket_limit;
149159 + u16 er_token_bucket_limit;
149160 +};
149161 +
149162 +struct qm_ceetm_ccg;
149163 +
149164 +/* This callback type is used when handling congestion entry/exit. The
149165 + * 'cb_ctx' value is the opaque value associated with ccg object.
149166 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
149167 + */
149168 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
149169 + int congested);
149170 +
149171 +/* Class Congestion Group */
149172 +struct qm_ceetm_ccg {
149173 + struct qm_ceetm_channel *parent;
149174 + struct list_head node;
149175 + struct list_head cb_node;
149176 + qman_cb_ccgr cb;
149177 + void *cb_ctx;
149178 + unsigned int idx;
149179 +};
149180 +
149181 +/* Class Queue */
149182 +struct qm_ceetm_cq {
149183 + struct qm_ceetm_channel *parent;
149184 + struct qm_ceetm_ccg *ccg;
149185 + struct list_head node;
149186 + unsigned int idx;
149187 + int is_claimed;
149188 + struct list_head bound_lfqids;
149189 + struct list_head binding_node;
149190 +};
149191 +
149192 +/* Logical Frame Queue */
149193 +struct qm_ceetm_lfq {
149194 + struct qm_ceetm_channel *parent;
149195 + struct list_head node;
149196 + unsigned int idx;
149197 + unsigned int dctidx;
149198 + u64 context_a;
149199 + u32 context_b;
149200 + qman_cb_mr ern;
149201 +};
149202 +
149203 +/**
149204 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
149205 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
149206 + * approximates that rate.
149207 + * @bps: the desired shaper rate in bps.
149208 + * @token_rate: the output token rate computed with the given kbps.
149209 + * @rounding: dictates how to round if an exact conversion is not possible; if
149210 + * it is negative then 'token_rate' will round down to the highest value that
149211 + * does not exceed the desired rate, if it is positive then 'token_rate' will
149212 + * round up to the lowest value that is greater than or equal to the desired
149213 + * rate, and if it is zero then it will round to the nearest approximation,
149214 + * whether that be up or down.
149215 + *
149216 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
149217 + */
149218 +int qman_ceetm_bps2tokenrate(u64 bps,
149219 + struct qm_ceetm_rate *token_rate,
149220 + int rounding);
149221 +
149222 +/**
149223 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
149224 + * corresponding number of 'bps'.
149225 + * @token_rate: the input desired token_rate fraction.
149226 + * @bps: the output shaper rate in bps computed with the give token rate.
149227 + * @rounding: has the same semantics as the previous function.
149228 + *
149229 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
149230 + */
149231 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
149232 + u64 *bps,
149233 + int rounding);
149234 +
149235 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
149236 + int partial);
149237 +static inline int qman_alloc_ceetm0_channel(u32 *result)
149238 +{
149239 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
149240 + return (ret > 0) ? 0 : ret;
149241 +}
149242 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
149243 +static inline void qman_release_ceetm0_channelid(u32 channelid)
149244 +{
149245 + qman_release_ceetm0_channel_range(channelid, 1);
149246 +}
149247 +
149248 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
149249 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
149250 +{
149251 + return qman_reserve_ceetm0_channel_range(channelid, 1);
149252 +}
149253 +
149254 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
149255 +
149256 +
149257 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
149258 + int partial);
149259 +static inline int qman_alloc_ceetm1_channel(u32 *result)
149260 +{
149261 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
149262 + return (ret > 0) ? 0 : ret;
149263 +}
149264 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
149265 +static inline void qman_release_ceetm1_channelid(u32 channelid)
149266 +{
149267 + qman_release_ceetm1_channel_range(channelid, 1);
149268 +}
149269 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
149270 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
149271 +{
149272 + return qman_reserve_ceetm1_channel_range(channelid, 1);
149273 +}
149274 +
149275 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
149276 +
149277 +
149278 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
149279 + int partial);
149280 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
149281 +{
149282 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
149283 + return (ret > 0) ? 0 : ret;
149284 +}
149285 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
149286 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
149287 +{
149288 + qman_release_ceetm0_lfqid_range(lfqid, 1);
149289 +}
149290 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
149291 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
149292 +{
149293 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
149294 +}
149295 +
149296 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
149297 +
149298 +
149299 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
149300 + int partial);
149301 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
149302 +{
149303 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
149304 + return (ret > 0) ? 0 : ret;
149305 +}
149306 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
149307 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
149308 +{
149309 + qman_release_ceetm1_lfqid_range(lfqid, 1);
149310 +}
149311 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
149312 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
149313 +{
149314 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
149315 +}
149316 +
149317 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
149318 +
149319 +
149320 + /* ----------------------------- */
149321 + /* CEETM :: sub-portals */
149322 + /* ----------------------------- */
149323 +
149324 +/**
149325 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
149326 + * to us and configured for traffic-management.
149327 + * @sp: the returned sub-portal object, if successful.
149328 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
149329 + * instance),
149330 + * @sp_idx" is the desired sub-portal index from 0 to 15.
149331 + *
149332 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
149333 + * if the sp_idx is out of range.
149334 + *
149335 + * Note that if there are multiple driver domains (eg. a linux kernel versus
149336 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
149337 + * then a sub-portal may be accessible by more than one instance of a qman
149338 + * driver and so it may be claimed multiple times. If this is the case, it is
149339 + * up to the system architect to prevent conflicting configuration actions
149340 + * coming from the different driver domains. The qman drivers do not have any
149341 + * behind-the-scenes coordination to prevent this from happening.
149342 + */
149343 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
149344 + enum qm_dc_portal dcp_idx,
149345 + unsigned int sp_idx);
149346 +
149347 +/**
149348 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
149349 + * @sp: the sub-portal to be released.
149350 + *
149351 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
149352 + * released.
149353 + */
149354 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
149355 +
149356 + /* ----------------------------------- */
149357 + /* CEETM :: logical network interfaces */
149358 + /* ----------------------------------- */
149359 +
149360 +/**
149361 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
149362 + * @lni: the returned LNI object, if successful.
149363 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
149364 + * instance)
149365 + * @lni_idx: is the desired LNI index.
149366 + *
149367 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
149368 + * is not available or has already been claimed (and not yet successfully
149369 + * released), or lni_dix is out of range.
149370 + *
149371 + * Note that there may be multiple driver domains (or instances) that need to
149372 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
149373 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
149374 + * qman_ceetm_sp_get_lni() for more information.
149375 + */
149376 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
149377 + enum qm_dc_portal dcp_id,
149378 + unsigned int lni_idx);
149379 +
149380 +/**
149381 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
149382 + * @lni: the lni needs to be released.
149383 + *
149384 + * This will only succeed if all dependent objects have been released.
149385 + * Returns zero for success, or -EBUSY if the dependencies are not released.
149386 + */
149387 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
149388 +
149389 +/**
149390 + * qman_ceetm_sp_set_lni
149391 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
149392 + * mapped to.
149393 + * @sp: the given sub-portal.
149394 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
149395 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
149396 + *
149397 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
149398 + * mapping has been set, or configure mapping command returns error, and
149399 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
149400 + * mapping command returns error.
149401 + *
149402 + * This may be useful in situations where multiple driver domains have access
149403 + * to the same sub-portals in order to all be able to transmit out the same
149404 + * physical interface (perhaps they're on different IP addresses or VPNs, so
149405 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
149406 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
149407 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
149408 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
149409 + * in order to determine the LNI that the control-plane had assigned. This is
149410 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
149411 + * LNI object.
149412 + */
149413 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
149414 + struct qm_ceetm_lni *lni);
149415 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
149416 + unsigned int *lni_idx);
149417 +
149418 +/**
149419 + * qman_ceetm_lni_enable_shaper
149420 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
149421 + * @lni: the given LNI.
149422 + * @coupled: indicates whether CR and ER are coupled.
149423 + * @oal: the overhead accounting length which is added to the actual length of
149424 + * each frame when performing shaper calculations.
149425 + *
149426 + * When the number of (unused) committed-rate tokens reach the committed-rate
149427 + * token limit, 'coupled' indicates whether surplus tokens should be added to
149428 + * the excess-rate token count (up to the excess-rate token limit).
149429 + * When LNI is claimed, the shaper is disabled by default. The enable function
149430 + * will turn on this shaper for this lni.
149431 + * Whenever a claimed LNI is first enabled for shaping, its committed and
149432 + * excess token rates and limits are zero, so will need to be changed to do
149433 + * anything useful. The shaper can subsequently be enabled/disabled without
149434 + * resetting the shaping parameters, but the shaping parameters will be reset
149435 + * when the LNI is released.
149436 + *
149437 + * Returns zero for success, or errno for "enable" function in the cases as:
149438 + * a) -EINVAL if the shaper is already enabled,
149439 + * b) -EIO if the configure shaper command returns error.
149440 + * For "disable" function, returns:
149441 + * a) -EINVAL if the shaper is has already disabled.
149442 + * b) -EIO if calling configure shaper command returns error.
149443 + */
149444 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
149445 + int oal);
149446 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
149447 +
149448 +/**
149449 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
149450 + * @lni: the give LNI
149451 + */
149452 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
149453 +
149454 +/**
149455 + * qman_ceetm_lni_set_commit_rate
149456 + * qman_ceetm_lni_get_commit_rate
149457 + * qman_ceetm_lni_set_excess_rate
149458 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
149459 + * token limit for the given LNI.
149460 + * @lni: the given LNI.
149461 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
149462 + * the LNI queried by "get" function.
149463 + * @token_limit: the desired token bucket limit for "set" function, or the token
149464 + * limit of the given LNI queried by "get" function.
149465 + *
149466 + * Returns zero for success. The "set" function returns -EINVAL if the given
149467 + * LNI is unshapped or -EIO if the configure shaper command returns error.
149468 + * The "get" function returns -EINVAL if the token rate or the token limit is
149469 + * not set or the query command returns error.
149470 + */
149471 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
149472 + const struct qm_ceetm_rate *token_rate,
149473 + u16 token_limit);
149474 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
149475 + struct qm_ceetm_rate *token_rate,
149476 + u16 *token_limit);
149477 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
149478 + const struct qm_ceetm_rate *token_rate,
149479 + u16 token_limit);
149480 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
149481 + struct qm_ceetm_rate *token_rate,
149482 + u16 *token_limit);
149483 +/**
149484 + * qman_ceetm_lni_set_commit_rate_bps
149485 + * qman_ceetm_lni_get_commit_rate_bps
149486 + * qman_ceetm_lni_set_excess_rate_bps
149487 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
149488 + * and token limit for the given LNI.
149489 + * @lni: the given LNI.
149490 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
149491 + * of the LNI queried by "get" function.
149492 + * @token_limit: the desired token bucket limit for "set" function, or the token
149493 + * limit of the given LNI queried by "get" function.
149494 + *
149495 + * Returns zero for success. The "set" function returns -EINVAL if the given
149496 + * LNI is unshapped or -EIO if the configure shaper command returns error.
149497 + * The "get" function returns -EINVAL if the token rate or the token limit is
149498 + * not set or the query command returns error.
149499 + */
149500 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
149501 + u64 bps,
149502 + u16 token_limit);
149503 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
149504 + u64 *bps, u16 *token_limit);
149505 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
149506 + u64 bps,
149507 + u16 token_limit);
149508 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
149509 + u64 *bps, u16 *token_limit);
149510 +
149511 +/**
149512 + * qman_ceetm_lni_set_tcfcc
149513 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
149514 + * @lni: the given LNI.
149515 + * @cq_level: is between 0 and 15, representing individual class queue levels
149516 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
149517 + * for every channel).
149518 + * @traffic_class: is between 0 and 7 when associating a given class queue level
149519 + * to a traffic class, or -1 when disabling traffic class flow control for this
149520 + * class queue level.
149521 + *
149522 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
149523 + * of range as indicated above, or -EIO if the configure/query tcfcc command
149524 + * returns error.
149525 + *
149526 + * Refer to the section of QMan CEETM traffic class flow control in the
149527 + * Reference Manual.
149528 + */
149529 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
149530 + unsigned int cq_level,
149531 + int traffic_class);
149532 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
149533 + unsigned int cq_level,
149534 + int *traffic_class);
149535 +
149536 + /* ----------------------------- */
149537 + /* CEETM :: class queue channels */
149538 + /* ----------------------------- */
149539 +
149540 +/**
149541 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
149542 + * the given LNI.
149543 + * @channel: the returned class queue channel object, if successful.
149544 + * @lni: the LNI that the channel belongs to.
149545 + *
149546 + * Channels are always initially "unshaped".
149547 + *
149548 + * Return zero for success, or -ENODEV if there is no channel available(all 32
149549 + * channels are claimed) or -EINVAL if the channel mapping command returns
149550 + * error.
149551 + */
149552 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
149553 + struct qm_ceetm_lni *lni);
149554 +
149555 +/**
149556 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
149557 + * @channel: the channel needs to be released.
149558 + *
149559 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
149560 + *
149561 + * Note any shaping of the channel will be cleared to leave it in an unshaped
149562 + * state.
149563 + */
149564 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
149565 +
149566 +/**
149567 + * qman_ceetm_channel_enable_shaper
149568 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
149569 + * @channel: the given channel.
149570 + * @coupled: indicates whether surplus CR tokens should be added to the
149571 + * excess-rate token count (up to the excess-rate token limit) when the number
149572 + * of (unused) committed-rate tokens reach the committed_rate token limit.
149573 + *
149574 + * Whenever a claimed channel is first enabled for shaping, its committed and
149575 + * excess token rates and limits are zero, so will need to be changed to do
149576 + * anything useful. The shaper can subsequently be enabled/disabled without
149577 + * resetting the shaping parameters, but the shaping parameters will be reset
149578 + * when the channel is released.
149579 + *
149580 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
149581 + * shaper has been enabled/disabled or the management command returns error.
149582 + */
149583 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
149584 + int coupled);
149585 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
149586 +
149587 +/**
149588 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
149589 + * @channel: the give channel.
149590 + */
149591 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
149592 +
149593 +/**
149594 + * qman_ceetm_channel_set_commit_rate
149595 + * qman_ceetm_channel_get_commit_rate
149596 + * qman_ceetm_channel_set_excess_rate
149597 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
149598 + * @channel: the given channel.
149599 + * @token_rate: the desired token rate for "set" function, or the queried token
149600 + * rate for "get" function.
149601 + * @token_limit: the desired token limit for "set" function, or the queried
149602 + * token limit for "get" function.
149603 + *
149604 + * Return zero for success. The "set" function returns -EINVAL if the channel
149605 + * is unshaped, or -EIO if the configure shapper command returns error. The
149606 + * "get" function returns -EINVAL if token rate of token limit is not set, or
149607 + * the query shaper command returns error.
149608 + */
149609 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
149610 + const struct qm_ceetm_rate *token_rate,
149611 + u16 token_limit);
149612 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
149613 + struct qm_ceetm_rate *token_rate,
149614 + u16 *token_limit);
149615 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
149616 + const struct qm_ceetm_rate *token_rate,
149617 + u16 token_limit);
149618 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
149619 + struct qm_ceetm_rate *token_rate,
149620 + u16 *token_limit);
149621 +/**
149622 + * qman_ceetm_channel_set_commit_rate_bps
149623 + * qman_ceetm_channel_get_commit_rate_bps
149624 + * qman_ceetm_channel_set_excess_rate_bps
149625 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
149626 + * parameters.
149627 + * @channel: the given channel.
149628 + * @token_rate: the desired shaper rate in bps for "set" function, or the
149629 + * shaper rate in bps for "get" function.
149630 + * @token_limit: the desired token limit for "set" function, or the queried
149631 + * token limit for "get" function.
149632 + *
149633 + * Return zero for success. The "set" function returns -EINVAL if the channel
149634 + * is unshaped, or -EIO if the configure shapper command returns error. The
149635 + * "get" function returns -EINVAL if token rate of token limit is not set, or
149636 + * the query shaper command returns error.
149637 + */
149638 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
149639 + u64 bps, u16 token_limit);
149640 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
149641 + u64 *bps, u16 *token_limit);
149642 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
149643 + u64 bps, u16 token_limit);
149644 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
149645 + u64 *bps, u16 *token_limit);
149646 +
149647 +/**
149648 + * qman_ceetm_channel_set_weight
149649 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
149650 + * @channel: the given channel.
149651 + * @token_limit: the desired token limit as the weight of the unshaped channel
149652 + * for "set" function, or the queried token limit for "get" function.
149653 + *
149654 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
149655 + * It allows the unshaped channels to be included in the CR time eligible list,
149656 + * and thus use the configured CR token limit value as their fair queuing
149657 + * weight.
149658 + *
149659 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
149660 + * the management command returns error.
149661 + */
149662 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
149663 + u16 token_limit);
149664 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
149665 + u16 *token_limit);
149666 +
149667 +/**
149668 + * qman_ceetm_channel_set_group
149669 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
149670 + * @channel: the given channel.
149671 + * @group_b: indicates whether there is group B in this channel.
149672 + * @prio_a: the priority of group A.
149673 + * @prio_b: the priority of group B.
149674 + *
149675 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
149676 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
149677 + * group A, otherwise they are split into group A (CQ8-11) and group B
149678 + * (CQ12-C15). The individual class queues and the group(s) are in strict
149679 + * priority order relative to each other. Within the group(s), the scheduling
149680 + * is not strict priority order, but the result of scheduling within a group
149681 + * is in strict priority order relative to the other class queues in the
149682 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
149683 + * relative to the individual class queues, and take values from 0-7. Eg. if
149684 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
149685 + * priority order would be;
149686 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
149687 + *
149688 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
149689 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
149690 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
149691 + * the configure scheduler command returns error. For "get" function, return
149692 + * -EINVAL if the query scheduler command returns error.
149693 + */
149694 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
149695 + int group_b,
149696 + unsigned int prio_a,
149697 + unsigned int prio_b);
149698 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
149699 + int *group_b,
149700 + unsigned int *prio_a,
149701 + unsigned int *prio_b);
149702 +
149703 +/**
149704 + * qman_ceetm_channel_set_group_cr_eligibility
149705 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
149706 + * @channel: the given channel object
149707 + * @group_b: indicates whether there is group B in this channel.
149708 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
149709 + *
149710 + * Return zero for success, or -EINVAL if eligibility setting fails.
149711 +*/
149712 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
149713 + *channel, int group_b, int cre);
149714 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
149715 + *channel, int group_b, int ere);
149716 +
149717 +/**
149718 + * qman_ceetm_channel_set_cq_cr_eligibility
149719 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
149720 + * @channel: the given channel object
149721 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
149722 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
149723 + *
149724 + * Return zero for success, or -EINVAL if eligibility setting fails.
149725 +*/
149726 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
149727 + unsigned int idx, int cre);
149728 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
149729 + unsigned int idx, int ere);
149730 +
149731 + /* --------------------- */
149732 + /* CEETM :: class queues */
149733 + /* --------------------- */
149734 +
149735 +/**
149736 + * qman_ceetm_cq_claim - Claims an individual class queue.
149737 + * @cq: the returned class queue object, if successful.
149738 + * @channel: the class queue channel.
149739 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
149740 + * @ccg: represents the class congestion group that this class queue should be
149741 + * subscribed to, or NULL if no congestion group membership is desired.
149742 + *
149743 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
149744 + * if this class queue has been claimed, or configure class queue command
149745 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
149746 + */
149747 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
149748 + struct qm_ceetm_channel *channel,
149749 + unsigned int idx,
149750 + struct qm_ceetm_ccg *ccg);
149751 +
149752 +/**
149753 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
149754 + * @cq: the returned class queue object, if successful.
149755 + * @channel: the class queue channel.
149756 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
149757 + * @ccg: represents the class congestion group that this class queue should be
149758 + * subscribed to, or NULL if no congestion group membership is desired.
149759 + *
149760 + * Return zero for success, or -EINVAL if @idx is out the range or if
149761 + * this class queue has been claimed or configure class queue command returns
149762 + * error, or returns -ENOMEM if allocating CQ memory fails.
149763 + */
149764 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
149765 + struct qm_ceetm_channel *channel,
149766 + unsigned int idx,
149767 + struct qm_ceetm_ccg *ccg);
149768 +
149769 +/**
149770 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
149771 + * @cq: the returned class queue object, if successful.
149772 + * @channel: the class queue channel.
149773 + * @idx: is from 0 to 3 (CQ12 to CQ15).
149774 + * @ccg: represents the class congestion group that this class queue should be
149775 + * subscribed to, or NULL if no congestion group membership is desired.
149776 + *
149777 + * Return zero for success, or -EINVAL if @idx is out the range or if
149778 + * this class queue has been claimed or configure class queue command returns
149779 + * error, or returns -ENOMEM if allocating CQ memory fails.
149780 + */
149781 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
149782 + struct qm_ceetm_channel *channel,
149783 + unsigned int idx,
149784 + struct qm_ceetm_ccg *ccg);
149785 +
149786 +/**
149787 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
149788 + * @cq: The class queue to be released.
149789 + *
149790 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
149791 + * FQIDs) have not been released.
149792 + */
149793 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
149794 +
149795 +/**
149796 + * qman_ceetm_set_queue_weight
149797 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
149798 + * queue.
149799 + * @cq: the given class queue.
149800 + * @weight_code: the desired weight code to set for the given class queue for
149801 + * "set" function or the queired weight code for "get" function.
149802 + *
149803 + * Grouped class queues have a default weight code of zero, which corresponds to
149804 + * a scheduler weighting of 1. This function can be used to modify a grouped
149805 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
149806 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
149807 + * and the corresponding sharing weight.)
149808 + *
149809 + * Returns zero for success, or -EIO if the configure weight command returns
149810 + * error for "set" function, or -EINVAL if the query command returns
149811 + * error for "get" function.
149812 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
149813 + * Manual for weight and weight code.
149814 + */
149815 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
149816 + struct qm_ceetm_weight_code *weight_code);
149817 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
149818 + struct qm_ceetm_weight_code *weight_code);
149819 +
149820 +/**
149821 + * qman_ceetm_set_queue_weight_in_ratio
149822 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
149823 + * grouped class queue.
149824 + * @cq: the given class queue.
149825 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
149826 + * by 100 to get rid of fraction.
149827 + *
149828 + * Returns zero for success, or -EIO if the configure weight command returns
149829 + * error for "set" function, or -EINVAL if the query command returns
149830 + * error for "get" function.
149831 + */
149832 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
149833 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
149834 +
149835 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
149836 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
149837 + * corresponding to intermediate weight codes are calculated using linear
149838 + * interpolation on the inverted values. Or put another way, the inverse weights
149839 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
149840 + * between these are divided linearly into 32 intermediate values, the inverses
149841 + * of which form the remaining weight codes.
149842 + *
149843 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
149844 + * scheduling within a group of class queues (group A or B). Weights are used to
149845 + * normalise the class queues to an underlying BFS algorithm where all class
149846 + * queues are assumed to require "equal bandwidth". So the weights referred to
149847 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
149848 + * one class queue in a group is assigned a weight of 2 whilst the other class
149849 + * queues in the group keep the default weight of 1, then the WBFS scheduler
149850 + * will effectively treat all frames enqueued on the weight-2 class queue as
149851 + * having half the number of bytes they really have. Ie. if all other things are
149852 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
149853 + * the others. So weights should be chosen to provide bandwidth ratios between
149854 + * members of the same class queue group. These weights have no bearing on
149855 + * behaviour outside that group's WBFS mechanism though.
149856 + */
149857 +
149858 +/**
149859 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
149860 + * representation of the corresponding weight is given (in order to not lose
149861 + * any precision).
149862 + * @weight_code: The given weight code in WBFS.
149863 + * @numerator: the numerator part of the weight computed by the weight code.
149864 + * @denominator: the denominator part of the weight computed by the weight code
149865 + *
149866 + * Returns zero for success or -EINVAL if the given weight code is illegal.
149867 + */
149868 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
149869 + u32 *numerator,
149870 + u32 *denominator);
149871 +/**
149872 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
149873 + * If the user needs to know how close this is, convert the resulting weight
149874 + * code back to a weight and compare.
149875 + * @numerator: numerator part of the given weight.
149876 + * @denominator: denominator part of the given weight.
149877 + * @weight_code: the weight code computed from the given weight.
149878 + *
149879 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
149880 + * the range of weights.
149881 + */
149882 +int qman_ceetm_ratio2wbfs(u32 numerator,
149883 + u32 denominator,
149884 + struct qm_ceetm_weight_code *weight_code,
149885 + int rounding);
149886 +
149887 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
149888 +/**
149889 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
149890 + * CQ counters.
149891 + * @cq: the given CQ object.
149892 + * @flags: indicates whether the statistics counter will be cleared after query.
149893 + * @frame_count: The number of the frames that have been counted since the
149894 + * counter was cleared last time.
149895 + * @byte_count: the number of bytes in all frames that have been counted.
149896 + *
149897 + * Return zero for success or -EINVAL if query statistics command returns error.
149898 + *
149899 + */
149900 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
149901 + u64 *frame_count, u64 *byte_count);
149902 +
149903 +/**
149904 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
149905 + * @cq: the give CQ object.
149906 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
149907 + */
149908 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
149909 +
149910 + /* ---------------------- */
149911 + /* CEETM :: logical FQIDs */
149912 + /* ---------------------- */
149913 +/**
149914 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
149915 + * the given class queue.
149916 + * @lfq: the returned lfq object, if successful.
149917 + * @cq: the class queue which needs to claim a LFQID.
149918 + *
149919 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
149920 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
149921 + */
149922 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
149923 + struct qm_ceetm_cq *cq);
149924 +
149925 +/**
149926 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
149927 + * @lfq: the lfq to be released.
149928 + *
149929 + * Return zero for success.
149930 + */
149931 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
149932 +
149933 +/**
149934 + * qman_ceetm_lfq_set_context
149935 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
149936 + * "dequeue context table" associated with the logical FQID.
149937 + * @lfq: the given logical FQ object.
149938 + * @context_a: contextA of the dequeue context.
149939 + * @context_b: contextB of the dequeue context.
149940 + *
149941 + * Returns zero for success, or -EINVAL if there is error to set/get the
149942 + * context pair.
149943 + */
149944 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
149945 + u64 context_a,
149946 + u32 context_b);
149947 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
149948 + u64 *context_a,
149949 + u32 *context_b);
149950 +
149951 +/**
149952 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
149953 + * @lfq: the given logic fq.
149954 + * @fq: the fq object created for the given logic fq.
149955 + *
149956 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
149957 + * target a logical FQID (and the class queue it is associated with).
149958 + * Note that this FQ object can only be used for enqueues, and
149959 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
149960 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
149961 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
149962 + * responsibility to ensure that the underlying 'lfq' is not released until any
149963 + * enqueues to this FQ object have completed. The only field the user needs to
149964 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
149965 + * could conceivably be called on this FQ object. This API can be called
149966 + * multiple times to create multiple FQ objects referring to the same logical
149967 + * FQID, and any enqueue rejections will respect the callback of the object that
149968 + * issued the enqueue (and will identify the object via the parameter passed to
149969 + * the callback too). There is no 'flags' parameter to this API as there is for
149970 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
149971 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
149972 + *
149973 + * Returns 0 for success.
149974 + */
149975 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
149976 +
149977 + /* -------------------------------- */
149978 + /* CEETM :: class congestion groups */
149979 + /* -------------------------------- */
149980 +
149981 +/**
149982 + * qman_ceetm_ccg_claim - Claims an unused CCG.
149983 + * @ccg: the returned CCG object, if successful.
149984 + * @channel: the given class queue channel
149985 + * @cscn: the callback function of this CCG.
149986 + * @cb_ctx: the corresponding context to be used used if state change
149987 + * notifications are later enabled for this CCG.
149988 + *
149989 + * The congestion group is local to the given class queue channel, so only
149990 + * class queues within the channel can be associated with that congestion group.
149991 + * The association of class queues to congestion groups occurs when the class
149992 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
149993 + * Congestion groups are in a "zero" state when initially claimed, and they are
149994 + * returned to that state when released.
149995 + *
149996 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
149997 + */
149998 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
149999 + struct qm_ceetm_channel *channel,
150000 + unsigned int idx,
150001 + void (*cscn)(struct qm_ceetm_ccg *,
150002 + void *cb_ctx,
150003 + int congested),
150004 + void *cb_ctx);
150005 +
150006 +/**
150007 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
150008 + * @ccg: the given ccg.
150009 + *
150010 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
150011 + * (class queues that are associated with the CCG) have not been released.
150012 + */
150013 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
150014 +
150015 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
150016 + * controls which CCG attributes are to be updated, and the remainder specify
150017 + * the values for those attributes. A CCG counts either frames or the bytes
150018 + * within those frames, but not both ('mode'). A CCG can optionally cause
150019 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
150020 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
150021 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
150022 + * to a "congestion state", but not both ('td_mode'). Congestion state has
150023 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
150024 + * notifications can be sent to software the CCG goes in to and out of this
150025 + * congested state ('cscn_en'). */
150026 +struct qm_ceetm_ccg_params {
150027 + /* Boolean fields together in a single bitfield struct */
150028 + struct {
150029 + /* Whether to count bytes or frames. 1==frames */
150030 + u8 mode:1;
150031 + /* En/disable tail-drop. 1==enable */
150032 + u8 td_en:1;
150033 + /* Tail-drop on congestion-state or threshold. 1=threshold */
150034 + u8 td_mode:1;
150035 + /* Generate congestion state change notifications. 1==enable */
150036 + u8 cscn_en:1;
150037 + /* Enable WRED rejections (per colour). 1==enable */
150038 + u8 wr_en_g:1;
150039 + u8 wr_en_y:1;
150040 + u8 wr_en_r:1;
150041 + } __packed;
150042 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
150043 + struct qm_cgr_cs_thres td_thres;
150044 + /* Congestion state thresholds, for entry and exit. */
150045 + struct qm_cgr_cs_thres cs_thres_in;
150046 + struct qm_cgr_cs_thres cs_thres_out;
150047 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
150048 + signed char oal;
150049 + /* Congestion state change notification for DCP portal, virtual CCGID*/
150050 + /* WRED parameters. */
150051 + struct qm_cgr_wr_parm wr_parm_g;
150052 + struct qm_cgr_wr_parm wr_parm_y;
150053 + struct qm_cgr_wr_parm wr_parm_r;
150054 +};
150055 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
150056 + * the CCGR are to be updated. */
150057 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
150058 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
150059 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
150060 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
150061 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
150062 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
150063 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
150064 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
150065 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
150066 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
150067 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
150068 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
150069 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
150070 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
150071 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
150072 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
150073 +
150074 +/**
150075 + * qman_ceetm_ccg_set
150076 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
150077 + * @ccg: the given CCG object.
150078 + * @we_mask: the write enable mask.
150079 + * @params: the parameters setting for this ccg
150080 + *
150081 + * Return 0 for success, or -EIO if configure ccg command returns error for
150082 + * "set" function, or -EINVAL if query ccg command returns error for "get"
150083 + * function.
150084 + */
150085 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
150086 + u16 we_mask,
150087 + const struct qm_ceetm_ccg_params *params);
150088 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
150089 + struct qm_ceetm_ccg_params *params);
150090 +
150091 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
150092 + * mask.
150093 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
150094 + * in the cscn target mask.
150095 + * @ccg: the give CCG object.
150096 + * @swp_idx: the index of the software portal.
150097 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
150098 + * the target mask.
150099 + * @we_mask: the write enable mask.
150100 + * @params: the parameters setting for this ccg
150101 + *
150102 + * Return 0 for success, or -EINVAL if command in set/get function fails.
150103 + */
150104 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
150105 + u16 swp_idx,
150106 + unsigned int cscn_enabled,
150107 + u16 we_mask,
150108 + const struct qm_ceetm_ccg_params *params);
150109 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
150110 + u16 swp_idx,
150111 + unsigned int *cscn_enabled);
150112 +
150113 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
150114 + * target mask.
150115 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
150116 + * is in the cscn target mask.
150117 + * @ccg: the give CCG object.
150118 + * @dcp_idx: the index of the direct connect portal.
150119 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
150120 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
150121 + * the target mask.
150122 + * @we_mask: the write enable mask.
150123 + * @params: the parameters setting for this ccg
150124 + *
150125 + * Return 0 for success, or -EINVAL if command in set/get function fails.
150126 + */
150127 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
150128 + u16 dcp_idx,
150129 + u8 vcgid,
150130 + unsigned int cscn_enabled,
150131 + u16 we_mask,
150132 + const struct qm_ceetm_ccg_params *params);
150133 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
150134 + u16 dcp_idx,
150135 + u8 *vcgid,
150136 + unsigned int *cscn_enabled);
150137 +
150138 +/**
150139 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
150140 + * CEETM CCG counters.
150141 + * @ccg: the given CCG object.
150142 + * @flags: indicates whether the statistics counter will be cleared after query.
150143 + * @frame_count: The number of the frames that have been counted since the
150144 + * counter was cleared last time.
150145 + * @byte_count: the number of bytes in all frames that have been counted.
150146 + *
150147 + * Return zero for success or -EINVAL if query statistics command returns error.
150148 + *
150149 + */
150150 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
150151 + u64 *frame_count, u64 *byte_count);
150152 +
150153 +/**
150154 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
150155 + * @lfqid: Logical Frame Queue ID
150156 + * @lfqmt_query: Results of the query command
150157 + *
150158 + * Returns zero for success or -EIO if the query command returns error.
150159 + *
150160 + */
150161 +int qman_ceetm_query_lfqmt(int lfqid,
150162 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
150163 +
150164 +/**
150165 + * qman_ceetm_query_cq - Queries a CEETM CQ
150166 + * @cqid: the channel ID (first byte) followed by the CQ idx
150167 + * @dcpid: CEETM portal ID
150168 + * @cq_query: storage for the queried CQ fields
150169 + *
150170 + * Returns zero for success or -EIO if the query command returns error.
150171 + *
150172 +*/
150173 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
150174 + struct qm_mcr_ceetm_cq_query *cq_query);
150175 +
150176 +/**
150177 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
150178 + * @cid: Target ID (CQID or CCGRID)
150179 + * @dcp_idx: CEETM portal ID
150180 + * @command_type: One of the following:
150181 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
150182 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
150183 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
150184 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
150185 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
150186 + * 5 = Write reject statistics. CID carries the CCGRID to be written
150187 + * @frame_count: Frame count value to be written if this is a write command
150188 + * @byte_count: Bytes count value to be written if this is a write command
150189 + *
150190 + * Returns zero for success or -EIO if the query command returns error.
150191 + */
150192 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
150193 + u16 command_type, u64 frame_count,
150194 + u64 byte_count);
150195 +
150196 +/**
150197 + * qman_set_wpm - Set waterfall power management
150198 + *
150199 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
150200 + *
150201 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
150202 + * accessible.
150203 + */
150204 +int qman_set_wpm(int wpm_enable);
150205 +
150206 +/**
150207 + * qman_get_wpm - Query the waterfall power management setting
150208 + *
150209 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
150210 + *
150211 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
150212 + * accessible.
150213 + */
150214 +int qman_get_wpm(int *wpm_enable);
150215 +
150216 +/* The below qman_p_***() variants might be called in a migration situation
150217 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
150218 + * execution was affine to prior to migration.
150219 + * @qman_portal specifies which portal the APIs will use.
150220 +*/
150221 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
150222 + *p);
150223 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
150224 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
150225 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
150226 +u32 qman_p_poll_slow(struct qman_portal *p);
150227 +void qman_p_poll(struct qman_portal *p);
150228 +void qman_p_stop_dequeues(struct qman_portal *p);
150229 +void qman_p_start_dequeues(struct qman_portal *p);
150230 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
150231 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
150232 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
150233 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
150234 + int park_request);
150235 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
150236 + u32 flags __maybe_unused, u32 vdqcr);
150237 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
150238 + const struct qm_fd *fd, u32 flags);
150239 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
150240 + const struct qm_fd *fd, u32 flags,
150241 + struct qman_fq *orp, u16 orp_seqnum);
150242 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
150243 + const struct qm_fd *fd, u32 flags,
150244 + qman_cb_precommit cb, void *cb_arg);
150245 +#ifdef __cplusplus
150246 +}
150247 +#endif
150248 +
150249 +#endif /* FSL_QMAN_H */
150250 --- /dev/null
150251 +++ b/include/linux/fsl_usdpaa.h
150252 @@ -0,0 +1,372 @@
150253 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
150254 + *
150255 + * This file is licensed under the terms of the GNU General Public License
150256 + * version 2. This program is licensed "as is" without any warranty of any
150257 + * kind, whether express or implied.
150258 + */
150259 +
150260 +#ifndef FSL_USDPAA_H
150261 +#define FSL_USDPAA_H
150262 +
150263 +#ifdef __cplusplus
150264 +extern "C" {
150265 +#endif
150266 +
150267 +#include <linux/uaccess.h>
150268 +#include <linux/ioctl.h>
150269 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
150270 +#include <linux/compat.h>
150271 +
150272 +#ifdef CONFIG_FSL_USDPAA
150273 +
150274 +/******************************/
150275 +/* Allocation of resource IDs */
150276 +/******************************/
150277 +
150278 +/* This enum is used to distinguish between the type of underlying object being
150279 + * manipulated. */
150280 +enum usdpaa_id_type {
150281 + usdpaa_id_fqid,
150282 + usdpaa_id_bpid,
150283 + usdpaa_id_qpool,
150284 + usdpaa_id_cgrid,
150285 + usdpaa_id_ceetm0_lfqid,
150286 + usdpaa_id_ceetm0_channelid,
150287 + usdpaa_id_ceetm1_lfqid,
150288 + usdpaa_id_ceetm1_channelid,
150289 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
150290 +};
150291 +#define USDPAA_IOCTL_MAGIC 'u'
150292 +struct usdpaa_ioctl_id_alloc {
150293 + uint32_t base; /* Return value, the start of the allocated range */
150294 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
150295 + uint32_t num; /* how many IDs to allocate (and return value) */
150296 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
150297 + int partial; /* whether to allow less than 'num' */
150298 +};
150299 +struct usdpaa_ioctl_id_release {
150300 + /* Input; */
150301 + enum usdpaa_id_type id_type;
150302 + uint32_t base;
150303 + uint32_t num;
150304 +};
150305 +struct usdpaa_ioctl_id_reserve {
150306 + enum usdpaa_id_type id_type;
150307 + uint32_t base;
150308 + uint32_t num;
150309 +};
150310 +
150311 +
150312 +/* ioctl() commands */
150313 +#define USDPAA_IOCTL_ID_ALLOC \
150314 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
150315 +#define USDPAA_IOCTL_ID_RELEASE \
150316 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
150317 +#define USDPAA_IOCTL_ID_RESERVE \
150318 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
150319 +
150320 +/**********************/
150321 +/* Mapping DMA memory */
150322 +/**********************/
150323 +
150324 +/* Maximum length for a map name, including NULL-terminator */
150325 +#define USDPAA_DMA_NAME_MAX 16
150326 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
150327 + * For a sharable and named map, specify _SHARED (whether creating one or
150328 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
150329 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
150330 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
150331 + * specified and the mapping already exists, the mapping will fail unless _LAZY
150332 + * is specified. When mapping to a pre-existing sharable map, the length must be
150333 + * an exact match. Lengths must be a power-of-4 multiple of page size.
150334 + *
150335 + * Note that this does not actually map the memory to user-space, that is done
150336 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
150337 + * ioctl() is what gives the process permission to do this, and a page-offset
150338 + * with which to do so.
150339 + */
150340 +#define USDPAA_DMA_FLAG_SHARE 0x01
150341 +#define USDPAA_DMA_FLAG_CREATE 0x02
150342 +#define USDPAA_DMA_FLAG_LAZY 0x04
150343 +#define USDPAA_DMA_FLAG_RDONLY 0x08
150344 +struct usdpaa_ioctl_dma_map {
150345 + /* Output parameters - virtual and physical addresses */
150346 + void *ptr;
150347 + uint64_t phys_addr;
150348 + /* Input parameter, the length of the region to be created (or if
150349 + * mapping an existing region, this must match it). Must be a power-of-4
150350 + * multiple of page size. */
150351 + uint64_t len;
150352 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
150353 + uint32_t flags;
150354 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
150355 + * of the existing mapping to use). */
150356 + char name[USDPAA_DMA_NAME_MAX];
150357 + /* If this ioctl() creates the mapping, this is an input parameter
150358 + * stating whether the region supports locking. If mapping an existing
150359 + * region, this is a return value indicating the same thing. */
150360 + int has_locking;
150361 + /* In the case of a successful map with _CREATE and _LAZY, this return
150362 + * value indicates whether we created the mapped region or whether it
150363 + * already existed. */
150364 + int did_create;
150365 +};
150366 +
150367 +#ifdef CONFIG_COMPAT
150368 +struct usdpaa_ioctl_dma_map_compat {
150369 + /* Output parameters - virtual and physical addresses */
150370 + compat_uptr_t ptr;
150371 + uint64_t phys_addr;
150372 + /* Input parameter, the length of the region to be created (or if
150373 + * mapping an existing region, this must match it). Must be a power-of-4
150374 + * multiple of page size. */
150375 + uint64_t len;
150376 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
150377 + uint32_t flags;
150378 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
150379 + * of the existing mapping to use). */
150380 + char name[USDPAA_DMA_NAME_MAX];
150381 + /* If this ioctl() creates the mapping, this is an input parameter
150382 + * stating whether the region supports locking. If mapping an existing
150383 + * region, this is a return value indicating the same thing. */
150384 + int has_locking;
150385 + /* In the case of a successful map with _CREATE and _LAZY, this return
150386 + * value indicates whether we created the mapped region or whether it
150387 + * already existed. */
150388 + int did_create;
150389 +};
150390 +
150391 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
150392 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
150393 +#endif
150394 +
150395 +
150396 +#define USDPAA_IOCTL_DMA_MAP \
150397 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
150398 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
150399 + * This ioctl will do both (though you can munmap() before calling the ioctl
150400 + * too). */
150401 +#define USDPAA_IOCTL_DMA_UNMAP \
150402 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
150403 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
150404 + * with a mmap()'d address, and the process will (interruptible) sleep if the
150405 + * lock is already held by another process. Process destruction will
150406 + * automatically clean up any held locks. */
150407 +#define USDPAA_IOCTL_DMA_LOCK \
150408 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
150409 +#define USDPAA_IOCTL_DMA_UNLOCK \
150410 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
150411 +
150412 +/***************************************/
150413 +/* Mapping and using QMan/BMan portals */
150414 +/***************************************/
150415 +enum usdpaa_portal_type {
150416 + usdpaa_portal_qman,
150417 + usdpaa_portal_bman,
150418 +};
150419 +
150420 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
150421 +
150422 +struct usdpaa_ioctl_portal_map {
150423 + /* Input parameter, is a qman or bman portal required. */
150424 +
150425 + enum usdpaa_portal_type type;
150426 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150427 + for don't care. The portal index will be populated by the
150428 + driver when the ioctl() successfully completes */
150429 + uint32_t index;
150430 +
150431 + /* Return value if the map succeeds, this gives the mapped
150432 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
150433 + struct usdpaa_portal_map {
150434 + void *cinh;
150435 + void *cena;
150436 + } addr;
150437 + /* Qman-specific return values */
150438 + uint16_t channel;
150439 + uint32_t pools;
150440 +};
150441 +
150442 +#ifdef CONFIG_COMPAT
150443 +struct compat_usdpaa_ioctl_portal_map {
150444 + /* Input parameter, is a qman or bman portal required. */
150445 + enum usdpaa_portal_type type;
150446 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150447 + for don't care. The portal index will be populated by the
150448 + driver when the ioctl() successfully completes */
150449 + uint32_t index;
150450 + /* Return value if the map succeeds, this gives the mapped
150451 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
150452 + struct usdpaa_portal_map_compat {
150453 + compat_uptr_t cinh;
150454 + compat_uptr_t cena;
150455 + } addr;
150456 + /* Qman-specific return values */
150457 + uint16_t channel;
150458 + uint32_t pools;
150459 +};
150460 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
150461 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
150462 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
150463 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
150464 +#endif
150465 +
150466 +#define USDPAA_IOCTL_PORTAL_MAP \
150467 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
150468 +#define USDPAA_IOCTL_PORTAL_UNMAP \
150469 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
150470 +
150471 +struct usdpaa_ioctl_irq_map {
150472 + enum usdpaa_portal_type type; /* Type of portal to map */
150473 + int fd; /* File descriptor that contains the portal */
150474 + void *portal_cinh; /* Cache inhibited area to identify the portal */
150475 +};
150476 +
150477 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
150478 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
150479 +
150480 +#ifdef CONFIG_COMPAT
150481 +
150482 +struct compat_ioctl_irq_map {
150483 + enum usdpaa_portal_type type; /* Type of portal to map */
150484 + compat_int_t fd; /* File descriptor that contains the portal */
150485 + compat_uptr_t portal_cinh; /* Used identify the portal */};
150486 +
150487 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
150488 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
150489 +#endif
150490 +
150491 +/* ioctl to query the amount of DMA memory used in the system */
150492 +struct usdpaa_ioctl_dma_used {
150493 + uint64_t free_bytes;
150494 + uint64_t total_bytes;
150495 +};
150496 +#define USDPAA_IOCTL_DMA_USED \
150497 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
150498 +
150499 +/* ioctl to allocate a raw portal */
150500 +struct usdpaa_ioctl_raw_portal {
150501 + /* inputs */
150502 + enum usdpaa_portal_type type; /* Type of portal to allocate */
150503 +
150504 + /* set to non zero to turn on stashing */
150505 + uint8_t enable_stash;
150506 + /* Stashing attributes for the portal */
150507 + uint32_t cpu;
150508 + uint32_t cache;
150509 + uint32_t window;
150510 +
150511 + /* Specifies the stash request queue this portal should use */
150512 + uint8_t sdest;
150513 +
150514 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150515 + * for don't care. The portal index will be populated by the
150516 + * driver when the ioctl() successfully completes */
150517 + uint32_t index;
150518 +
150519 + /* outputs */
150520 + uint64_t cinh;
150521 + uint64_t cena;
150522 +};
150523 +
150524 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
150525 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
150526 +
150527 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
150528 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
150529 +
150530 +#ifdef CONFIG_COMPAT
150531 +
150532 +struct compat_ioctl_raw_portal {
150533 + /* inputs */
150534 + enum usdpaa_portal_type type; /* Type of portal to allocate */
150535 +
150536 + /* set to non zero to turn on stashing */
150537 + uint8_t enable_stash;
150538 + /* Stashing attributes for the portal */
150539 + uint32_t cpu;
150540 + uint32_t cache;
150541 + uint32_t window;
150542 + /* Specifies the stash request queue this portal should use */
150543 + uint8_t sdest;
150544 +
150545 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150546 + * for don't care. The portal index will be populated by the
150547 + * driver when the ioctl() successfully completes */
150548 + uint32_t index;
150549 +
150550 + /* outputs */
150551 + uint64_t cinh;
150552 + uint64_t cena;
150553 +};
150554 +
150555 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
150556 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
150557 +
150558 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
150559 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
150560 +
150561 +#endif
150562 +
150563 +#ifdef __KERNEL__
150564 +
150565 +/* Early-boot hook */
150566 +int __init fsl_usdpaa_init_early(void);
150567 +
150568 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
150569 + * faults within its ranges via this hook. */
150570 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
150571 +
150572 +#endif /* __KERNEL__ */
150573 +
150574 +#endif /* CONFIG_FSL_USDPAA */
150575 +
150576 +#ifdef __KERNEL__
150577 +/* This interface is needed in a few places and though it's not specific to
150578 + * USDPAA as such, creating a new header for it doesn't make any sense. The
150579 + * qbman kernel driver implements this interface and uses it as the backend for
150580 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
150581 + * interface for tracking per-process allocations handed out to user-space. */
150582 +struct dpa_alloc {
150583 + struct list_head free;
150584 + spinlock_t lock;
150585 + struct list_head used;
150586 +};
150587 +#define DECLARE_DPA_ALLOC(name) \
150588 + struct dpa_alloc name = { \
150589 + .free = { \
150590 + .prev = &name.free, \
150591 + .next = &name.free \
150592 + }, \
150593 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
150594 + .used = { \
150595 + .prev = &name.used, \
150596 + .next = &name.used \
150597 + } \
150598 + }
150599 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
150600 +{
150601 + INIT_LIST_HEAD(&alloc->free);
150602 + INIT_LIST_HEAD(&alloc->used);
150603 + spin_lock_init(&alloc->lock);
150604 +}
150605 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
150606 + int partial);
150607 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
150608 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
150609 +
150610 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
150611 + * desired range is not available, or 0 for success. */
150612 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
150613 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
150614 + * 'alloc' is empty. */
150615 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
150616 +/* Returns 1 if the specified id is alloced, 0 otherwise */
150617 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
150618 +#endif /* __KERNEL__ */
150619 +
150620 +#ifdef __cplusplus
150621 +}
150622 +#endif
150623 +
150624 +#endif /* FSL_USDPAA_H */
150625 --- a/include/linux/netdev_features.h
150626 +++ b/include/linux/netdev_features.h
150627 @@ -79,6 +79,7 @@ enum {
150628 NETIF_F_HW_ESP_BIT, /* Hardware ESP transformation offload */
150629 NETIF_F_HW_ESP_TX_CSUM_BIT, /* ESP with TX checksum offload */
150630 NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */
150631 + NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */
150632
150633 /*
150634 * Add your fresh new feature above and remember to update
150635 @@ -144,6 +145,7 @@ enum {
150636 #define NETIF_F_HW_ESP __NETIF_F(HW_ESP)
150637 #define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM)
150638 #define NETIF_F_RX_UDP_TUNNEL_PORT __NETIF_F(RX_UDP_TUNNEL_PORT)
150639 +#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ)
150640
150641 /* Finds the next feature with the highest number of the range of start till 0.
150642 */
150643 --- /dev/null
150644 +++ b/include/uapi/linux/fmd/Kbuild
150645 @@ -0,0 +1,5 @@
150646 +header-y += integrations/
150647 +header-y += Peripherals/
150648 +
150649 +header-y += ioctls.h
150650 +header-y += net_ioctls.h
150651 --- /dev/null
150652 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
150653 @@ -0,0 +1,4 @@
150654 +header-y += fm_ioctls.h
150655 +header-y += fm_port_ioctls.h
150656 +header-y += fm_pcd_ioctls.h
150657 +header-y += fm_test_ioctls.h
150658 --- /dev/null
150659 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
150660 @@ -0,0 +1,628 @@
150661 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
150662 + * All rights reserved.
150663 + *
150664 + * Redistribution and use in source and binary forms, with or without
150665 + * modification, are permitted provided that the following conditions are met:
150666 + * * Redistributions of source code must retain the above copyright
150667 + * notice, this list of conditions and the following disclaimer.
150668 + * * Redistributions in binary form must reproduce the above copyright
150669 + * notice, this list of conditions and the following disclaimer in the
150670 + * documentation and/or other materials provided with the distribution.
150671 + * * Neither the name of Freescale Semiconductor nor the
150672 + * names of its contributors may be used to endorse or promote products
150673 + * derived from this software without specific prior written permission.
150674 + *
150675 + *
150676 + * ALTERNATIVELY, this software may be distributed under the terms of the
150677 + * GNU General Public License ("GPL") as published by the Free Software
150678 + * Foundation, either version 2 of that License or (at your option) any
150679 + * later version.
150680 + *
150681 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
150682 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
150683 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
150684 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
150685 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
150686 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
150687 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
150688 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
150689 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
150690 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
150691 + */
150692 +
150693 +/**************************************************************************//**
150694 + @File fm_ioctls.h
150695 +
150696 + @Description FM Char device ioctls
150697 +*//***************************************************************************/
150698 +#ifndef __FM_IOCTLS_H
150699 +#define __FM_IOCTLS_H
150700 +
150701 +
150702 +/**************************************************************************//**
150703 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
150704 +
150705 + @Description FM Linux ioctls definitions and enums
150706 +
150707 + @{
150708 +*//***************************************************************************/
150709 +
150710 +/**************************************************************************//**
150711 + @Collection FM IOCTL device ('/dev') definitions
150712 +*//***************************************************************************/
150713 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
150714 +
150715 +#define DEV_FM_MINOR_BASE 0
150716 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
150717 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
150718 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
150719 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
150720 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
150721 +
150722 +#define FM_IOC_NUM(n) (n)
150723 +#define FM_PCD_IOC_NUM(n) (n+20)
150724 +#define FM_PORT_IOC_NUM(n) (n+70)
150725 +/* @} */
150726 +
150727 +#define IOC_FM_MAX_NUM_OF_PORTS 64
150728 +
150729 +
150730 +/**************************************************************************//**
150731 + @Description Enum for defining port types
150732 + (must match enum e_FmPortType defined in fm_ext.h)
150733 +*//***************************************************************************/
150734 +typedef enum ioc_fm_port_type {
150735 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
150736 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
150737 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
150738 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
150739 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
150740 + e_IOC_FM_PORT_TYPE_DUMMY
150741 +} ioc_fm_port_type;
150742 +
150743 +
150744 +/**************************************************************************//**
150745 + @Group lnx_ioctl_FM_lib_grp FM library
150746 +
150747 + @Description FM API functions, definitions and enums
150748 + The FM module is the main driver module and is a mandatory module
150749 + for FM driver users. Before any further module initialization,
150750 + this module must be initialized.
150751 + The FM is a "single-tone" module. It is responsible of the common
150752 + HW modules: FPM, DMA, common QMI, common BMI initializations and
150753 + run-time control routines. This module must be initialized always
150754 + when working with any of the FM modules.
150755 + NOTE - We assumes that the FML will be initialize only by core No. 0!
150756 +
150757 + @{
150758 +*//***************************************************************************/
150759 +
150760 +/**************************************************************************//**
150761 + @Description FM Exceptions
150762 +*//***************************************************************************/
150763 +typedef enum ioc_fm_exceptions {
150764 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
150765 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
150766 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
150767 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
150768 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
150769 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
150770 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
150771 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
150772 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
150773 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
150774 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
150775 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
150776 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
150777 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
150778 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
150779 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
150780 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
150781 +} ioc_fm_exceptions;
150782 +
150783 +/**************************************************************************//**
150784 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
150785 +
150786 + @Description FM Runtime control unit API functions, definitions and enums.
150787 + The FM driver provides a set of control routines for each module.
150788 + These routines may only be called after the module was fully
150789 + initialized (both configuration and initialization routines were
150790 + called). They are typically used to get information from hardware
150791 + (status, counters/statistics, revision etc.), to modify a current
150792 + state or to force/enable a required action. Run-time control may
150793 + be called whenever necessary and as many times as needed.
150794 + @{
150795 +*//***************************************************************************/
150796 +
150797 +/**************************************************************************//**
150798 + @Collection General FM defines.
150799 + *//***************************************************************************/
150800 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
150801 + FM_MAX_NUM_OF_1G_RX_PORTS + \
150802 + FM_MAX_NUM_OF_10G_RX_PORTS + \
150803 + FM_MAX_NUM_OF_1G_TX_PORTS + \
150804 + FM_MAX_NUM_OF_10G_TX_PORTS)
150805 +/* @} */
150806 +
150807 +/**************************************************************************//**
150808 + @Description Structure for Port bandwidth requirement. Port is identified
150809 + by type and relative id.
150810 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
150811 +*//***************************************************************************/
150812 +typedef struct ioc_fm_port_bandwidth_t {
150813 + ioc_fm_port_type type; /**< FM port type */
150814 + uint8_t relative_port_id; /**< Type relative port id */
150815 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
150816 +} ioc_fm_port_bandwidth_t;
150817 +
150818 +/**************************************************************************//**
150819 + @Description A Structure containing an array of Port bandwidth requirements.
150820 + The user should state the ports requiring bandwidth in terms of
150821 + percentage - i.e. all port's bandwidths in the array must add
150822 + up to 100.
150823 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
150824 +*//***************************************************************************/
150825 +typedef struct ioc_fm_port_bandwidth_params {
150826 + uint8_t num_of_ports;
150827 + /**< num of ports listed in the array below */
150828 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
150829 + /**< for each port, it's bandwidth (all port's
150830 + bandwidths must add up to 100.*/
150831 +} ioc_fm_port_bandwidth_params;
150832 +
150833 +/**************************************************************************//**
150834 + @Description enum for defining FM counters
150835 +*//***************************************************************************/
150836 +typedef enum ioc_fm_counters {
150837 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
150838 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
150839 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
150840 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
150841 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
150842 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
150843 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
150844 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
150845 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
150846 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
150847 +} ioc_fm_counters;
150848 +
150849 +typedef struct ioc_fm_obj_t {
150850 + void *obj;
150851 +} ioc_fm_obj_t;
150852 +
150853 +/**************************************************************************//**
150854 + @Description A structure for returning revision information
150855 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
150856 +*//***************************************************************************/
150857 +typedef struct ioc_fm_revision_info_t {
150858 + uint8_t major; /**< Major revision */
150859 + uint8_t minor; /**< Minor revision */
150860 +} ioc_fm_revision_info_t;
150861 +
150862 +/**************************************************************************//**
150863 + @Description A structure for FM counters
150864 +*//***************************************************************************/
150865 +typedef struct ioc_fm_counters_params_t {
150866 + ioc_fm_counters cnt; /**< The requested counter */
150867 + uint32_t val; /**< The requested value to get/set from/into the counter */
150868 +} ioc_fm_counters_params_t;
150869 +
150870 +typedef union ioc_fm_api_version_t {
150871 + struct {
150872 + uint8_t major;
150873 + uint8_t minor;
150874 + uint8_t respin;
150875 + uint8_t reserved;
150876 + } version;
150877 + uint32_t ver;
150878 +} ioc_fm_api_version_t;
150879 +
150880 +#if (DPAA_VERSION >= 11)
150881 +/**************************************************************************//**
150882 + @Description A structure of information about each of the external
150883 + buffer pools used by a port or storage-profile.
150884 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
150885 +*//***************************************************************************/
150886 +typedef struct ioc_fm_ext_pool_params {
150887 + uint8_t id; /**< External buffer pool id */
150888 + uint16_t size; /**< External buffer pool buffer size */
150889 +} ioc_fm_ext_pool_params;
150890 +
150891 +/**************************************************************************//**
150892 + @Description A structure for informing the driver about the external
150893 + buffer pools allocated in the BM and used by a port or a
150894 + storage-profile.
150895 + (must be identical to t_FmExtPools defined in fm_ext.h)
150896 +*//***************************************************************************/
150897 +typedef struct ioc_fm_ext_pools {
150898 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
150899 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
150900 + /**< Parameters for each port */
150901 +} ioc_fm_ext_pools;
150902 +
150903 +typedef struct ioc_fm_vsp_params_t {
150904 + void *p_fm; /**< A handle to the FM object this VSP related to */
150905 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
150906 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
150907 + parameter associated with Rx / OP port */
150908 + uint16_t liodn_offset; /**< VSP's LIODN offset */
150909 + struct {
150910 + ioc_fm_port_type port_type; /**< Port type */
150911 + uint8_t port_id; /**< Port Id - relative to type */
150912 + } port_params;
150913 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
150914 + defined in relevant FM object */
150915 + void *id; /**< return value */
150916 +} ioc_fm_vsp_params_t;
150917 +#endif /* (DPAA_VERSION >= 11) */
150918 +
150919 +/**************************************************************************//**
150920 + @Description A structure for defining BM pool depletion criteria
150921 +*//***************************************************************************/
150922 +typedef struct ioc_fm_buf_pool_depletion_t {
150923 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
150924 + a number of pools (all together!) are depleted */
150925 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
150926 + pause frames transmission. */
150927 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
150928 + /**< For each pool, TRUE if it should be considered for
150929 + depletion (Note - this pool must be used by this port!). */
150930 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
150931 + a single-pool is depleted; */
150932 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
150933 + /**< For each pool, TRUE if it should be considered for
150934 + depletion (Note - this pool must be used by this port!) */
150935 +#if (DPAA_VERSION >= 11)
150936 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
150937 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
150938 + which is transmitted */
150939 +#endif /* (DPAA_VERSION >= 11) */
150940 +} ioc_fm_buf_pool_depletion_t;
150941 +
150942 +#if (DPAA_VERSION >= 11)
150943 +typedef struct ioc_fm_buf_pool_depletion_params_t {
150944 + void *p_fm_vsp;
150945 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
150946 +} ioc_fm_buf_pool_depletion_params_t;
150947 +#endif /* (DPAA_VERSION >= 11) */
150948 +
150949 +typedef struct ioc_fm_buffer_prefix_content_t {
150950 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
150951 + of the external buffer; Note that the private-area will
150952 + start from the base of the buffer address. */
150953 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
150954 + User may use FM_PORT_GetBufferPrsResult() in order to
150955 + get the parser-result from a buffer. */
150956 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
150957 + User may use FM_PORT_GetBufferTimeStamp() in order to
150958 + get the parser-result from a buffer. */
150959 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
150960 + User may use FM_PORT_GetBufferHashResult() in order to
150961 + get the parser-result from a buffer. */
150962 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
150963 + AD, hash-result, key, etc. */
150964 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
150965 + other value for selecting a data alignment (must be a power of 2);
150966 + if write optimization is used, must be >= 16. */
150967 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
150968 + Note that this field impacts the size of the buffer-prefix
150969 + (i.e. it pushes the data offset);
150970 + This field is irrelevant if DPAA_VERSION==10 */
150971 +} ioc_fm_buffer_prefix_content_t;
150972 +
150973 +typedef struct ioc_fm_buffer_prefix_content_params_t {
150974 + void *p_fm_vsp;
150975 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
150976 +} ioc_fm_buffer_prefix_content_params_t;
150977 +
150978 +#if (DPAA_VERSION >= 11)
150979 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
150980 + void *p_fm_vsp;
150981 + bool no_sg;
150982 +} ioc_fm_vsp_config_no_sg_params_t;
150983 +
150984 +typedef struct ioc_fm_vsp_prs_result_params_t {
150985 + void *p_fm_vsp;
150986 + void *p_data;
150987 +} ioc_fm_vsp_prs_result_params_t;
150988 +#endif
150989 +
150990 +typedef struct fm_ctrl_mon_t {
150991 + uint8_t percent_cnt[2];
150992 +} fm_ctrl_mon_t;
150993 +
150994 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
150995 + uint8_t fm_ctrl_index;
150996 + fm_ctrl_mon_t *p_mon;
150997 +} ioc_fm_ctrl_mon_counters_params_t;
150998 +
150999 +/**************************************************************************//**
151000 + @Function FM_IOC_SET_PORTS_BANDWIDTH
151001 +
151002 + @Description Sets relative weights between ports when accessing common resources.
151003 +
151004 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
151005 + their sum must equal 100.
151006 +
151007 + @Return E_OK on success; Error code otherwise.
151008 +
151009 + @Cautions Allowed only following FM_Init().
151010 +*//***************************************************************************/
151011 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
151012 +
151013 +/**************************************************************************//**
151014 + @Function FM_IOC_GET_REVISION
151015 +
151016 + @Description Returns the FM revision
151017 +
151018 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
151019 +
151020 + @Return None.
151021 +
151022 + @Cautions Allowed only following FM_Init().
151023 +*//***************************************************************************/
151024 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
151025 +
151026 +/**************************************************************************//**
151027 + @Function FM_IOC_GET_COUNTER
151028 +
151029 + @Description Reads one of the FM counters.
151030 +
151031 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
151032 +
151033 + @Return Counter's current value.
151034 +
151035 + @Cautions Allowed only following FM_Init().
151036 + Note that it is user's responsibilty to call this routine only
151037 + for enabled counters, and there will be no indication if a
151038 + disabled counter is accessed.
151039 +*//***************************************************************************/
151040 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
151041 +
151042 +/**************************************************************************//**
151043 + @Function FM_IOC_SET_COUNTER
151044 +
151045 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
151046 +
151047 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
151048 +
151049 + @Return E_OK on success; Error code otherwise.
151050 +
151051 + @Cautions Allowed only following FM_Init().
151052 +*//***************************************************************************/
151053 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
151054 +
151055 +/**************************************************************************//**
151056 + @Function FM_IOC_FORCE_INTR
151057 +
151058 + @Description Causes an interrupt event on the requested source.
151059 +
151060 + @Param[in] ioc_fm_exceptions An exception to be forced.
151061 +
151062 + @Return E_OK on success; Error code if the exception is not enabled,
151063 + or is not able to create interrupt.
151064 +
151065 + @Cautions Allowed only following FM_Init().
151066 +*//***************************************************************************/
151067 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
151068 +
151069 +/**************************************************************************//**
151070 + @Function FM_IOC_GET_API_VERSION
151071 +
151072 + @Description Reads the FMD IOCTL API version.
151073 +
151074 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
151075 +
151076 + @Return Version's value.
151077 +*//***************************************************************************/
151078 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
151079 +
151080 +#if (DPAA_VERSION >= 11)
151081 +/**************************************************************************//**
151082 + @Function FM_VSP_Config
151083 +
151084 + @Description Creates descriptor for the FM VSP module.
151085 +
151086 + The routine returns a handle (descriptor) to the FM VSP object.
151087 + This descriptor must be passed as first parameter to all other
151088 + FM VSP function calls.
151089 +
151090 + No actual initialization or configuration of FM hardware is
151091 + done by this routine.
151092 +
151093 +@Param[in] p_FmVspParams Pointer to data structure of parameters
151094 +
151095 + @Retval Handle to FM VSP object, or NULL for Failure.
151096 +*//***************************************************************************/
151097 +#if defined(CONFIG_COMPAT)
151098 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
151099 +#endif
151100 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
151101 +
151102 +/**************************************************************************//**
151103 + @Function FM_VSP_Init
151104 +
151105 + @Description Initializes the FM VSP module
151106 +
151107 + @Param[in] h_FmVsp - FM VSP module descriptor
151108 +
151109 + @Return E_OK on success; Error code otherwise.
151110 +*//***************************************************************************/
151111 +#if defined(CONFIG_COMPAT)
151112 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
151113 +#endif
151114 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
151115 +
151116 +/**************************************************************************//**
151117 + @Function FM_VSP_Free
151118 +
151119 + @Description Frees all resources that were assigned to FM VSP module.
151120 +
151121 + Calling this routine invalidates the descriptor.
151122 +
151123 + @Param[in] h_FmVsp - FM VSP module descriptor
151124 +
151125 + @Return E_OK on success; Error code otherwise.
151126 +*//***************************************************************************/
151127 +#if defined(CONFIG_COMPAT)
151128 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
151129 +#endif
151130 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
151131 +
151132 +/**************************************************************************//**
151133 + @Function FM_VSP_ConfigPoolDepletion
151134 +
151135 + @Description Calling this routine enables pause frame generation depending on the
151136 + depletion status of BM pools. It also defines the conditions to activate
151137 + this functionality. By default, this functionality is disabled.
151138 +
151139 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
151140 +
151141 + @Return E_OK on success; Error code otherwise.
151142 +
151143 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
151144 +*//***************************************************************************/
151145 +#if defined(CONFIG_COMPAT)
151146 +#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)
151147 +#endif
151148 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
151149 +
151150 +/**************************************************************************//**
151151 + @Function FM_VSP_ConfigBufferPrefixContent
151152 +
151153 + @Description Defines the structure, size and content of the application buffer.
151154 +
151155 + The prefix will
151156 + In VSPs defined for Tx ports, if 'passPrsResult', the application
151157 + should set a value to their offsets in the prefix of
151158 + the FM will save the first 'privDataSize', than,
151159 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
151160 + and timeStamp, and the packet itself (in this order), to the
151161 + application buffer, and to offset.
151162 +
151163 + Calling this routine changes the buffer margins definitions
151164 + in the internal driver data base from its default
151165 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
151166 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
151167 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
151168 +
151169 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
151170 +
151171 + @Return E_OK on success; Error code otherwise.
151172 +
151173 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
151174 +*//***************************************************************************/
151175 +#if defined(CONFIG_COMPAT)
151176 +#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)
151177 +#endif
151178 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
151179 +
151180 +/**************************************************************************//**
151181 + @Function FM_VSP_ConfigNoScatherGather
151182 +
151183 + @Description Calling this routine changes the possibility to receive S/G frame
151184 + in the internal driver data base
151185 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
151186 +
151187 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
151188 +
151189 + @Return E_OK on success; Error code otherwise.
151190 +
151191 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
151192 +*//***************************************************************************/
151193 +#if defined(CONFIG_COMPAT)
151194 +#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)
151195 +#endif
151196 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
151197 +
151198 +/**************************************************************************//**
151199 + @Function FM_VSP_GetBufferPrsResult
151200 +
151201 + @Description Returns the pointer to the parse result in the data buffer.
151202 + In Rx ports this is relevant after reception, if parse
151203 + result is configured to be part of the data passed to the
151204 + application. For non Rx ports it may be used to get the pointer
151205 + of the area in the buffer where parse result should be
151206 + initialized - if so configured.
151207 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
151208 + configuration.
151209 +
151210 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
151211 +
151212 + @Return Parse result pointer on success, NULL if parse result was not
151213 + configured for this port.
151214 +
151215 + @Cautions Allowed only following FM_VSP_Init().
151216 +*//***************************************************************************/
151217 +#if defined(CONFIG_COMPAT)
151218 +#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)
151219 +#endif
151220 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
151221 +#endif /* (DPAA_VERSION >= 11) */
151222 +
151223 +/**************************************************************************//**
151224 + @Function FM_CtrlMonStart
151225 +
151226 + @Description Start monitoring utilization of all available FM controllers.
151227 +
151228 + In order to obtain FM controllers utilization the following sequence
151229 + should be used:
151230 + -# FM_CtrlMonStart()
151231 + -# FM_CtrlMonStop()
151232 + -# FM_CtrlMonGetCounters() - issued for each FM controller
151233 +
151234 + @Return E_OK on success; Error code otherwise.
151235 +
151236 + @Cautions Allowed only following FM_Init().
151237 +*//***************************************************************************/
151238 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
151239 +
151240 +
151241 +/**************************************************************************//**
151242 + @Function FM_CtrlMonStop
151243 +
151244 + @Description Stop monitoring utilization of all available FM controllers.
151245 +
151246 + In order to obtain FM controllers utilization the following sequence
151247 + should be used:
151248 + -# FM_CtrlMonStart()
151249 + -# FM_CtrlMonStop()
151250 + -# FM_CtrlMonGetCounters() - issued for each FM controller
151251 +
151252 + @Return E_OK on success; Error code otherwise.
151253 +
151254 + @Cautions Allowed only following FM_Init().
151255 +*//***************************************************************************/
151256 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
151257 +
151258 +/**************************************************************************//**
151259 + @Function FM_CtrlMonGetCounters
151260 +
151261 + @Description Obtain FM controller utilization parameters.
151262 +
151263 + In order to obtain FM controllers utilization the following sequence
151264 + should be used:
151265 + -# FM_CtrlMonStart()
151266 + -# FM_CtrlMonStop()
151267 + -# FM_CtrlMonGetCounters() - issued for each FM controller
151268 +
151269 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
151270 +
151271 + @Return E_OK on success; Error code otherwise.
151272 +
151273 + @Cautions Allowed only following FM_Init().
151274 +*//***************************************************************************/
151275 +#if defined(CONFIG_COMPAT)
151276 +#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)
151277 +#endif
151278 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
151279 +
151280 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
151281 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
151282 +/** @} */ /* end of lnx_ioctl_FM_grp */
151283 +
151284 +#define FMD_API_VERSION_MAJOR 21
151285 +#define FMD_API_VERSION_MINOR 1
151286 +#define FMD_API_VERSION_RESPIN 0
151287 +
151288 +#endif /* __FM_IOCTLS_H */
151289 --- /dev/null
151290 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
151291 @@ -0,0 +1,3084 @@
151292 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
151293 + * All rights reserved.
151294 + *
151295 + * Redistribution and use in source and binary forms, with or without
151296 + * modification, are permitted provided that the following conditions are met:
151297 + * * Redistributions of source code must retain the above copyright
151298 + * notice, this list of conditions and the following disclaimer.
151299 + * * Redistributions in binary form must reproduce the above copyright
151300 + * notice, this list of conditions and the following disclaimer in the
151301 + * documentation and/or other materials provided with the distribution.
151302 + * * Neither the name of Freescale Semiconductor nor the
151303 + * names of its contributors may be used to endorse or promote products
151304 + * derived from this software without specific prior written permission.
151305 + *
151306 + *
151307 + * ALTERNATIVELY, this software may be distributed under the terms of the
151308 + * GNU General Public License ("GPL") as published by the Free Software
151309 + * Foundation, either version 2 of that License or (at your option) any
151310 + * later version.
151311 + *
151312 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
151313 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
151314 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
151315 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
151316 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
151317 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
151318 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
151319 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
151320 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
151321 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
151322 + */
151323 +
151324 +
151325 +/******************************************************************************
151326 + @File fm_pcd_ioctls.h
151327 +
151328 + @Description FM PCD ...
151329 +*//***************************************************************************/
151330 +#ifndef __FM_PCD_IOCTLS_H
151331 +#define __FM_PCD_IOCTLS_H
151332 +
151333 +#include "net_ioctls.h"
151334 +#include "fm_ioctls.h"
151335 +
151336 +
151337 +/**************************************************************************//**
151338 +
151339 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
151340 +
151341 + @Description Frame Manager Linux ioctls definitions and enums
151342 +
151343 + @{
151344 +*//***************************************************************************/
151345 +
151346 +/**************************************************************************//**
151347 + @Group lnx_ioctl_FM_PCD_grp FM PCD
151348 +
151349 + @Description Frame Manager PCD API functions, definitions and enums
151350 +
151351 + The FM PCD module is responsible for the initialization of all
151352 + global classifying FM modules. This includes the parser general and
151353 + common registers, the key generator global and common registers,
151354 + and the policer global and common registers.
151355 + In addition, the FM PCD SW module will initialize all required
151356 + key generator schemes, coarse classification flows, and policer
151357 + profiles. When an FM module is configured to work with one of these
151358 + entities, it will register to it using the FM PORT API. The PCD
151359 + module will manage the PCD resources - i.e. resource management of
151360 + KeyGen schemes, etc.
151361 +
151362 + @{
151363 +*//***************************************************************************/
151364 +
151365 +/**************************************************************************//**
151366 + @Collection General PCD defines
151367 +*//***************************************************************************/
151368 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
151369 +
151370 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
151371 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
151372 + /**< Number of distinction units is limited by
151373 + register size (32 bits) minus reserved bits
151374 + for private headers. */
151375 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
151376 + in a distinction unit */
151377 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
151378 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
151379 + For HW implementation reasons, in most
151380 + cases less than this will be allowed; The
151381 + driver will return an initialization error
151382 + if resource is unavailable. */
151383 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
151384 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
151385 +
151386 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
151387 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
151388 +
151389 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
151390 + insert manipulation */
151391 +
151392 +#if DPAA_VERSION >= 11
151393 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
151394 +#endif /* DPAA_VERSION >= 11 */
151395 +/* @} */
151396 +
151397 +#ifdef FM_CAPWAP_SUPPORT
151398 +#error "FM_CAPWAP_SUPPORT not implemented!"
151399 +#endif
151400 +
151401 +
151402 +/**************************************************************************//**
151403 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
151404 +
151405 + @Description Frame Manager PCD Initialization Unit API
151406 +
151407 + @{
151408 +*//***************************************************************************/
151409 +
151410 +/**************************************************************************//**
151411 + @Description PCD counters
151412 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
151413 +*//***************************************************************************/
151414 +typedef enum ioc_fm_pcd_counters {
151415 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
151416 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
151417 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
151418 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
151419 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
151420 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
151421 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
151422 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
151423 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
151424 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
151425 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
151426 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
151427 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
151428 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
151429 + 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. */
151430 + 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. */
151431 + 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. */
151432 + 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. */
151433 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
151434 + 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. */
151435 + 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). */
151436 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
151437 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
151438 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
151439 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
151440 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
151441 +} ioc_fm_pcd_counters;
151442 +
151443 +/**************************************************************************//**
151444 + @Description PCD interrupts
151445 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
151446 +*//***************************************************************************/
151447 +typedef enum ioc_fm_pcd_exceptions {
151448 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
151449 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
151450 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
151451 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
151452 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
151453 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
151454 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
151455 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
151456 +} ioc_fm_pcd_exceptions;
151457 +
151458 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
151459 +
151460 +
151461 +/**************************************************************************//**
151462 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
151463 +
151464 + @Description Frame Manager PCD Runtime Unit
151465 +
151466 + The runtime control allows creation of PCD infrastructure modules
151467 + such as Network Environment Characteristics, Classification Plan
151468 + Groups and Coarse Classification Trees.
151469 + It also allows on-the-fly initialization, modification and removal
151470 + of PCD modules such as KeyGen schemes, coarse classification nodes
151471 + and Policer profiles.
151472 +
151473 + In order to explain the programming model of the PCD driver interface
151474 + a few terms should be explained, and will be used below.
151475 + - Distinction Header - One of the 16 protocols supported by the FM parser,
151476 + or one of the SHIM headers (1 or 2). May be a header with a special
151477 + option (see below).
151478 + - Interchangeable Headers Group - This is a group of Headers recognized
151479 + by either one of them. For example, if in a specific context the user
151480 + chooses to treat IPv4 and IPV6 in the same way, they may create an
151481 + interchangeable Headers Unit consisting of these 2 headers.
151482 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
151483 + Group.
151484 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
151485 + IPv6, includes multicast, broadcast and other protocol specific options.
151486 + In terms of hardware it relates to the options available in the classification
151487 + plan.
151488 + - Network Environment Characteristics - a set of Distinction Units that define
151489 + the total recognizable header selection for a certain environment. This is
151490 + NOT the list of all headers that will ever appear in a flow, but rather
151491 + everything that needs distinction in a flow, where distinction is made by KeyGen
151492 + schemes and coarse classification action descriptors.
151493 +
151494 + The PCD runtime modules initialization is done in stages. The first stage after
151495 + initializing the PCD module itself is to establish a Network Flows Environment
151496 + Definition. The application may choose to establish one or more such environments.
151497 + Later, when needed, the application will have to state, for some of its modules,
151498 + to which single environment it belongs.
151499 +
151500 + @{
151501 +*//***************************************************************************/
151502 +
151503 +
151504 +/**************************************************************************//**
151505 + @Description structure for FM counters
151506 +*//***************************************************************************/
151507 +typedef struct ioc_fm_pcd_counters_params_t {
151508 + ioc_fm_pcd_counters cnt; /**< The requested counter */
151509 + uint32_t val; /**< The requested value to get/set from/into the counter */
151510 +} ioc_fm_pcd_counters_params_t;
151511 +
151512 +/**************************************************************************//**
151513 + @Description structure for FM exception definitios
151514 +*//***************************************************************************/
151515 +typedef struct ioc_fm_pcd_exception_params_t {
151516 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
151517 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
151518 +} ioc_fm_pcd_exception_params_t;
151519 +
151520 +/**************************************************************************//**
151521 + @Description A structure for SW parser labels
151522 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
151523 + *//***************************************************************************/
151524 +typedef struct ioc_fm_pcd_prs_label_params_t {
151525 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
151526 + resolution), relative to Parser RAM. */
151527 + ioc_net_header_type hdr; /**< The existence of this header will invoke
151528 + the SW parser code. */
151529 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
151530 + attachments for the same header, use this
151531 + index to distinguish between them. */
151532 +} ioc_fm_pcd_prs_label_params_t;
151533 +
151534 +/**************************************************************************//**
151535 + @Description A structure for SW parser
151536 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
151537 + *//***************************************************************************/
151538 +typedef struct ioc_fm_pcd_prs_sw_params_t {
151539 + bool override; /**< FALSE to invoke a check that nothing else
151540 + was loaded to this address, including
151541 + internal patches.
151542 + TRUE to override any existing code.*/
151543 + uint32_t size; /**< SW parser code size */
151544 + uint16_t base; /**< SW parser base (in instruction counts!
151545 + must be larger than 0x20)*/
151546 + uint8_t *p_code; /**< SW parser code */
151547 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
151548 + /**< SW parser data (parameters) */
151549 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
151550 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
151551 + /**< SW parser labels table,
151552 + containing num_of_labels entries */
151553 +} ioc_fm_pcd_prs_sw_params_t;
151554 +
151555 +/**************************************************************************//**
151556 + @Description A structure to set the a KeyGen default value
151557 + *//***************************************************************************/
151558 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
151559 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
151560 + uint32_t value; /**< The requested default value */
151561 +} ioc_fm_pcd_kg_dflt_value_params_t;
151562 +
151563 +
151564 +/**************************************************************************//**
151565 + @Function FM_PCD_Enable
151566 +
151567 + @Description This routine should be called after PCD is initialized for enabling all
151568 + PCD engines according to their existing configuration.
151569 +
151570 + @Return 0 on success; Error code otherwise.
151571 +
151572 + @Cautions Allowed only when PCD is disabled.
151573 +*//***************************************************************************/
151574 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
151575 +
151576 +/**************************************************************************//**
151577 + @Function FM_PCD_Disable
151578 +
151579 + @Description This routine may be called when PCD is enabled in order to
151580 + disable all PCD engines. It may be called
151581 + only when none of the ports in the system are using the PCD.
151582 +
151583 + @Return 0 on success; Error code otherwise.
151584 +
151585 + @Cautions Allowed only when PCD is enabled.
151586 +*//***************************************************************************/
151587 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
151588 +
151589 + /**************************************************************************//**
151590 + @Function FM_PCD_PrsLoadSw
151591 +
151592 + @Description This routine may be called only when all ports in the
151593 + system are actively using the classification plan scheme.
151594 + In such cases it is recommended in order to save resources.
151595 + The driver automatically saves 8 classification plans for
151596 + ports that do NOT use the classification plan mechanism, to
151597 + avoid this (in order to save those entries) this routine may
151598 + be called.
151599 +
151600 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
151601 +
151602 + @Return 0 on success; Error code otherwise.
151603 +
151604 + @Cautions Allowed only when PCD is disabled.
151605 +*//***************************************************************************/
151606 +#if defined(CONFIG_COMPAT)
151607 +#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)
151608 +#endif
151609 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
151610 +
151611 +/**************************************************************************//**
151612 + @Function FM_PCD_KgSetDfltValue
151613 +
151614 + @Description Calling this routine sets a global default value to be used
151615 + by the KeyGen when parser does not recognize a required
151616 + field/header.
151617 + By default default values are 0.
151618 +
151619 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
151620 +
151621 + @Return 0 on success; Error code otherwise.
151622 +
151623 + @Cautions Allowed only when PCD is disabled.
151624 +*//***************************************************************************/
151625 +#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)
151626 +
151627 +/**************************************************************************//**
151628 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
151629 +
151630 + @Description Calling this routine allows the keygen to access data past
151631 + the parser finishing point.
151632 +
151633 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
151634 +
151635 + @Return 0 on success; Error code otherwise.
151636 +
151637 + @Cautions Allowed only when PCD is disabled.
151638 +*//***************************************************************************/
151639 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
151640 +
151641 +/**************************************************************************//**
151642 + @Function FM_PCD_SetException
151643 +
151644 + @Description Calling this routine enables/disables PCD interrupts.
151645 +
151646 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
151647 +
151648 + @Return 0 on success; Error code otherwise.
151649 +*//***************************************************************************/
151650 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
151651 +
151652 +/**************************************************************************//**
151653 + @Function FM_PCD_GetCounter
151654 +
151655 + @Description Reads one of the FM PCD counters.
151656 +
151657 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
151658 +
151659 + @Return 0 on success; Error code otherwise.
151660 +
151661 + @Cautions Note that it is user's responsibilty to call this routine only
151662 + for enabled counters, and there will be no indication if a
151663 + disabled counter is accessed.
151664 +*//***************************************************************************/
151665 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
151666 +
151667 +/**************************************************************************//**
151668 +
151669 + @Function FM_PCD_KgSchemeGetCounter
151670 +
151671 + @Description Reads scheme packet counter.
151672 +
151673 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
151674 +
151675 + @Return Counter's current value.
151676 +
151677 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
151678 +*//***************************************************************************/
151679 +#if defined(CONFIG_COMPAT)
151680 +#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)
151681 +#endif
151682 +#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)
151683 +
151684 +#if 0
151685 +TODO: unused IOCTL
151686 +/**************************************************************************//**
151687 + @Function FM_PCD_ModifyCounter
151688 +
151689 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
151690 +
151691 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
151692 +
151693 + @Return 0 on success; Error code otherwise.
151694 +*//***************************************************************************/
151695 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
151696 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
151697 +#endif
151698 +
151699 +/**************************************************************************//**
151700 + @Function FM_PCD_ForceIntr
151701 +
151702 + @Description Causes an interrupt event on the requested source.
151703 +
151704 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
151705 +
151706 + @Return 0 on success; error code if the exception is not enabled,
151707 + or is not able to create interrupt.
151708 +*//***************************************************************************/
151709 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
151710 +
151711 +/**************************************************************************//**
151712 + @Collection Definitions of coarse classification parameters as required by KeyGen
151713 + (when coarse classification is the next engine after this scheme).
151714 +*//***************************************************************************/
151715 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
151716 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
151717 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
151718 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
151719 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
151720 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
151721 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
151722 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
151723 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
151724 +/* @} */
151725 +
151726 +/**************************************************************************//**
151727 + @Collection A set of definitions to allow protocol
151728 + special option description.
151729 +*//***************************************************************************/
151730 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
151731 +
151732 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
151733 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
151734 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
151735 +
151736 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
151737 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
151738 +
151739 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
151740 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
151741 +
151742 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
151743 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
151744 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
151745 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
151746 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
151747 +
151748 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
151749 + IPV4 Reassembly manipulation requires network
151750 + environment with IPV4 header and IPV4_FRAG_1 option */
151751 +
151752 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
151753 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
151754 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
151755 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
151756 +
151757 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
151758 + IPV6 Reassembly manipulation requires network
151759 + environment with IPV6 header and IPV6_FRAG_1 option */
151760 +#if (DPAA_VERSION >= 11)
151761 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
151762 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
151763 + CAPWAP Reassembly manipulation requires network
151764 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
151765 + in case where fragment found, the fragment-extension offset
151766 + may be found at 'shim2' (in parser-result). */
151767 +#endif /* (DPAA_VERSION >= 11) */
151768 +
151769 +/* @} */
151770 +
151771 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
151772 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
151773 +/**************************************************************************//**
151774 + @Collection A set of definitions to support Header Manipulation selection.
151775 +*//***************************************************************************/
151776 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
151777 +
151778 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
151779 +
151780 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
151781 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
151782 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
151783 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
151784 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
151785 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
151786 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
151787 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
151788 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
151789 +
151790 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
151791 +
151792 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
151793 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
151794 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
151795 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
151796 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
151797 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
151798 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
151799 +
151800 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
151801 +
151802 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
151803 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
151804 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
151805 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
151806 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
151807 +
151808 +/* @} */
151809 +
151810 +/**************************************************************************//**
151811 + @Description A type used for returning the order of the key extraction.
151812 + each value in this array represents the index of the extraction
151813 + command as defined by the user in the initialization extraction array.
151814 + The valid size of this array is the user define number of extractions
151815 + required (also marked by the second '0' in this array).
151816 +*//***************************************************************************/
151817 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
151818 +
151819 +/**************************************************************************//**
151820 + @Description All PCD engines
151821 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
151822 +*//***************************************************************************/
151823 +typedef enum ioc_fm_pcd_engine {
151824 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
151825 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
151826 + e_IOC_FM_PCD_KG, /**< KeyGen */
151827 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
151828 + e_IOC_FM_PCD_PLCR, /**< Policer */
151829 + e_IOC_FM_PCD_PRS, /**< Parser */
151830 +#if DPAA_VERSION >= 11
151831 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
151832 +#endif /* DPAA_VERSION >= 11 */
151833 + e_IOC_FM_PCD_HASH /**< Hash Table */
151834 +} ioc_fm_pcd_engine;
151835 +
151836 +/**************************************************************************//**
151837 + @Description An enum for selecting extraction by header types
151838 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
151839 +*//***************************************************************************/
151840 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
151841 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
151842 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
151843 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
151844 +} ioc_fm_pcd_extract_by_hdr_type;
151845 +
151846 +/**************************************************************************//**
151847 + @Description An enum for selecting extraction source (when it is not the header)
151848 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
151849 +*//***************************************************************************/
151850 +typedef enum ioc_fm_pcd_extract_from {
151851 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
151852 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
151853 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
151854 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
151855 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
151856 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
151857 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
151858 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
151859 +} ioc_fm_pcd_extract_from;
151860 +
151861 +/**************************************************************************//**
151862 + @Description An enum for selecting extraction type
151863 +*//***************************************************************************/
151864 +typedef enum ioc_fm_pcd_extract_type {
151865 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
151866 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
151867 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
151868 +} ioc_fm_pcd_extract_type;
151869 +
151870 +/**************************************************************************//**
151871 + @Description An enum for selecting a default
151872 +*//***************************************************************************/
151873 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
151874 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
151875 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
151876 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
151877 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
151878 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
151879 +} ioc_fm_pcd_kg_extract_dflt_select;
151880 +
151881 +/**************************************************************************//**
151882 + @Description Enumeration type defining all default groups - each group shares
151883 + a default value, one of four user-initialized values.
151884 +*//***************************************************************************/
151885 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
151886 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
151887 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
151888 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
151889 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
151890 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
151891 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
151892 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
151893 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
151894 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
151895 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
151896 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
151897 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
151898 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
151899 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
151900 + any data extraction that is not the full
151901 + field described above */
151902 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
151903 + any data extraction without validation */
151904 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
151905 + extraction from parser result or
151906 + direct use of default value */
151907 +} ioc_fm_pcd_kg_known_fields_dflt_types;
151908 +
151909 +/**************************************************************************//**
151910 + @Description Enumeration type for defining header index for scenarios with
151911 + multiple (tunneled) headers
151912 +*//***************************************************************************/
151913 +typedef enum ioc_fm_pcd_hdr_index {
151914 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
151915 + to specify regular IP (not tunneled). */
151916 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
151917 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
151918 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
151919 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
151920 +} ioc_fm_pcd_hdr_index;
151921 +
151922 +/**************************************************************************//**
151923 + @Description Enumeration type for selecting the policer profile functional type
151924 +*//***************************************************************************/
151925 +typedef enum ioc_fm_pcd_profile_type_selection {
151926 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
151927 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
151928 +} ioc_fm_pcd_profile_type_selection;
151929 +
151930 +/**************************************************************************//**
151931 + @Description Enumeration type for selecting the policer profile algorithm
151932 +*//***************************************************************************/
151933 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
151934 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
151935 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
151936 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
151937 +} ioc_fm_pcd_plcr_algorithm_selection;
151938 +
151939 +/**************************************************************************//**
151940 + @Description Enumeration type for selecting a policer profile color mode
151941 +*//***************************************************************************/
151942 +typedef enum ioc_fm_pcd_plcr_color_mode {
151943 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
151944 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
151945 +} ioc_fm_pcd_plcr_color_mode;
151946 +
151947 +/**************************************************************************//**
151948 + @Description Enumeration type for selecting a policer profile color
151949 +*//***************************************************************************/
151950 +typedef enum ioc_fm_pcd_plcr_color {
151951 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
151952 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
151953 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
151954 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
151955 +} ioc_fm_pcd_plcr_color;
151956 +
151957 +/**************************************************************************//**
151958 + @Description Enumeration type for selecting the policer profile packet frame length selector
151959 +*//***************************************************************************/
151960 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
151961 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
151962 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
151963 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
151964 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
151965 +} ioc_fm_pcd_plcr_frame_length_select;
151966 +
151967 +/**************************************************************************//**
151968 + @Description Enumeration type for selecting roll-back frame
151969 +*//***************************************************************************/
151970 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
151971 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
151972 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
151973 +} ioc_fm_pcd_plcr_roll_back_frame_select;
151974 +
151975 +/**************************************************************************//**
151976 + @Description Enumeration type for selecting the policer profile packet or byte mode
151977 +*//***************************************************************************/
151978 +typedef enum ioc_fm_pcd_plcr_rate_mode {
151979 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
151980 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
151981 +} ioc_fm_pcd_plcr_rate_mode;
151982 +
151983 +/**************************************************************************//**
151984 + @Description Enumeration type for defining action of frame
151985 +*//***************************************************************************/
151986 +typedef enum ioc_fm_pcd_done_action {
151987 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
151988 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
151989 +} ioc_fm_pcd_done_action;
151990 +
151991 +/**************************************************************************//**
151992 + @Description Enumeration type for selecting the policer counter
151993 +*//***************************************************************************/
151994 +typedef enum ioc_fm_pcd_plcr_profile_counters {
151995 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
151996 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
151997 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
151998 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
151999 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
152000 +} ioc_fm_pcd_plcr_profile_counters;
152001 +
152002 +/**************************************************************************//**
152003 + @Description Enumeration type for selecting the PCD action after extraction
152004 +*//***************************************************************************/
152005 +typedef enum ioc_fm_pcd_action {
152006 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
152007 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
152008 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
152009 +} ioc_fm_pcd_action;
152010 +
152011 +/**************************************************************************//**
152012 + @Description Enumeration type for selecting type of insert manipulation
152013 +*//***************************************************************************/
152014 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
152015 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
152016 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
152017 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152018 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
152019 +#endif /* FM_CAPWAP_SUPPORT */
152020 +} ioc_fm_pcd_manip_hdr_insrt_type;
152021 +
152022 +/**************************************************************************//**
152023 + @Description Enumeration type for selecting type of remove manipulation
152024 +*//***************************************************************************/
152025 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
152026 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
152027 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
152028 +} ioc_fm_pcd_manip_hdr_rmv_type;
152029 +
152030 +/**************************************************************************//**
152031 + @Description An enum for selecting specific L2 fields removal
152032 +*//***************************************************************************/
152033 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
152034 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
152035 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
152036 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
152037 + the header which follows the MPLS header */
152038 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
152039 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
152040 +
152041 +/**************************************************************************//**
152042 + @Description Enumeration type for selecting specific fields updates
152043 +*//***************************************************************************/
152044 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
152045 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
152046 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
152047 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
152048 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
152049 +} ioc_fm_pcd_manip_hdr_field_update_type;
152050 +
152051 +/**************************************************************************//**
152052 + @Description Enumeration type for selecting VLAN updates
152053 +*//***************************************************************************/
152054 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
152055 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
152056 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
152057 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
152058 +
152059 +/**************************************************************************//**
152060 + @Description Enumeration type for selecting specific L2 fields removal
152061 +*//***************************************************************************/
152062 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
152063 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
152064 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
152065 +
152066 +#if (DPAA_VERSION >= 11)
152067 +/**************************************************************************//**
152068 + @Description Enumeration type for selecting QoS mapping mode
152069 +
152070 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
152071 + User should instruct the port to read the parser-result
152072 +*//***************************************************************************/
152073 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
152074 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
152075 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
152076 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
152077 +
152078 +/**************************************************************************//**
152079 + @Description Enumeration type for selecting QoS source
152080 +
152081 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
152082 + User should left room for the parser-result on input/output buffer
152083 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
152084 +*//***************************************************************************/
152085 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
152086 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
152087 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
152088 +} ioc_fm_pcd_manip_hdr_qos_src;
152089 +#endif /* (DPAA_VERSION >= 11) */
152090 +
152091 +/**************************************************************************//**
152092 + @Description Enumeration type for selecting type of header insertion
152093 +*//***************************************************************************/
152094 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
152095 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
152096 +#if (DPAA_VERSION >= 11)
152097 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
152098 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
152099 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
152100 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
152101 +#endif /* (DPAA_VERSION >= 11) */
152102 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
152103 +
152104 +/**************************************************************************//**
152105 + @Description Enumeration type for selecting specific custom command
152106 +*//***************************************************************************/
152107 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
152108 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
152109 +} ioc_fm_pcd_manip_hdr_custom_type;
152110 +
152111 +/**************************************************************************//**
152112 + @Description Enumeration type for selecting specific custom command
152113 +*//***************************************************************************/
152114 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
152115 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
152116 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
152117 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
152118 +
152119 +/**************************************************************************//**
152120 + @Description Enumeration type for selecting type of header removal
152121 +*//***************************************************************************/
152122 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
152123 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
152124 +#if (DPAA_VERSION >= 11)
152125 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
152126 +#endif /* (DPAA_VERSION >= 11) */
152127 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
152128 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
152129 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
152130 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
152131 +
152132 +/**************************************************************************//**
152133 + @Description Enumeration type for selecting type of timeout mode
152134 +*//***************************************************************************/
152135 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
152136 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
152137 + from the first fragment to the last */
152138 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
152139 +} ioc_fm_pcd_manip_reassem_time_out_mode;
152140 +
152141 +/**************************************************************************//**
152142 + @Description Enumeration type for selecting type of WaysNumber mode
152143 +*//***************************************************************************/
152144 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
152145 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
152146 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
152147 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
152148 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
152149 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
152150 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
152151 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
152152 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
152153 +} ioc_fm_pcd_manip_reassem_ways_number;
152154 +
152155 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152156 +/**************************************************************************//**
152157 + @Description Enumeration type for selecting type of statistics mode
152158 +*//***************************************************************************/
152159 +typedef enum ioc_fm_pcd_stats {
152160 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
152161 +} ioc_fm_pcd_stats;
152162 +#endif
152163 +
152164 +/**************************************************************************//**
152165 + @Description Enumeration type for selecting manipulation type
152166 +*//***************************************************************************/
152167 +typedef enum ioc_fm_pcd_manip_type {
152168 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
152169 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
152170 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
152171 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
152172 +} ioc_fm_pcd_manip_type;
152173 +
152174 +/**************************************************************************//**
152175 + @Description Enumeration type for selecting type of statistics mode
152176 +*//***************************************************************************/
152177 +typedef enum ioc_fm_pcd_cc_stats_mode {
152178 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
152179 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
152180 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
152181 +#if (DPAA_VERSION >= 11)
152182 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
152183 +#endif /* (DPAA_VERSION >= 11) */
152184 +} ioc_fm_pcd_cc_stats_mode;
152185 +
152186 +/**************************************************************************//**
152187 + @Description Enumeration type for determining the action in case an IP packet
152188 + is larger than MTU but its DF (Don't Fragment) bit is set.
152189 +*//***************************************************************************/
152190 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
152191 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
152192 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
152193 + /**< Obsolete, cannot enqueue to error queue;
152194 + In practice, selects to discard packets;
152195 + Will be removed in the future */
152196 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
152197 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
152198 +} ioc_fm_pcd_manip_dont_frag_action;
152199 +
152200 +/**************************************************************************//**
152201 + @Description Enumeration type for selecting type of special offload manipulation
152202 +*//***************************************************************************/
152203 +typedef enum ioc_fm_pcd_manip_special_offload_type {
152204 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
152205 +#if (DPAA_VERSION >= 11)
152206 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
152207 +#endif /* (DPAA_VERSION >= 11) */
152208 +} ioc_fm_pcd_manip_special_offload_type;
152209 +
152210 +/**************************************************************************//**
152211 + @Description A union of protocol dependent special options
152212 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
152213 +*//***************************************************************************/
152214 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
152215 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
152216 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
152217 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
152218 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
152219 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
152220 +#if (DPAA_VERSION >= 11)
152221 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
152222 +#endif /* (DPAA_VERSION >= 11) */
152223 +} ioc_fm_pcd_hdr_protocol_opt_u;
152224 +
152225 +/**************************************************************************//**
152226 + @Description A union holding all known protocol fields
152227 +*//***************************************************************************/
152228 +typedef union ioc_fm_pcd_fields_u {
152229 + ioc_header_field_eth_t eth; /**< Ethernet */
152230 + ioc_header_field_vlan_t vlan; /**< VLAN */
152231 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
152232 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
152233 + ioc_header_field_mpls_t mpls; /**< MPLS */
152234 + ioc_header_field_ip_t ip; /**< IP */
152235 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
152236 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
152237 + ioc_header_field_udp_t udp; /**< UDP */
152238 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
152239 + ioc_header_field_tcp_t tcp; /**< TCP */
152240 + ioc_header_field_sctp_t sctp; /**< SCTP */
152241 + ioc_header_field_dccp_t dccp; /**< DCCP */
152242 + ioc_header_field_gre_t gre; /**< GRE */
152243 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
152244 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
152245 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
152246 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
152247 +} ioc_fm_pcd_fields_u;
152248 +
152249 +/**************************************************************************//**
152250 + @Description Parameters for defining header extraction for key generation
152251 +*//***************************************************************************/
152252 +typedef struct ioc_fm_pcd_from_hdr_t {
152253 + uint8_t size; /**< Size in byte */
152254 + uint8_t offset; /**< Byte offset */
152255 +} ioc_fm_pcd_from_hdr_t;
152256 +
152257 +/**************************************************************************//**
152258 + @Description Parameters for defining field extraction for key generation
152259 +*//***************************************************************************/
152260 +typedef struct ioc_fm_pcd_from_field_t {
152261 + ioc_fm_pcd_fields_u field; /**< Field selection */
152262 + uint8_t size; /**< Size in byte */
152263 + uint8_t offset; /**< Byte offset */
152264 +} ioc_fm_pcd_from_field_t;
152265 +
152266 +/**************************************************************************//**
152267 + @Description Parameters for defining a single network environment unit
152268 + A distinction unit should be defined if it will later be used
152269 + by one or more PCD engines to distinguish between flows.
152270 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
152271 +*//***************************************************************************/
152272 +typedef struct ioc_fm_pcd_distinction_unit_t {
152273 + struct {
152274 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
152275 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
152276 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
152277 +} ioc_fm_pcd_distinction_unit_t;
152278 +
152279 +/**************************************************************************//**
152280 + @Description Parameters for defining all different distinction units supported
152281 + by a specific PCD Network Environment Characteristics module.
152282 +
152283 + Each unit represent a protocol or a group of protocols that may
152284 + be used later by the different PCD engines to distinguish between flows.
152285 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
152286 +*//***************************************************************************/
152287 +typedef struct ioc_fm_pcd_net_env_params_t {
152288 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
152289 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
152290 + /**< An array of num_of_distinction_units of the
152291 + different units to be identified */
152292 + void *id; /**< Output parameter; Returns the net-env Id to be used */
152293 +} ioc_fm_pcd_net_env_params_t;
152294 +
152295 +/**************************************************************************//**
152296 + @Description Parameters for defining a single extraction action when
152297 + creating a key
152298 +*//***************************************************************************/
152299 +typedef struct ioc_fm_pcd_extract_entry_t {
152300 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
152301 + union {
152302 + struct {
152303 + ioc_net_header_type hdr; /**< Header selection */
152304 + bool ignore_protocol_validation;
152305 + /**< Ignore protocol validation */
152306 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
152307 + IP. Otherwise should be cleared.*/
152308 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
152309 + union {
152310 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
152311 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
152312 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
152313 + } extract_by_hdr_type;
152314 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
152315 + struct {
152316 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
152317 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
152318 + uint16_t ic_indx_mask; /**< Relevant only for CC when
152319 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
152320 + Note that the number of bits that are set within
152321 + this mask must be log2 of the CC-node 'num_of_keys'.
152322 + Note that the mask cannot be set on the lower bits. */
152323 + uint8_t offset; /**< Byte offset */
152324 + uint8_t size; /**< Size in bytes */
152325 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
152326 + } extract_params;
152327 +} ioc_fm_pcd_extract_entry_t;
152328 +
152329 +/**************************************************************************//**
152330 + @Description A structure for defining masks for each extracted
152331 + field in the key.
152332 +*//***************************************************************************/
152333 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
152334 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
152335 + uint8_t offset; /**< Byte offset */
152336 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
152337 +} ioc_fm_pcd_kg_extract_mask_t;
152338 +
152339 +/**************************************************************************//**
152340 + @Description A structure for defining default selection per groups
152341 + of fields
152342 +*//***************************************************************************/
152343 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
152344 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
152345 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
152346 +} ioc_fm_pcd_kg_extract_dflt_t;
152347 +
152348 +
152349 +/**************************************************************************//**
152350 + @Description A structure for defining all parameters needed for
152351 + generation a key and using a hash function
152352 +*//***************************************************************************/
152353 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
152354 + uint32_t private_dflt0; /**< Scheme default register 0 */
152355 + uint32_t private_dflt1; /**< Scheme default register 1 */
152356 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
152357 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
152358 + /**< An array of extraction definitions. */
152359 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
152360 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
152361 + /**< For each extraction used in this scheme, specify the required
152362 + default register to be used when header is not found.
152363 + types not specified in this array will get undefined value. */
152364 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
152365 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
152366 + uint8_t hash_shift; /**< Hash result right shift.
152367 + Selects the 24 bits out of the 64 hash result.
152368 + 0 means using the 24 LSB's, otherwise use the
152369 + 24 LSB's after shifting right.*/
152370 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
152371 + of queues for the key and hash functionality */
152372 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
152373 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
152374 + destination fields on all layers; If TRUE, driver will check that for
152375 + all layers, if SRC extraction is selected, DST extraction must also be
152376 + selected, and vice versa. */
152377 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
152378 +
152379 +/**************************************************************************//**
152380 + @Description A structure of parameters for defining a single
152381 + Qid mask (extracted OR).
152382 +*//***************************************************************************/
152383 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
152384 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
152385 + union {
152386 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
152387 + ioc_net_header_type hdr;
152388 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
152389 + IP. Otherwise should be cleared.*/
152390 + bool ignore_protocol_validation;
152391 +
152392 + } extract_by_hdr;
152393 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
152394 + } extract_params;
152395 + uint8_t extraction_offset; /**< Offset for extraction */
152396 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
152397 + field not found */
152398 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
152399 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
152400 + the extracted byte; Assume byte is placed as the 8 MSB's in
152401 + a 32 bit word where the lower bits
152402 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
152403 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
152404 + extracted byte will effect the 8 LSB's of the FQID,
152405 + if bitOffsetInFqid=31 than the byte's MSB will effect
152406 + the FQID's LSB; 0 means - no effect on FQID;
152407 + Note that one, and only one of
152408 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
152409 + extracted byte must effect either FQID or Policer profile).*/
152410 + uint8_t bit_offset_in_plcr_profile;
152411 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
152412 + effect using the extracted byte; Assume byte is placed
152413 + as the 8 MSB's in a 16 bit word where the lower bits
152414 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
152415 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
152416 + than the extracted byte will effect the whole policer profile id,
152417 + if bitOffsetInFqid=15 than the byte's MSB will effect
152418 + the Policer Profile id's LSB;
152419 + 0 means - no effect on policer profile; Note that one, and only one of
152420 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
152421 + extracted byte must effect either FQID or Policer profile).*/
152422 +} ioc_fm_pcd_kg_extracted_or_params_t;
152423 +
152424 +/**************************************************************************//**
152425 + @Description A structure for configuring scheme counter
152426 +*//***************************************************************************/
152427 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
152428 + bool update; /**< FALSE to keep the current counter state
152429 + and continue from that point, TRUE to update/reset
152430 + the counter when the scheme is written. */
152431 + uint32_t value; /**< If update=TRUE, this value will be written into the
152432 + counter; clear this field to reset the counter. */
152433 +} ioc_fm_pcd_kg_scheme_counter_t;
152434 +
152435 +
152436 +/**************************************************************************//**
152437 + @Description A structure for retrieving FMKG_SE_SPC
152438 +*//***************************************************************************/
152439 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
152440 + uint32_t val; /**< return value */
152441 + void *id; /**< scheme handle */
152442 +} ioc_fm_pcd_kg_scheme_spc_t;
152443 +
152444 +/**************************************************************************//**
152445 + @Description A structure for defining policer profile parameters as required by keygen
152446 + (when policer is the next engine after this scheme).
152447 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
152448 +*//***************************************************************************/
152449 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
152450 + bool shared_profile; /**< TRUE if this profile is shared between ports
152451 + (i.e. managed by master partition) May not be TRUE
152452 + if profile is after Coarse Classification*/
152453 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
152454 + id, if FALSE fqid_offset_relative_profile_id_base is used
152455 + together with fqid_offset_shift and num_of_profiles
152456 + parameters, to define a range of profiles from
152457 + which the KeyGen result will determine the
152458 + destination policer profile. */
152459 + union {
152460 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
152461 + This parameter should indicate the policer profile offset within the port's
152462 + policer profiles or SHARED window. */
152463 + struct {
152464 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
152465 + uint8_t fqid_offset_relative_profile_id_base;
152466 + /**< OR of KG results without the qid base
152467 + This parameter should indicate the policer profile
152468 + offset within the port's policer profiles window
152469 + or SHARED window depends on shared_profile */
152470 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
152471 + } indirect_profile; /**< Indirect profile parameters */
152472 + } profile_select; /**< Direct/indirect profile selection and parameters */
152473 +} ioc_fm_pcd_kg_plcr_profile_t;
152474 +
152475 +#if DPAA_VERSION >= 11
152476 +/**************************************************************************//**
152477 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
152478 +*//***************************************************************************/
152479 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
152480 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
152481 + profile id;
152482 + If FALSE, fqidOffsetRelativeProfileIdBase is used
152483 + together with fqidOffsetShift and numOfProfiles
152484 + parameters to define a range of profiles from which
152485 + the KeyGen result will determine the destination
152486 + storage profile. */
152487 + union {
152488 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
152489 + should indicate the storage profile offset within the
152490 + port's storage profiles window. */
152491 + struct {
152492 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
152493 + uint8_t fqid_offset_relative_profile_id_base;
152494 + /**< OR of KeyGen results without the FQID base;
152495 + should indicate the policer profile offset within the
152496 + port's storage profiles window. */
152497 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
152498 + } indirect_profile; /**< Indirect profile parameters. */
152499 + } profile_select; /**< Direct/indirect profile selection and parameters. */
152500 +} ioc_fm_pcd_kg_storage_profile_t;
152501 +#endif /* DPAA_VERSION >= 11 */
152502 +
152503 +/**************************************************************************//**
152504 + @Description Parameters for defining CC as the next engine after KeyGen
152505 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
152506 +*//***************************************************************************/
152507 +typedef struct ioc_fm_pcd_kg_cc_t {
152508 + void *tree_id; /**< CC Tree id */
152509 + uint8_t grp_id; /**< CC group id within the CC tree */
152510 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
152511 + policing is required. */
152512 + bool bypass_plcr_profile_generation;
152513 + /**< TRUE to bypass KeyGen policer profile generation;
152514 + selected profile is the one set at port initialization. */
152515 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
152516 + bypass_plcr_profile_generation = FALSE */
152517 +} ioc_fm_pcd_kg_cc_t;
152518 +
152519 +/**************************************************************************//**
152520 + @Description Parameters for defining initializing a KeyGen scheme
152521 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
152522 +*//***************************************************************************/
152523 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
152524 + bool modify; /**< TRUE to change an existing scheme */
152525 + union {
152526 + uint8_t relative_scheme_id;
152527 + /**< if modify=FALSE: partition-relative scheme id */
152528 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
152529 + } scm_id;
152530 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
152531 + for match vector; KeyGen will ignore it when matching */
152532 + struct { /**< HL relevant only if always_direct=FALSE */
152533 + void *net_env_id; /**< The id of the Network Environment as returned
152534 + by FM_PCD_NetEnvCharacteristicsSet() */
152535 + uint8_t num_of_distinction_units;
152536 + /**< Number of NetEnv units listed in unit_ids array */
152537 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
152538 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
152539 + } net_env_params;
152540 + bool use_hash; /**< use the KG Hash functionality */
152541 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
152542 + /**< used only if useHash = TRUE */
152543 + bool bypass_fqid_generation;
152544 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
152545 + In such a case FQID after KG will be the default FQID
152546 + defined for the relevant port, or the FQID defined by CC
152547 + in cases where CC was the previous engine. */
152548 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
152549 + If hash is used and an even distribution is expected
152550 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
152551 + hash_distribution_num_of_fqids. */
152552 + uint8_t num_of_used_extracted_ors;
152553 + /**< Number of FQID masks listed in extracted_ors array*/
152554 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
152555 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
152556 + registers are shared between qid_masks
152557 + functionality and some of the extraction
152558 + actions; Normally only some will be used
152559 + for qid_mask. Driver will return error if
152560 + resource is full at initialization time. */
152561 +#if DPAA_VERSION >= 11
152562 + bool override_storage_profile;
152563 + /**< TRUE if KeyGen override previously decided storage profile */
152564 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
152565 +#endif /* DPAA_VERSION >= 11 */
152566 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
152567 + union { /**< depends on nextEngine */
152568 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
152569 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
152570 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
152571 + } kg_next_engine_params;
152572 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
152573 + the scheme counter */
152574 + void *id; /**< Returns the scheme Id to be used */
152575 +} ioc_fm_pcd_kg_scheme_params_t;
152576 +
152577 +/**************************************************************************//**
152578 + @Collection
152579 +*//***************************************************************************/
152580 +#if DPAA_VERSION >= 11
152581 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
152582 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
152583 +#endif /* DPAA_VERSION >= 11 */
152584 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
152585 +/* @} */
152586 +
152587 +/**************************************************************************//**
152588 + @Description Parameters for defining CC as the next engine after a CC node.
152589 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
152590 +*//***************************************************************************/
152591 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
152592 + void *cc_node_id; /**< Id of the next CC node */
152593 +} ioc_fm_pcd_cc_next_cc_params_t;
152594 +
152595 +#if DPAA_VERSION >= 11
152596 +/**************************************************************************//**
152597 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
152598 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
152599 +*//***************************************************************************/
152600 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
152601 + void* frm_replic_id; /**< The id of the next frame replicator group */
152602 +} ioc_fm_pcd_cc_next_fr_params_t;
152603 +#endif /* DPAA_VERSION >= 11 */
152604 +
152605 +/**************************************************************************//**
152606 + @Description A structure for defining PLCR params when PLCR is the
152607 + next engine after a CC node
152608 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
152609 +*//***************************************************************************/
152610 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
152611 + bool override_params; /**< TRUE if CC override previously decided parameters*/
152612 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
152613 + TRUE if this profile is shared between ports */
152614 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
152615 + (otherwise profile id is taken from keygen);
152616 + This parameter should indicate the policer
152617 + profile offset within the port's
152618 + policer profiles or from SHARED window.*/
152619 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
152620 + FQID for enquing the frame;
152621 + In earlier chips if policer next engine is KEYGEN,
152622 + this parameter can be 0, because the KEYGEN always decides
152623 + the enqueue FQID.*/
152624 +#if DPAA_VERSION >= 11
152625 + uint8_t new_relative_storage_profile_id;
152626 + /**< Indicates the relative storage profile offset within
152627 + the port's storage profiles window;
152628 + Relevant only if the port was configured with VSP. */
152629 +#endif /* DPAA_VERSION >= 11 */
152630 +} ioc_fm_pcd_cc_next_plcr_params_t;
152631 +
152632 +/**************************************************************************//**
152633 + @Description A structure for defining enqueue params when BMI is the
152634 + next engine after a CC node
152635 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
152636 +*//***************************************************************************/
152637 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
152638 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
152639 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
152640 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
152641 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
152642 + (otherwise FQID is taken from KeyGen),
152643 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
152644 +#if DPAA_VERSION >= 11
152645 + uint8_t new_relative_storage_profile_id;
152646 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
152647 + storage profile offset within the port's storage profiles
152648 + window; Relevant only if the port was configured with VSP. */
152649 +#endif /* DPAA_VERSION >= 11 */
152650 +
152651 +} ioc_fm_pcd_cc_next_enqueue_params_t;
152652 +
152653 +/**************************************************************************//**
152654 + @Description A structure for defining KG params when KG is the next engine after a CC node
152655 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
152656 +*//***************************************************************************/
152657 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
152658 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
152659 + Note - this parameters are irrelevant for earlier chips */
152660 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
152661 + (otherwise FQID is taken from KeyGen),
152662 + Note - this parameters are irrelevant for earlier chips */
152663 +#if DPAA_VERSION >= 11
152664 + uint8_t new_relative_storage_profile_id;
152665 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
152666 + storage profile offset within the port's storage profiles
152667 + window; Relevant only if the port was configured with VSP. */
152668 +#endif /* DPAA_VERSION >= 11 */
152669 + void *p_direct_scheme; /**< Direct scheme id to go to. */
152670 +} ioc_fm_pcd_cc_next_kg_params_t;
152671 +
152672 +/**************************************************************************//**
152673 + @Description Parameters for defining the next engine after a CC node.
152674 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
152675 +*//***************************************************************************/
152676 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
152677 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
152678 + according to nextEngine definition */
152679 + union {
152680 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
152681 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
152682 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
152683 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
152684 +#if DPAA_VERSION >= 11
152685 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
152686 +#endif /* DPAA_VERSION >= 11 */
152687 + } params; /**< Union used for all the next-engine parameters options */
152688 + void *manip_id; /**< Handle to Manipulation object.
152689 + Relevant if next engine is of type result
152690 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
152691 + bool statistics_en; /**< If TRUE, statistics counters are incremented
152692 + for each frame passing through this
152693 + Coarse Classification entry. */
152694 +} ioc_fm_pcd_cc_next_engine_params_t;
152695 +
152696 +/**************************************************************************//**
152697 + @Description Parameters for defining a single CC key
152698 +*//***************************************************************************/
152699 +typedef struct ioc_fm_pcd_cc_key_params_t {
152700 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
152701 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
152702 + in keySize. p_key and p_mask (if defined) has to be
152703 + of the same size defined in the key_size */
152704 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
152705 + /**< parameters for the next for the defined Key in p_key */
152706 +
152707 +} ioc_fm_pcd_cc_key_params_t;
152708 +
152709 +/**************************************************************************//**
152710 + @Description Parameters for defining CC keys parameters
152711 + The driver supports two methods for CC node allocation: dynamic and static.
152712 + Static mode was created in order to prevent runtime alloc/free
152713 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
152714 + the driver automatically allocates the memory according to
152715 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
152716 + size that may be used for this CC-Node taking into consideration
152717 + 'mask_support' and 'statistics_mode' parameters.
152718 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
152719 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
152720 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
152721 + all required structures are allocated according to 'num_of_keys'
152722 + parameter. During runtime modification, these structures are
152723 + re-allocated according to the updated number of keys.
152724 +
152725 + Please note that 'action' and 'ic_indx_mask' mentioned in the
152726 + specific parameter explanations are passed in the extraction
152727 + parameters of the node (fields of extractccparams.extractnonhdr).
152728 +*//***************************************************************************/
152729 +typedef struct ioc_keys_params_t {
152730 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
152731 + A value of zero may be used for dynamic memory allocation. */
152732 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
152733 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
152734 + Should be TRUE to reserve table memory for key masks, even if
152735 + initial keys do not contain masks, or if the node was initialized
152736 + as 'empty' (without keys); this will allow user to add keys with
152737 + masks at runtime. */
152738 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
152739 + To enable statistics gathering, statistics should be enabled per
152740 + every key, using 'statistics_en' in next engine parameters structure
152741 + of that key;
152742 + If 'max_num_of_keys' is set, all required structures will be
152743 + preallocated for all keys. */
152744 +#if (DPAA_VERSION >= 11)
152745 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
152746 + /**< Relevant only for 'RMON' statistics mode
152747 + (this feature is supported only on B4860 device);
152748 + Holds a list of programmable thresholds. For each received frame,
152749 + its length in bytes is examined against these range thresholds and
152750 + the appropriate counter is incremented by 1. For example, to belong
152751 + to range i, the following should hold:
152752 + range i-1 threshold < frame length <= range i threshold
152753 + Each range threshold must be larger then its preceding range
152754 + threshold. Last range threshold must be 0xFFFF. */
152755 +#endif /* (DPAA_VERSION >= 11) */
152756 + uint16_t num_of_keys; /**< Number of initial keys;
152757 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
152758 + this field should be power-of-2 of the number of bits that are
152759 + set in 'ic_indx_mask'. */
152760 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
152761 + to be the standard size of the selected key; For other extraction
152762 + types, 'key_size' has to be as size of extraction; When 'action' =
152763 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
152764 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
152765 + /**< An array with 'num_of_keys' entries, each entry specifies the
152766 + corresponding key parameters;
152767 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
152768 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
152769 + for the 'miss' entry. */
152770 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
152771 + /**< Parameters for defining the next engine when a key is not matched;
152772 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
152773 +} ioc_keys_params_t;
152774 +
152775 +/**************************************************************************//**
152776 + @Description Parameters for defining a CC node
152777 +*//***************************************************************************/
152778 +typedef struct ioc_fm_pcd_cc_node_params_t {
152779 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
152780 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
152781 + void *id; /**< Output parameter; returns the CC node Id to be used */
152782 +} ioc_fm_pcd_cc_node_params_t;
152783 +
152784 +/**************************************************************************//**
152785 + @Description Parameters for defining a hash table
152786 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
152787 +*//***************************************************************************/
152788 +typedef struct ioc_fm_pcd_hash_table_params_t {
152789 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
152790 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
152791 + requested statistics mode will be allocated according to max_num_of_keys. */
152792 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
152793 + that leads to this hash-table. */
152794 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
152795 + The number-of-sets for this hash will be calculated
152796 + as (2^(number of bits set in 'hash_res_mask'));
152797 + The 4 lower bits must be cleared. */
152798 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
152799 + 2-bytes to be used as hash index. */
152800 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
152801 +
152802 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
152803 + /**< Parameters for defining the next engine when a key is not matched */
152804 + void *id;
152805 +} ioc_fm_pcd_hash_table_params_t;
152806 +
152807 +/**************************************************************************//**
152808 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
152809 +*//***************************************************************************/
152810 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
152811 + void *p_hash_tbl;
152812 + uint8_t key_size;
152813 + ioc_fm_pcd_cc_key_params_t key_params;
152814 +} ioc_fm_pcd_hash_table_add_key_params_t;
152815 +
152816 +/**************************************************************************//**
152817 + @Description Parameters for defining a CC tree group.
152818 +
152819 + This structure defines a CC group in terms of NetEnv units
152820 + and the action to be taken in each case. The unit_ids list must
152821 + be given in order from low to high indices.
152822 +
152823 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
152824 + structures where each defines the next action to be taken for
152825 + each units combination. for example:
152826 + num_of_distinction_units = 2
152827 + unit_ids = {1,3}
152828 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
152829 + unit 1 - not found; unit 3 - not found;
152830 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
152831 + unit 1 - not found; unit 3 - found;
152832 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
152833 + unit 1 - found; unit 3 - not found;
152834 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
152835 + unit 1 - found; unit 3 - found;
152836 +*//***************************************************************************/
152837 +typedef struct ioc_fm_pcd_cc_grp_params_t {
152838 + uint8_t num_of_distinction_units; /**< Up to 4 */
152839 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
152840 + /**< Indexes of the units as defined in
152841 + FM_PCD_NetEnvCharacteristicsSet() */
152842 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
152843 + /**< Maximum entries per group is 16 */
152844 +} ioc_fm_pcd_cc_grp_params_t;
152845 +
152846 +/**************************************************************************//**
152847 + @Description Parameters for defining the CC tree groups
152848 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
152849 +*//***************************************************************************/
152850 +typedef struct ioc_fm_pcd_cc_tree_params_t {
152851 + void *net_env_id; /**< Id of the Network Environment as returned
152852 + by FM_PCD_NetEnvCharacteristicsSet() */
152853 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
152854 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
152855 + /**< Parameters for each group. */
152856 + void *id; /**< Output parameter; Returns the tree Id to be used */
152857 +} ioc_fm_pcd_cc_tree_params_t;
152858 +
152859 +/**************************************************************************//**
152860 + @Description Parameters for defining policer byte rate
152861 +*//***************************************************************************/
152862 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
152863 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
152864 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
152865 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
152866 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
152867 +
152868 +/**************************************************************************//**
152869 + @Description Parameters for defining the policer profile (based on
152870 + RFC-2698 or RFC-4115 attributes).
152871 +*//***************************************************************************/
152872 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
152873 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
152874 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
152875 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
152876 + uint32_t committed_burst_size; /**< KBits or Packets */
152877 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
152878 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
152879 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
152880 +
152881 +/**************************************************************************//**
152882 + @Description Parameters for defining the next engine after policer
152883 +*//***************************************************************************/
152884 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
152885 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
152886 + void *p_profile; /**< Policer profile handle - used when next engine
152887 + is PLCR, must be a SHARED profile */
152888 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
152889 +} ioc_fm_pcd_plcr_next_engine_params_u;
152890 +
152891 +typedef struct ioc_fm_pcd_port_params_t {
152892 + ioc_fm_port_type port_type; /**< Type of port for this profile */
152893 + uint8_t port_id; /**< FM-Port id of port for this profile */
152894 +} ioc_fm_pcd_port_params_t;
152895 +
152896 +/**************************************************************************//**
152897 + @Description Parameters for defining the policer profile entry
152898 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
152899 +*//***************************************************************************/
152900 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
152901 + bool modify; /**< TRUE to change an existing profile */
152902 + union {
152903 + struct {
152904 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
152905 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
152906 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
152907 + } new_params; /**< Use it when modify = FALSE */
152908 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
152909 + } profile_select;
152910 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
152911 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
152912 +
152913 + union {
152914 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
152915 + any incoming packet with the default value. */
152916 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
152917 + pre-color value of 2'b11. */
152918 + } color;
152919 +
152920 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
152921 +
152922 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
152923 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
152924 +
152925 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
152926 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
152927 +
152928 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
152929 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
152930 +
152931 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
152932 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
152933 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
152934 +
152935 + void *id; /**< output parameter; Returns the profile Id to be used */
152936 +} ioc_fm_pcd_plcr_profile_params_t;
152937 +
152938 +/**************************************************************************//**
152939 + @Description A structure for modifying CC tree next engine
152940 +*//***************************************************************************/
152941 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
152942 + void *id; /**< CC tree Id to be used */
152943 + uint8_t grp_indx; /**< A Group index in the tree */
152944 + uint8_t indx; /**< Entry index in the group defined by grp_index */
152945 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
152946 + /**< Parameters for the next for the defined Key in the p_Key */
152947 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
152948 +
152949 +/**************************************************************************//**
152950 + @Description A structure for modifying CC node next engine
152951 +*//***************************************************************************/
152952 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
152953 + void *id; /**< CC node Id to be used */
152954 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152955 + NOTE: This parameter is IGNORED for miss-key! */
152956 + uint8_t key_size; /**< Key size of added key */
152957 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
152958 + /**< parameters for the next for the defined Key in the p_Key */
152959 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
152960 +
152961 +/**************************************************************************//**
152962 + @Description A structure for remove CC node key
152963 +*//***************************************************************************/
152964 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
152965 + void *id; /**< CC node Id to be used */
152966 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152967 + NOTE: This parameter is IGNORED for miss-key! */
152968 +} ioc_fm_pcd_cc_node_remove_key_params_t;
152969 +
152970 +/**************************************************************************//**
152971 + @Description A structure for modifying CC node key and next engine
152972 +*//***************************************************************************/
152973 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
152974 + void *id; /**< CC node Id to be used */
152975 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152976 + NOTE: This parameter is IGNORED for miss-key! */
152977 + uint8_t key_size; /**< Key size of added key */
152978 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
152979 + the array of the type ioc_fm_pcd_cc_key_params_t */
152980 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
152981 +
152982 +/**************************************************************************//**
152983 + @Description A structure for modifying CC node key
152984 +*//***************************************************************************/
152985 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
152986 + void *id; /**< CC node Id to be used */
152987 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
152988 + NOTE: This parameter is IGNORED for miss-key! */
152989 + uint8_t key_size; /**< Key size of added key */
152990 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
152991 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
152992 + in keySize. p_Key and p_Mask (if defined) have to be
152993 + of the same size as defined in the key_size */
152994 +} ioc_fm_pcd_cc_node_modify_key_params_t;
152995 +
152996 +/**************************************************************************//**
152997 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
152998 +*//***************************************************************************/
152999 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
153000 + void *p_hash_tbl; /**< The id of the hash table */
153001 + uint8_t key_size; /**< The size of the key to remove */
153002 + uint8_t *p_key; /**< Pointer to the key to remove */
153003 +} ioc_fm_pcd_hash_table_remove_key_params_t;
153004 +
153005 +/**************************************************************************//**
153006 + @Description Parameters for selecting a location for requested manipulation
153007 +*//***************************************************************************/
153008 +typedef struct ioc_fm_manip_hdr_info_t {
153009 + ioc_net_header_type hdr; /**< Header selection */
153010 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
153011 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
153012 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
153013 +} ioc_fm_manip_hdr_info_t;
153014 +
153015 +/**************************************************************************//**
153016 + @Description Parameters for defining header removal by header type
153017 +*//***************************************************************************/
153018 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
153019 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
153020 + union {
153021 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
153022 + struct {
153023 + bool include;/**< If FALSE, remove until the specified header (not including the header);
153024 + If TRUE, remove also the specified header. */
153025 + ioc_fm_manip_hdr_info_t hdr_info;
153026 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
153027 +#endif /* FM_CAPWAP_SUPPORT */
153028 +#if (DPAA_VERSION >= 11)
153029 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
153030 +#endif /* (DPAA_VERSION >= 11) */
153031 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
153032 + Defines which L2 headers to remove. */
153033 + } u;
153034 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
153035 +
153036 +/**************************************************************************//**
153037 + @Description Parameters for configuring IP fragmentation manipulation
153038 +*//***************************************************************************/
153039 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
153040 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
153041 + IP fragmentation will be executed.*/
153042 +#if DPAA_VERSION == 10
153043 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
153044 +#endif /* DPAA_VERSION == 10 */
153045 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
153046 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
153047 + received frame's buffer. */
153048 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
153049 + This parameter is relevant when 'sg_bpid_en=TRUE';
153050 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
153051 + of this pool need to be allocated in the same memory area as the received buffers.
153052 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
153053 + mutual to all these sources. */
153054 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
153055 + than MTU and its DF bit is set, then this field will
153056 + determine the action to be taken.*/
153057 +} ioc_fm_pcd_manip_frag_ip_params_t;
153058 +
153059 +/**************************************************************************//**
153060 + @Description Parameters for configuring IP reassembly manipulation.
153061 +
153062 + This is a common structure for both IPv4 and IPv6 reassembly
153063 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
153064 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
153065 +*//***************************************************************************/
153066 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
153067 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
153068 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
153069 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
153070 + NOTE: The following comment is relevant only for FMAN v2 devices:
153071 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
153072 + the user schemes id to ensure that the reassembly's schemes will be first match.
153073 + The remaining schemes, if defined, should have higher relative scheme ID. */
153074 +#if DPAA_VERSION >= 11
153075 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
153076 + profile than the opening fragment (Non-Consistent-SP state)
153077 + then one of two possible scenarios occurs:
153078 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
153079 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
153080 +#else
153081 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
153082 +#endif /* DPAA_VERSION >= 11 */
153083 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
153084 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
153085 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
153086 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
153087 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
153088 + /**< Number of frames per hash entry needed for reassembly process:
153089 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
153090 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
153091 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
153092 + Must be power of 2;
153093 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
153094 + maxNumFramesInProcess has to be in the range of 4 - 512;
153095 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
153096 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
153097 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
153098 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
153099 + uint32_t timeout_threshold_for_reassm_process;
153100 + /**< Represents the time interval in microseconds which defines
153101 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
153102 +} ioc_fm_pcd_manip_reassem_ip_params_t;
153103 +
153104 +/**************************************************************************//**
153105 + @Description Parameters for defining IPSEC manipulation
153106 +*//***************************************************************************/
153107 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
153108 + bool decryption; /**< TRUE if being used in decryption direction;
153109 + FALSE if being used in encryption direction. */
153110 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
153111 + (direction depends on the 'decryption' field). */
153112 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
153113 + (direction depends on the 'decryption' field). */
153114 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
153115 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
153116 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
153117 + It is specifies the length of the outer IP header that was configured in the
153118 + corresponding SA. */
153119 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
153120 + The value must be a multiplication of 16 */
153121 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
153122 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
153123 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
153124 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
153125 +
153126 +#if (DPAA_VERSION >= 11)
153127 +/**************************************************************************//**
153128 + @Description Parameters for configuring CAPWAP fragmentation manipulation
153129 +
153130 + Restrictions:
153131 + - Maximum number of fragments per frame is 16.
153132 + - Transmit confirmation is not supported.
153133 + - Fragmentation nodes must be set as the last PCD action (i.e. the
153134 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
153135 + - Only BMan buffers shall be used for frames to be fragmented.
153136 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
153137 + does not support VSP. Therefore, on the same port where we have IPF we
153138 + cannot support VSP.
153139 +*//***************************************************************************/
153140 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
153141 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
153142 + CAPWAP fragmentation will be executed.*/
153143 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
153144 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
153145 + received frame's buffer. */
153146 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
153147 + This parameters is relevant when 'sgBpidEn=TRUE';
153148 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
153149 + of this pool need to be allocated in the same memory area as the received buffers.
153150 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
153151 + mutual to all these sources. */
153152 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
153153 + When this mode is enabled then only the first fragment include the CAPWAP header options
153154 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
153155 + options field (CAPWAP header is updated accordingly).*/
153156 +} ioc_fm_pcd_manip_frag_capwap_params_t;
153157 +
153158 +/**************************************************************************//**
153159 + @Description Parameters for configuring CAPWAP reassembly manipulation.
153160 +
153161 + Restrictions:
153162 + - Application must define one scheme to catch the reassembled frames.
153163 + - Maximum number of fragments per frame is 16.
153164 +
153165 +*//***************************************************************************/
153166 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
153167 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
153168 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
153169 + Rest schemes, if defined, should have higher relative scheme ID. */
153170 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
153171 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
153172 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
153173 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
153174 + considered as a valid length;
153175 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
153176 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
153177 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
153178 + /**< Number of frames per hash entry needed for reassembly process */
153179 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
153180 + Must be power of 2;
153181 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
153182 + maxNumFramesInProcess has to be in the range of 4 - 512;
153183 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
153184 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
153185 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
153186 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
153187 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
153188 + uint32_t timeout_threshold_for_reassm_process;
153189 + /**< Represents the time interval in microseconds which defines
153190 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
153191 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
153192 +
153193 +/**************************************************************************//**
153194 + @Description structure for defining CAPWAP manipulation
153195 +*//***************************************************************************/
153196 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
153197 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
153198 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
153199 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
153200 +
153201 +#endif /* (DPAA_VERSION >= 11) */
153202 +
153203 +/**************************************************************************//**
153204 + @Description Parameters for defining special offload manipulation
153205 +*//***************************************************************************/
153206 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
153207 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
153208 + union
153209 + {
153210 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
153211 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
153212 +
153213 +#if (DPAA_VERSION >= 11)
153214 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
153215 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
153216 +#endif /* (DPAA_VERSION >= 11) */
153217 + } u;
153218 +} ioc_fm_pcd_manip_special_offload_params_t;
153219 +
153220 +/**************************************************************************//**
153221 + @Description Parameters for defining generic removal manipulation
153222 +*//***************************************************************************/
153223 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
153224 + uint8_t offset; /**< Offset from beginning of header to the start
153225 + location of the removal */
153226 + uint8_t size; /**< Size of removed section */
153227 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
153228 +
153229 +/**************************************************************************//**
153230 + @Description Parameters for defining insertion manipulation
153231 +*//***************************************************************************/
153232 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
153233 + uint8_t size; /**< size of inserted section */
153234 + uint8_t *p_data; /**< data to be inserted */
153235 +} ioc_fm_pcd_manip_hdr_insrt_t;
153236 +
153237 +/**************************************************************************//**
153238 + @Description Parameters for defining generic insertion manipulation
153239 +*//***************************************************************************/
153240 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
153241 + uint8_t offset; /**< Offset from beginning of header to the start
153242 + location of the insertion */
153243 + uint8_t size; /**< Size of inserted section */
153244 + bool replace; /**< TRUE to override (replace) existing data at
153245 + 'offset', FALSE to insert */
153246 + uint8_t *p_data; /**< Pointer to data to be inserted */
153247 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
153248 +
153249 +/**************************************************************************//**
153250 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
153251 +*//***************************************************************************/
153252 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
153253 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
153254 + /**< A table of VPri values for each DSCP value;
153255 + The index is the D_SCP value (0-0x3F) and the
153256 + value is the corresponding VPRI (0-15). */
153257 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
153258 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
153259 + this field is the Q Tag default value if the
153260 + IP header is not found. */
153261 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
153262 +
153263 +/**************************************************************************//**
153264 + @Description Parameters for defining header manipulation VLAN fields updates
153265 +*//***************************************************************************/
153266 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
153267 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
153268 + union {
153269 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
153270 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
153271 + is the new VLAN pri. */
153272 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
153273 + /**< Parameters structure, Relevant only if update_type =
153274 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
153275 + } u;
153276 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
153277 +
153278 +/**************************************************************************//**
153279 + @Description Parameters for defining header manipulation IPV4 fields updates
153280 +*//***************************************************************************/
153281 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
153282 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
153283 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
153284 + IOC_HDR_MANIP_IPV4_TOS */
153285 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
153286 + contains IOC_HDR_MANIP_IPV4_ID */
153287 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
153288 + contains IOC_HDR_MANIP_IPV4_SRC */
153289 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
153290 + contains IOC_HDR_MANIP_IPV4_DST */
153291 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
153292 +
153293 +/**************************************************************************//**
153294 + @Description Parameters for defining header manipulation IPV6 fields updates
153295 +*//***************************************************************************/
153296 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
153297 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
153298 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
153299 + IOC_HDR_MANIP_IPV6_TC */
153300 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
153301 + /**< 16 byte new IP SRC; Relevant only if valid_updates
153302 + contains IOC_HDR_MANIP_IPV6_SRC */
153303 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
153304 + /**< 16 byte new IP DST; Relevant only if valid_updates
153305 + contains IOC_HDR_MANIP_IPV6_DST */
153306 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
153307 +
153308 +/**************************************************************************//**
153309 + @Description Parameters for defining header manipulation TCP/UDP fields updates
153310 +*//***************************************************************************/
153311 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
153312 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
153313 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
153314 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
153315 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
153316 + contains IOC_HDR_MANIP_TCP_UDP_DST */
153317 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
153318 +
153319 +/**************************************************************************//**
153320 + @Description Parameters for defining header manipulation fields updates
153321 +*//***************************************************************************/
153322 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
153323 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
153324 + union {
153325 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
153326 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
153327 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
153328 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
153329 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
153330 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
153331 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
153332 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
153333 + } u;
153334 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
153335 +
153336 +/**************************************************************************//**
153337 + @Description Parameters for defining custom header manipulation for IP replacement
153338 +*//***************************************************************************/
153339 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
153340 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
153341 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
153342 + bool update_ipv4_id; /**< Relevant when replace_type =
153343 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
153344 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
153345 + update_ipv4_id = TRUE */
153346 + uint8_t hdr_size; /**< The size of the new IP header */
153347 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
153348 + /**< The new IP header */
153349 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
153350 +
153351 +/**************************************************************************//**
153352 + @Description Parameters for defining custom header manipulation
153353 +*//***************************************************************************/
153354 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
153355 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
153356 + union {
153357 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
153358 + /**< Parameters IP header replacement */
153359 + } u;
153360 +} ioc_fm_pcd_manip_hdr_custom_params_t;
153361 +
153362 +/**************************************************************************//**
153363 + @Description Parameters for defining specific L2 insertion manipulation
153364 +*//***************************************************************************/
153365 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
153366 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
153367 + bool update; /**< TRUE to update MPLS header */
153368 + uint8_t size; /**< size of inserted section */
153369 + uint8_t *p_data; /**< data to be inserted */
153370 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
153371 +
153372 +#if (DPAA_VERSION >= 11)
153373 +/**************************************************************************//**
153374 + @Description Parameters for defining IP insertion manipulation
153375 +*//***************************************************************************/
153376 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
153377 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
153378 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
153379 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
153380 + the inserted header */
153381 + uint16_t id; /**< 16 bit New IP ID */
153382 + bool dont_frag_overwrite;
153383 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
153384 + * This byte is configured to be overwritten when RPD is set. */
153385 + uint8_t last_dst_offset;
153386 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
153387 + * in order to calculate UDP checksum pseudo header;
153388 + * Otherwise set it to '0'. */
153389 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
153390 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
153391 +#endif /* (DPAA_VERSION >= 11) */
153392 +
153393 +/**************************************************************************//**
153394 + @Description Parameters for defining header insertion manipulation by header type
153395 +*//***************************************************************************/
153396 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
153397 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
153398 + union {
153399 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
153400 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
153401 + Selects which L2 headers to remove */
153402 +#if (DPAA_VERSION >= 11)
153403 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
153404 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
153405 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
153406 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
153407 +#endif /* (DPAA_VERSION >= 11) */
153408 + } u;
153409 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
153410 +
153411 +/**************************************************************************//**
153412 + @Description Parameters for defining header insertion manipulation
153413 +*//***************************************************************************/
153414 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
153415 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
153416 + union {
153417 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
153418 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
153419 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
153420 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
153421 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153422 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
153423 + /**< Parameters for defining header insertion manipulation by template,
153424 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
153425 +#endif /* FM_CAPWAP_SUPPORT */
153426 + } u;
153427 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
153428 +
153429 +/**************************************************************************//**
153430 + @Description Parameters for defining header removal manipulation
153431 +*//***************************************************************************/
153432 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
153433 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
153434 + union {
153435 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
153436 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
153437 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
153438 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
153439 + } u;
153440 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
153441 +
153442 +/**************************************************************************//**
153443 + @Description Parameters for defining header manipulation node
153444 +*//***************************************************************************/
153445 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
153446 + bool rmv; /**< TRUE, to define removal manipulation */
153447 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
153448 +
153449 + bool insrt; /**< TRUE, to define insertion manipulation */
153450 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
153451 +
153452 + bool field_update; /**< TRUE, to define field update manipulation */
153453 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
153454 +
153455 + bool custom; /**< TRUE, to define custom manipulation */
153456 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
153457 +
153458 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
153459 + completing the manipulation on the frame */
153460 +} ioc_fm_pcd_manip_hdr_params_t;
153461 +
153462 +
153463 +/**************************************************************************//**
153464 + @Description structure for defining fragmentation manipulation
153465 +*//***************************************************************************/
153466 +typedef struct ioc_fm_pcd_manip_frag_params_t {
153467 + ioc_net_header_type hdr; /**< Header selection */
153468 + union {
153469 +#if (DPAA_VERSION >= 11)
153470 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
153471 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
153472 +#endif /* (DPAA_VERSION >= 11) */
153473 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
153474 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
153475 + } u;
153476 +} ioc_fm_pcd_manip_frag_params_t;
153477 +
153478 +/**************************************************************************//**
153479 + @Description structure for defining reassemble manipulation
153480 +*//***************************************************************************/
153481 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
153482 + ioc_net_header_type hdr; /**< Header selection */
153483 + union {
153484 +#if (DPAA_VERSION >= 11)
153485 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
153486 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
153487 +#endif /* (DPAA_VERSION >= 11) */
153488 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
153489 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
153490 + } u;
153491 +} ioc_fm_pcd_manip_reassem_params_t;
153492 +
153493 +/**************************************************************************//**
153494 + @Description Parameters for defining a manipulation node
153495 +*//***************************************************************************/
153496 +typedef struct ioc_fm_pcd_manip_params_t {
153497 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
153498 + union {
153499 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
153500 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
153501 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
153502 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
153503 + } u;
153504 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
153505 + Allows concatenation of manipulation actions
153506 + This parameter is optional and may be NULL. */
153507 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153508 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
153509 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
153510 + relevant if frag_or_reasm = TRUE */
153511 +#endif /* FM_CAPWAP_SUPPORT */
153512 + void *id;
153513 +} ioc_fm_pcd_manip_params_t;
153514 +
153515 +/**************************************************************************//**
153516 + @Description Structure for retrieving IP reassembly statistics
153517 +*//***************************************************************************/
153518 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
153519 + /* common counters for both IPv4 and IPv6 */
153520 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
153521 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
153522 + a Reassembly Frame Descriptor */
153523 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
153524 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
153525 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
153526 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
153527 +#if (DPAA_VERSION >= 11)
153528 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
153529 + successfully reassembled frames */
153530 +#endif /* (DPAA_VERSION >= 11) */
153531 +struct {
153532 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
153533 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
153534 + have been processed for all frames */
153535 + uint32_t processed_fragments; /**< Counts the number of processed fragments
153536 + (valid and error fragments) for all frames */
153537 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
153538 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
153539 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
153540 + to access an IP-Reassembly Automatic Learning Hash set */
153541 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
153542 + exceeds 16 */
153543 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
153544 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
153545 +
153546 +/**************************************************************************//**
153547 + @Description Structure for retrieving IP fragmentation statistics
153548 +*//***************************************************************************/
153549 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
153550 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
153551 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
153552 + uint32_t generated_fragments; /**< Number of fragments that were generated */
153553 +} ioc_fm_pcd_manip_frag_ip_stats_t;
153554 +
153555 +#if (DPAA_VERSION >= 11)
153556 +/**************************************************************************//**
153557 + @Description Structure for retrieving CAPWAP reassembly statistics
153558 +*//***************************************************************************/
153559 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
153560 + uint32_t timeout; /**< Counts the number of timeout occurrences */
153561 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
153562 + a Reassembly Frame Descriptor */
153563 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
153564 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
153565 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
153566 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
153567 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
153568 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
153569 + have been processed for all frames */
153570 + uint32_t processed_fragments; /**< Counts the number of processed fragments
153571 + (valid and error fragments) for all frames */
153572 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
153573 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
153574 + to access an Reassembly Automatic Learning Hash set */
153575 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
153576 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
153577 + exceeds 16 */
153578 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
153579 + length exceeds MaxReassembledFrameLength value */
153580 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
153581 +
153582 +/**************************************************************************//**
153583 + @Description Structure for retrieving CAPWAP fragmentation statistics
153584 +*//***************************************************************************/
153585 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
153586 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
153587 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
153588 + uint32_t generated_fragments; /**< Number of fragments that were generated */
153589 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
153590 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
153591 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
153592 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
153593 +#endif /* (DPAA_VERSION >= 11) */
153594 +
153595 +/**************************************************************************//**
153596 + @Description Structure for retrieving reassembly statistics
153597 +*//***************************************************************************/
153598 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
153599 + union {
153600 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
153601 +#if (DPAA_VERSION >= 11)
153602 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
153603 +#endif /* (DPAA_VERSION >= 11) */
153604 + } u;
153605 +} ioc_fm_pcd_manip_reassem_stats_t;
153606 +
153607 +/**************************************************************************//**
153608 + @Description structure for retrieving fragmentation statistics
153609 +*//***************************************************************************/
153610 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
153611 + union {
153612 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
153613 +#if (DPAA_VERSION >= 11)
153614 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
153615 +#endif /* (DPAA_VERSION >= 11) */
153616 + } u;
153617 +} ioc_fm_pcd_manip_frag_stats_t;
153618 +
153619 +/**************************************************************************//**
153620 + @Description structure for defining manipulation statistics
153621 +*//***************************************************************************/
153622 +typedef struct ioc_fm_pcd_manip_stats_t {
153623 + union {
153624 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
153625 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
153626 + } u;
153627 +} ioc_fm_pcd_manip_stats_t;
153628 +
153629 +/**************************************************************************//**
153630 + @Description Parameters for acquiring manipulation statistics
153631 +*//***************************************************************************/
153632 +typedef struct ioc_fm_pcd_manip_get_stats_t {
153633 + void *id;
153634 + ioc_fm_pcd_manip_stats_t stats;
153635 +} ioc_fm_pcd_manip_get_stats_t;
153636 +
153637 +#if DPAA_VERSION >= 11
153638 +/**************************************************************************//**
153639 + @Description Parameters for defining frame replicator group and its members
153640 +*//***************************************************************************/
153641 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
153642 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
153643 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
153644 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
153645 + /**< Array of members' parameters */
153646 + void *id;
153647 +} ioc_fm_pcd_frm_replic_group_params_t;
153648 +
153649 +typedef struct ioc_fm_pcd_frm_replic_member_t {
153650 + void *h_replic_group;
153651 + uint16_t member_index;
153652 +} ioc_fm_pcd_frm_replic_member_t;
153653 +
153654 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
153655 + ioc_fm_pcd_frm_replic_member_t member;
153656 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
153657 +} ioc_fm_pcd_frm_replic_member_params_t;
153658 +#endif /* DPAA_VERSION >= 11 */
153659 +
153660 +
153661 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
153662 + uint32_t byte_count; /**< This counter reflects byte count of frames that
153663 + were matched by this key. */
153664 + uint32_t frame_count; /**< This counter reflects count of frames that
153665 + were matched by this key. */
153666 +#if (DPAA_VERSION >= 11)
153667 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
153668 + /**< These counters reflect how many frames matched
153669 + this key in 'RMON' statistics mode:
153670 + Each counter holds the number of frames of a
153671 + specific frames length range, according to the
153672 + ranges provided at initialization. */
153673 +#endif /* (DPAA_VERSION >= 11) */
153674 +} ioc_fm_pcd_cc_key_statistics_t;
153675 +
153676 +
153677 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
153678 + void *id;
153679 + uint16_t key_index;
153680 + ioc_fm_pcd_cc_key_statistics_t statistics;
153681 +} ioc_fm_pcd_cc_tbl_get_stats_t;
153682 +
153683 +/**************************************************************************//**
153684 + @Function FM_PCD_MatchTableGetKeyStatistics
153685 +
153686 + @Description This routine may be used to get statistics counters of specific key
153687 + in a CC Node.
153688 +
153689 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
153690 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
153691 + these counters reflect how many frames passed that were matched
153692 + this key; The total frames count will be returned in the counter
153693 + of the first range (as only one frame length range was defined).
153694 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
153695 + frame count will be separated to frame length counters, based on
153696 + provided frame length ranges.
153697 +
153698 + @Param[in] h_CcNode A handle to the node
153699 + @Param[in] keyIndex Key index for adding
153700 + @Param[out] p_KeyStatistics Key statistics counters
153701 +
153702 + @Return The specific key statistics.
153703 +
153704 + @Cautions Allowed only following FM_PCD_MatchTableSet().
153705 +*//***************************************************************************/
153706 +
153707 +#if defined(CONFIG_COMPAT)
153708 +#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)
153709 +#endif
153710 +#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)
153711 +
153712 +/**************************************************************************//**
153713 + @Function FM_PCD_MatchTableGetMissStatistics
153714 +
153715 + @Description This routine may be used to get statistics counters of miss entry
153716 + in a CC Node.
153717 +
153718 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
153719 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
153720 + these counters reflect how many frames were not matched to any
153721 + existing key and therefore passed through the miss entry; The
153722 + total frames count will be returned in the counter of the
153723 + first range (as only one frame length range was defined).
153724 +
153725 + @Param[in] h_CcNode A handle to the node
153726 + @Param[out] p_MissStatistics Statistics counters for 'miss'
153727 +
153728 + @Return E_OK on success; Error code otherwise.
153729 +
153730 + @Cautions Allowed only following FM_PCD_MatchTableSet().
153731 +*//***************************************************************************/
153732 +
153733 +#if defined(CONFIG_COMPAT)
153734 +#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)
153735 +#endif
153736 +#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)
153737 +
153738 +/**************************************************************************//**
153739 + @Function FM_PCD_HashTableGetMissStatistics
153740 +
153741 + @Description This routine may be used to get statistics counters of 'miss'
153742 + entry of the a hash table.
153743 +
153744 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
153745 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
153746 + these counters reflect how many frames were not matched to any
153747 + existing key and therefore passed through the miss entry;
153748 +
153749 + @Param[in] h_HashTbl A handle to a hash table
153750 + @Param[out] p_MissStatistics Statistics counters for 'miss'
153751 +
153752 + @Return E_OK on success; Error code otherwise.
153753 +
153754 + @Cautions Allowed only following FM_PCD_HashTableSet().
153755 +*//***************************************************************************/
153756 +
153757 +#if defined(CONFIG_COMPAT)
153758 +#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)
153759 +#endif
153760 +#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)
153761 +
153762 +
153763 +/**************************************************************************//**
153764 + @Function FM_PCD_NetEnvCharacteristicsSet
153765 +
153766 + @Description Define a set of Network Environment Characteristics.
153767 +
153768 + When setting an environment it is important to understand its
153769 + application. It is not meant to describe the flows that will run
153770 + on the ports using this environment, but what the user means TO DO
153771 + with the PCD mechanisms in order to parse-classify-distribute those
153772 + frames.
153773 + By specifying a distinction unit, the user means it would use that option
153774 + for distinction between frames at either a KeyGen scheme or a coarse
153775 + classification action descriptor. Using interchangeable headers to define a
153776 + unit means that the user is indifferent to which of the interchangeable
153777 + headers is present in the frame, and wants the distinction to be based
153778 + on the presence of either one of them.
153779 +
153780 + Depending on context, there are limitations to the use of environments. A
153781 + port using the PCD functionality is bound to an environment. Some or even
153782 + all ports may share an environment but also an environment per port is
153783 + possible. When initializing a scheme, a classification plan group (see below),
153784 + or a coarse classification tree, one of the initialized environments must be
153785 + stated and related to. When a port is bound to a scheme, a classification
153786 + plan group, or a coarse classification tree, it MUST be bound to the same
153787 + environment.
153788 +
153789 + The different PCD modules, may relate (for flows definition) ONLY on
153790 + distinction units as defined by their environment. When initializing a
153791 + scheme for example, it may not choose to select IPV4 as a match for
153792 + recognizing flows unless it was defined in the relating environment. In
153793 + fact, to guide the user through the configuration of the PCD, each module's
153794 + characterization in terms of flows is not done using protocol names, but using
153795 + environment indexes.
153796 +
153797 + In terms of HW implementation, the list of distinction units sets the LCV vectors
153798 + and later used for match vector, classification plan vectors and coarse classification
153799 + indexing.
153800 +
153801 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
153802 +
153803 + @Return 0 on success; Error code otherwise.
153804 +*//***************************************************************************/
153805 +#if defined(CONFIG_COMPAT)
153806 +#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)
153807 +#endif
153808 +#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)
153809 +
153810 +/**************************************************************************//**
153811 + @Function FM_PCD_NetEnvCharacteristicsDelete
153812 +
153813 + @Description Deletes a set of Network Environment Charecteristics.
153814 +
153815 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
153816 +
153817 + @Return 0 on success; Error code otherwise.
153818 +*//***************************************************************************/
153819 +#if defined(CONFIG_COMPAT)
153820 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
153821 +#endif
153822 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
153823 +
153824 +/**************************************************************************//**
153825 + @Function FM_PCD_KgSchemeSet
153826 +
153827 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
153828 + This routine should be called for adding or modifying a scheme.
153829 + When a scheme needs modifying, the API requires that it will be
153830 + rewritten. In such a case 'modify' should be TRUE. If the
153831 + routine is called for a valid scheme and 'modify' is FALSE,
153832 + it will return error.
153833 +
153834 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
153835 +
153836 + @Return 0 on success; Error code otherwise.
153837 +*//***************************************************************************/
153838 +#if defined(CONFIG_COMPAT)
153839 +#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)
153840 +#endif
153841 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
153842 +
153843 +/**************************************************************************//**
153844 + @Function FM_PCD_KgSchemeDelete
153845 +
153846 + @Description Deleting an initialized scheme.
153847 +
153848 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
153849 +
153850 + @Return 0 on success; Error code otherwise.
153851 +*//***************************************************************************/
153852 +#if defined(CONFIG_COMPAT)
153853 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
153854 +#endif
153855 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
153856 +
153857 +/**************************************************************************//**
153858 + @Function FM_PCD_CcRootBuild
153859 +
153860 + @Description This routine must be called to define a complete coarse
153861 + classification tree. This is the way to define coarse
153862 + classification to a certain flow - the KeyGen schemes
153863 + may point only to trees defined in this way.
153864 +
153865 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
153866 +
153867 + @Return 0 on success; Error code otherwise.
153868 +*//***************************************************************************/
153869 +#if defined(CONFIG_COMPAT)
153870 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
153871 +#endif
153872 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
153873 +
153874 +/**************************************************************************//**
153875 + @Function FM_PCD_CcRootDelete
153876 +
153877 + @Description Deleting a built tree.
153878 +
153879 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
153880 +*//***************************************************************************/
153881 +#if defined(CONFIG_COMPAT)
153882 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
153883 +#endif
153884 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
153885 +
153886 +/**************************************************************************//**
153887 + @Function FM_PCD_MatchTableSet
153888 +
153889 + @Description This routine should be called for each CC (coarse classification)
153890 + node. The whole CC tree should be built bottom up so that each
153891 + node points to already defined nodes. p_NodeId returns the node
153892 + Id to be used by other nodes.
153893 +
153894 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
153895 +
153896 + @Return 0 on success; Error code otherwise.
153897 +*//***************************************************************************/
153898 +#if defined(CONFIG_COMPAT)
153899 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
153900 +#endif
153901 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
153902 +
153903 +/**************************************************************************//**
153904 + @Function FM_PCD_MatchTableDelete
153905 +
153906 + @Description Deleting a built node.
153907 +
153908 + @Param[in] ioc_fm_obj_t - The id of a CC node.
153909 +
153910 + @Return 0 on success; Error code otherwise.
153911 +*//***************************************************************************/
153912 +#if defined(CONFIG_COMPAT)
153913 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
153914 +#endif
153915 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
153916 +
153917 +/**************************************************************************//**
153918 + @Function FM_PCD_CcRootModifyNextEngine
153919 +
153920 + @Description Modify the Next Engine Parameters in the entry of the tree.
153921 +
153922 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
153923 +
153924 + @Return 0 on success; Error code otherwise.
153925 +
153926 + @Cautions Allowed only following FM_PCD_CcRootBuild().
153927 +*//***************************************************************************/
153928 +#if defined(CONFIG_COMPAT)
153929 +#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)
153930 +#endif
153931 +#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)
153932 +
153933 +/**************************************************************************//**
153934 + @Function FM_PCD_MatchTableModifyNextEngine
153935 +
153936 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
153937 +
153938 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
153939 +
153940 + @Return 0 on success; Error code otherwise.
153941 +
153942 + @Cautions Allowed only following FM_PCD_MatchTableSet().
153943 +*//***************************************************************************/
153944 +#if defined(CONFIG_COMPAT)
153945 +#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)
153946 +#endif
153947 +#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)
153948 +
153949 +/**************************************************************************//**
153950 + @Function FM_PCD_MatchTableModifyMissNextEngine
153951 +
153952 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
153953 +
153954 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
153955 +
153956 + @Return 0 on success; Error code otherwise.
153957 +
153958 + @Cautions Allowed only following FM_PCD_MatchTableSet().
153959 +*//***************************************************************************/
153960 +#if defined(CONFIG_COMPAT)
153961 +#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)
153962 +#endif
153963 +#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)
153964 +
153965 +/**************************************************************************//**
153966 + @Function FM_PCD_MatchTableRemoveKey
153967 +
153968 + @Description Remove the key (including next engine parameters of this key)
153969 + defined by the index of the relevant node.
153970 +
153971 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
153972 +
153973 + @Return 0 on success; Error code otherwise.
153974 +
153975 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
153976 + node and for all of the nodes that lead to it.
153977 +*//***************************************************************************/
153978 +#if defined(CONFIG_COMPAT)
153979 +#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)
153980 +#endif
153981 +#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)
153982 +
153983 +/**************************************************************************//**
153984 + @Function FM_PCD_MatchTableAddKey
153985 +
153986 + @Description Add the key (including next engine parameters of this key in the
153987 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
153988 + may be used when the user doesn't care about the position of the
153989 + key in the table - in that case, the key will be automatically
153990 + added by the driver in the last available entry.
153991 +
153992 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
153993 +
153994 + @Return 0 on success; Error code otherwise.
153995 +
153996 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
153997 + node and for all of the nodes that lead to it.
153998 +*//***************************************************************************/
153999 +#if defined(CONFIG_COMPAT)
154000 +#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)
154001 +#endif
154002 +#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)
154003 +
154004 +/**************************************************************************//**
154005 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
154006 +
154007 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
154008 +
154009 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
154010 +
154011 + @Return 0 on success; Error code otherwise.
154012 +
154013 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
154014 + the node that points to this node
154015 +*//***************************************************************************/
154016 +#if defined(CONFIG_COMPAT)
154017 +#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)
154018 +#endif
154019 +#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)
154020 +
154021 +/**************************************************************************//**
154022 + @Function FM_PCD_MatchTableModifyKey
154023 +
154024 + @Description Modify the key at the index defined by key_index.
154025 +
154026 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
154027 +
154028 + @Return 0 on success; Error code otherwise.
154029 +
154030 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
154031 + node and for all of the nodes that lead to it.
154032 +*//***************************************************************************/
154033 +#if defined(CONFIG_COMPAT)
154034 +#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)
154035 +#endif
154036 +#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)
154037 +
154038 +/**************************************************************************//**
154039 + @Function FM_PCD_HashTableSet
154040 +
154041 + @Description This routine initializes a hash table structure.
154042 + KeyGen hash result determines the hash bucket.
154043 + Next, KeyGen key is compared against all keys of this
154044 + bucket (exact match).
154045 + Number of sets (number of buckets) of the hash equals to the
154046 + number of 1-s in 'hash_res_mask' in the provided parameters.
154047 + Number of hash table ways is then calculated by dividing
154048 + 'max_num_of_keys' equally between the hash sets. This is the maximal
154049 + number of keys that a hash bucket may hold.
154050 + The hash table is initialized empty and keys may be
154051 + added to it following the initialization. Keys masks are not
154052 + supported in current hash table implementation.
154053 + The initialized hash table can be integrated as a node in a
154054 + CC tree.
154055 +
154056 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
154057 +
154058 + @Return 0 on success; Error code otherwise.
154059 +*//***************************************************************************/
154060 +#if defined(CONFIG_COMPAT)
154061 +#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)
154062 +#endif
154063 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
154064 +
154065 +
154066 +/**************************************************************************//**
154067 + @Function FM_PCD_HashTableDelete
154068 +
154069 + @Description This routine deletes the provided hash table and released all
154070 + its allocated resources.
154071 +
154072 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
154073 +
154074 + @Return 0 on success; Error code otherwise.
154075 +
154076 + @Cautions Allowed only following FM_PCD_HashTableSet().
154077 +*//***************************************************************************/
154078 +#if defined(CONFIG_COMPAT)
154079 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
154080 +#endif
154081 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
154082 +
154083 +/**************************************************************************//**
154084 + @Function FM_PCD_HashTableAddKey
154085 +
154086 + @Description This routine adds the provided key (including next engine
154087 + parameters of this key) to the hash table.
154088 + The key is added as the last key of the bucket that it is
154089 + mapped to.
154090 +
154091 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
154092 +
154093 + @Return 0 on success; error code otherwise.
154094 +
154095 + @Cautions Allowed only following FM_PCD_HashTableSet().
154096 +*//***************************************************************************/
154097 +#if defined(CONFIG_COMPAT)
154098 +#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)
154099 +#endif
154100 +#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)
154101 +
154102 +/**************************************************************************//**
154103 + @Function FM_PCD_HashTableRemoveKey
154104 +
154105 + @Description This routine removes the requested key (including next engine
154106 + parameters of this key) from the hash table.
154107 +
154108 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
154109 +
154110 + @Return 0 on success; Error code otherwise.
154111 +
154112 + @Cautions Allowed only following FM_PCD_HashTableSet().
154113 +*//***************************************************************************/
154114 +#if defined(CONFIG_COMPAT)
154115 +#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)
154116 +#endif
154117 +#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)
154118 +
154119 +/**************************************************************************//**
154120 + @Function FM_PCD_PlcrProfileSet
154121 +
154122 + @Description Sets a profile entry in the policer profile table.
154123 + The routine overrides any existing value.
154124 +
154125 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
154126 + policer profile entry.
154127 +
154128 + @Return 0 on success; Error code otherwise.
154129 +*//***************************************************************************/
154130 +#if defined(CONFIG_COMPAT)
154131 +#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)
154132 +#endif
154133 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
154134 +
154135 +/**************************************************************************//**
154136 + @Function FM_PCD_PlcrProfileDelete
154137 +
154138 + @Description Delete a profile entry in the policer profile table.
154139 + The routine set entry to invalid.
154140 +
154141 + @Param[in] ioc_fm_obj_t The id of a policer profile.
154142 +
154143 + @Return 0 on success; Error code otherwise.
154144 +*//***************************************************************************/
154145 +#if defined(CONFIG_COMPAT)
154146 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
154147 +#endif
154148 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
154149 +
154150 +/**************************************************************************//**
154151 + @Function FM_PCD_ManipNodeSet
154152 +
154153 + @Description This routine should be called for defining a manipulation
154154 + node. A manipulation node must be defined before the CC node
154155 + that precedes it.
154156 +
154157 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
154158 +
154159 + @Return A handle to the initialized object on success; NULL code otherwise.
154160 +*//***************************************************************************/
154161 +#if defined(CONFIG_COMPAT)
154162 +#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)
154163 +#endif
154164 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
154165 +
154166 +/**************************************************************************//**
154167 + @Function FM_PCD_ManipNodeReplace
154168 +
154169 + @Description Change existing manipulation node to be according to new requirement.
154170 + (Here, it's implemented as a variant of the same IOCTL as for
154171 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
154172 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
154173 + the manip node's handle)
154174 +
154175 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
154176 +
154177 + @Return 0 on success; error code otherwise.
154178 +
154179 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
154180 +*//***************************************************************************/
154181 +#if defined(CONFIG_COMPAT)
154182 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
154183 +#endif
154184 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
154185 +
154186 +/**************************************************************************//**
154187 + @Function FM_PCD_ManipNodeDelete
154188 +
154189 + @Description Delete an existing manipulation node.
154190 +
154191 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
154192 +
154193 + @Return 0 on success; error code otherwise.
154194 +
154195 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
154196 +*//***************************************************************************/
154197 +#if defined(CONFIG_COMPAT)
154198 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
154199 +#endif
154200 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
154201 +
154202 +/**************************************************************************//**
154203 + @Function FM_PCD_ManipGetStatistics
154204 +
154205 + @Description Retrieve the manipulation statistics.
154206 +
154207 + @Param[in] h_ManipNode A handle to a manipulation node.
154208 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
154209 +
154210 + @Return E_OK on success; Error code otherwise.
154211 +
154212 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
154213 +*//***************************************************************************/
154214 +#if defined(CONFIG_COMPAT)
154215 +#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)
154216 +#endif
154217 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
154218 +
154219 +/**************************************************************************//**
154220 +@Function FM_PCD_SetAdvancedOffloadSupport
154221 +
154222 +@Description This routine must be called in order to support the following features:
154223 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
154224 +
154225 +@Param[in] h_FmPcd FM PCD module descriptor.
154226 +
154227 +@Return 0 on success; error code otherwise.
154228 +
154229 +@Cautions Allowed only when PCD is disabled.
154230 +*//***************************************************************************/
154231 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
154232 +
154233 +#if (DPAA_VERSION >= 11)
154234 +/**************************************************************************//**
154235 + @Function FM_PCD_FrmReplicSetGroup
154236 +
154237 + @Description Initialize a Frame Replicator group.
154238 +
154239 + @Param[in] h_FmPcd FM PCD module descriptor.
154240 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
154241 + the frame replicator group.
154242 +
154243 + @Return A handle to the initialized object on success; NULL code otherwise.
154244 +
154245 + @Cautions Allowed only following FM_PCD_Init().
154246 +*//***************************************************************************/
154247 +#if defined(CONFIG_COMPAT)
154248 +#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)
154249 +#endif
154250 +#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)
154251 +
154252 +/**************************************************************************//**
154253 + @Function FM_PCD_FrmReplicDeleteGroup
154254 +
154255 + @Description Delete a Frame Replicator group.
154256 +
154257 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
154258 +
154259 + @Return E_OK on success; Error code otherwise.
154260 +
154261 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
154262 +*//***************************************************************************/
154263 +#if defined(CONFIG_COMPAT)
154264 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
154265 +#endif
154266 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
154267 +
154268 +/**************************************************************************//**
154269 + @Function FM_PCD_FrmReplicAddMember
154270 +
154271 + @Description Add the member in the index defined by the memberIndex.
154272 +
154273 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
154274 + @Param[in] memberIndex member index for adding.
154275 + @Param[in] p_MemberParams A pointer to the new member parameters.
154276 +
154277 + @Return E_OK on success; Error code otherwise.
154278 +
154279 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
154280 +*//***************************************************************************/
154281 +#if defined(CONFIG_COMPAT)
154282 +#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)
154283 +#endif
154284 +#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)
154285 +
154286 +/**************************************************************************//**
154287 + @Function FM_PCD_FrmReplicRemoveMember
154288 +
154289 + @Description Remove the member defined by the index from the relevant group.
154290 +
154291 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
154292 + @Param[in] memberIndex member index for removing.
154293 +
154294 + @Return E_OK on success; Error code otherwise.
154295 +
154296 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
154297 +*//***************************************************************************/
154298 +#if defined(CONFIG_COMPAT)
154299 +#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)
154300 +#endif
154301 +#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)
154302 +
154303 +#endif
154304 +
154305 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
154306 +/**************************************************************************//**
154307 + @Function FM_PCD_StatisticsSetNode
154308 +
154309 + @Description This routine should be called for defining a statistics node.
154310 +
154311 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
154312 +
154313 + @Return 0 on success; Error code otherwise.
154314 +*//***************************************************************************/
154315 +#if defined(CONFIG_COMPAT)
154316 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
154317 +#endif
154318 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
154319 +
154320 +#endif /* FM_CAPWAP_SUPPORT */
154321 +
154322 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
154323 +#if defined(CONFIG_COMPAT)
154324 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
154325 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
154326 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
154327 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
154328 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
154329 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
154330 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
154331 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
154332 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
154333 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
154334 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
154335 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
154336 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
154337 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
154338 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
154339 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
154340 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
154341 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
154342 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
154343 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
154344 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
154345 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
154346 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
154347 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
154348 +#endif
154349 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
154350 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
154351 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
154352 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
154353 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
154354 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
154355 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
154356 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
154357 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
154358 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
154359 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
154360 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
154361 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
154362 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
154363 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
154364 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
154365 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
154366 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
154367 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
154368 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
154369 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
154370 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
154371 +
154372 +#endif /* __FM_PCD_IOCTLS_H */
154373 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
154374 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
154375 +/** @} */ /* end of lnx_ioctl_FM_grp group */
154376 --- /dev/null
154377 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
154378 @@ -0,0 +1,973 @@
154379 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154380 + * All rights reserved.
154381 + *
154382 + * Redistribution and use in source and binary forms, with or without
154383 + * modification, are permitted provided that the following conditions are met:
154384 + * * Redistributions of source code must retain the above copyright
154385 + * notice, this list of conditions and the following disclaimer.
154386 + * * Redistributions in binary form must reproduce the above copyright
154387 + * notice, this list of conditions and the following disclaimer in the
154388 + * documentation and/or other materials provided with the distribution.
154389 + * * Neither the name of Freescale Semiconductor nor the
154390 + * names of its contributors may be used to endorse or promote products
154391 + * derived from this software without specific prior written permission.
154392 + *
154393 + *
154394 + * ALTERNATIVELY, this software may be distributed under the terms of the
154395 + * GNU General Public License ("GPL") as published by the Free Software
154396 + * Foundation, either version 2 of that License or (at your option) any
154397 + * later version.
154398 + *
154399 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154400 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154401 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154402 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154403 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154404 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154405 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154406 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154407 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154408 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154409 + */
154410 +
154411 +/******************************************************************************
154412 + @File fm_port_ioctls.h
154413 +
154414 + @Description FM Port routines
154415 +*//***************************************************************************/
154416 +#ifndef __FM_PORT_IOCTLS_H
154417 +#define __FM_PORT_IOCTLS_H
154418 +
154419 +#include "enet_ext.h"
154420 +#include "net_ioctls.h"
154421 +#include "fm_ioctls.h"
154422 +#include "fm_pcd_ioctls.h"
154423 +
154424 +
154425 +/**************************************************************************//**
154426 +
154427 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
154428 +
154429 + @Description FM Linux ioctls definitions and enums
154430 +
154431 + @{
154432 +*//***************************************************************************/
154433 +
154434 +/**************************************************************************//**
154435 + @Group lnx_ioctl_FM_PORT_grp FM Port
154436 +
154437 + @Description FM Port API
154438 +
154439 + The FM uses a general module called "port" to represent a Tx port
154440 + (MAC), an Rx port (MAC), offline parsing flow or host command
154441 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
154442 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
154443 + Host command/Offline parsing ports. The SW driver manages these
154444 + ports as sub-modules of the FM, i.e. after an FM is initialized,
154445 + its ports may be initialized and operated upon.
154446 +
154447 + The port is initialized aware of its type, but other functions on
154448 + a port may be indifferent to its type. When necessary, the driver
154449 + verifies coherency and returns error if applicable.
154450 +
154451 + On initialization, user specifies the port type and it's index
154452 + (relative to the port's type). Host command and Offline parsing
154453 + ports share the same id range, I.e user may not initialized host
154454 + command port 0 and offline parsing port 0.
154455 +
154456 + @{
154457 +*//***************************************************************************/
154458 +
154459 +/**************************************************************************//**
154460 + @Description An enum for defining port PCD modes.
154461 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
154462 +
154463 + This enum defines the superset of PCD engines support - i.e. not
154464 + all engines have to be used, but all have to be enabled. The real
154465 + flow of a specific frame depends on the PCD configuration and the
154466 + frame headers and payload.
154467 + Note: the first engine and the first engine after the parser (if
154468 + exists) should be in order, the order is important as it will
154469 + define the flow of the port. However, as for the rest engines
154470 + (the ones that follows), the order is not important anymore as
154471 + it is defined by the PCD graph itself.
154472 +*//***************************************************************************/
154473 +typedef enum ioc_fm_port_pcd_support {
154474 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
154475 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
154476 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
154477 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
154478 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
154479 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
154480 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
154481 + /**< Use all PCD engines */
154482 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
154483 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
154484 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
154485 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
154486 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
154487 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
154488 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
154489 +#endif /* FM_CAPWAP_SUPPORT */
154490 +} ioc_fm_port_pcd_support;
154491 +
154492 +
154493 +/**************************************************************************//**
154494 + @Collection FM Frame error
154495 +*//***************************************************************************/
154496 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
154497 +
154498 +/* @} */
154499 +
154500 +
154501 +/**************************************************************************//**
154502 + @Description An enum for defining Dual Tx rate limiting scale.
154503 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
154504 +*//***************************************************************************/
154505 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
154506 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
154507 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
154508 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
154509 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
154510 +} ioc_fm_port_dual_rate_limiter_scale_down;
154511 +
154512 +/**************************************************************************//**
154513 + @Description A structure for defining Tx rate limiting
154514 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
154515 +*//***************************************************************************/
154516 +typedef struct ioc_fm_port_rate_limit_t {
154517 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
154518 + for offline parsing ports. (note that
154519 + for early chips burst size is
154520 + rounded up to a multiply of 1000 frames).*/
154521 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
154522 + offline parsing ports. Rate limit refers to
154523 + data rate (rather than line rate). */
154524 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
154525 + for some earlier chip revisions */
154526 +} ioc_fm_port_rate_limit_t;
154527 +
154528 +
154529 +
154530 +/**************************************************************************//**
154531 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
154532 +
154533 + @Description FM Port Runtime control unit API functions, definitions and enums.
154534 +
154535 + @{
154536 +*//***************************************************************************/
154537 +
154538 +/**************************************************************************//**
154539 + @Description An enum for defining FM Port counters.
154540 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
154541 +*//***************************************************************************/
154542 +typedef enum ioc_fm_port_counters {
154543 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
154544 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
154545 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
154546 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
154547 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
154548 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
154549 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
154550 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
154551 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
154552 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
154553 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
154554 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
154555 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
154556 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
154557 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
154558 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
154559 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
154560 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
154561 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
154562 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
154563 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
154564 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
154565 +} ioc_fm_port_counters;
154566 +
154567 +typedef struct ioc_fm_port_bmi_stats_t {
154568 + uint32_t cnt_cycle;
154569 + uint32_t cnt_task_util;
154570 + uint32_t cnt_queue_util;
154571 + uint32_t cnt_dma_util;
154572 + uint32_t cnt_fifo_util;
154573 + uint32_t cnt_rx_pause_activation;
154574 + uint32_t cnt_frame;
154575 + uint32_t cnt_discard_frame;
154576 + uint32_t cnt_dealloc_buf;
154577 + uint32_t cnt_rx_bad_frame;
154578 + uint32_t cnt_rx_large_frame;
154579 + uint32_t cnt_rx_filter_frame;
154580 + uint32_t cnt_rx_list_dma_err;
154581 + uint32_t cnt_rx_out_of_buffers_discard;
154582 + uint32_t cnt_wred_discard;
154583 + uint32_t cnt_length_err;
154584 + uint32_t cnt_unsupported_format;
154585 +} ioc_fm_port_bmi_stats_t;
154586 +
154587 +/**************************************************************************//**
154588 + @Description Structure for Port id parameters.
154589 + (Description may be inaccurate;
154590 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
154591 +
154592 + Fields commented 'IN' are passed by the port module to be used
154593 + by the FM module.
154594 + Fields commented 'OUT' will be filled by FM before returning to port.
154595 +*//***************************************************************************/
154596 +typedef struct ioc_fm_port_congestion_groups_t {
154597 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
154598 + to define the size of the following array */
154599 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
154600 + /**< An array of CG indexes;
154601 + Note that the size of the array should be
154602 + 'num_of_congestion_grps_to_consider'. */
154603 +#if DPAA_VERSION >= 11
154604 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
154605 + /**< A matrix that represents the map between the CG ids
154606 + defined in 'congestion_grps_to_consider' to the priorities
154607 + mapping array. */
154608 +#endif /* DPAA_VERSION >= 11 */
154609 +} ioc_fm_port_congestion_groups_t;
154610 +
154611 +
154612 +
154613 +/**************************************************************************//**
154614 + @Function FM_PORT_Disable
154615 +
154616 + @Description Gracefully disable an FM port. The port will not start new tasks after all
154617 + tasks associated with the port are terminated.
154618 +
154619 + @Return 0 on success; error code otherwise.
154620 +
154621 + @Cautions This is a blocking routine, it returns after port is
154622 + gracefully stopped, i.e. the port will not except new frames,
154623 + but it will finish all frames or tasks which were already began
154624 +*//***************************************************************************/
154625 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
154626 +
154627 +/**************************************************************************//**
154628 + @Function FM_PORT_Enable
154629 +
154630 + @Description A runtime routine provided to allow disable/enable of port.
154631 +
154632 + @Return 0 on success; error code otherwise.
154633 +*//***************************************************************************/
154634 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
154635 +
154636 +/**************************************************************************//**
154637 + @Function FM_PORT_SetRateLimit
154638 +
154639 + @Description Calling this routine enables rate limit algorithm.
154640 + By default, this functionality is disabled.
154641 + Note that rate-limit mechanism uses the FM time stamp.
154642 + The selected rate limit specified here would be
154643 + rounded DOWN to the nearest 16M.
154644 +
154645 + May be used for Tx and offline parsing ports only
154646 +
154647 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
154648 +
154649 + @Return 0 on success; error code otherwise.
154650 +*//***************************************************************************/
154651 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
154652 +
154653 +/**************************************************************************//**
154654 + @Function FM_PORT_DeleteRateLimit
154655 +
154656 + @Description Calling this routine disables the previously enabled rate limit.
154657 +
154658 + May be used for Tx and offline parsing ports only
154659 +
154660 + @Return 0 on success; error code otherwise.
154661 +*//***************************************************************************/
154662 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
154663 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
154664 +
154665 +
154666 +/**************************************************************************//**
154667 + @Function FM_PORT_AddCongestionGrps
154668 +
154669 + @Description This routine effects the corresponding Tx port.
154670 + It should be called in order to enable pause
154671 + frame transmission in case of congestion in one or more
154672 + of the congestion groups relevant to this port.
154673 + Each call to this routine may add one or more congestion
154674 + groups to be considered relevant to this port.
154675 +
154676 + May be used for Rx, or RX+OP ports only (depending on chip)
154677 +
154678 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
154679 + congestion group ids to consider.
154680 +
154681 + @Return 0 on success; error code otherwise.
154682 +*//***************************************************************************/
154683 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
154684 +
154685 +/**************************************************************************//**
154686 + @Function FM_PORT_RemoveCongestionGrps
154687 +
154688 + @Description This routine effects the corresponding Tx port. It should be
154689 + called when congestion groups were
154690 + defined for this port and are no longer relevant, or pause
154691 + frames transmitting is not required on their behalf.
154692 + Each call to this routine may remove one or more congestion
154693 + groups to be considered relevant to this port.
154694 +
154695 + May be used for Rx, or RX+OP ports only (depending on chip)
154696 +
154697 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
154698 + congestion group ids to consider.
154699 +
154700 + @Return 0 on success; error code otherwise.
154701 +*//***************************************************************************/
154702 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
154703 +
154704 +/**************************************************************************//**
154705 + @Function FM_PORT_SetErrorsRoute
154706 +
154707 + @Description Errors selected for this routine will cause a frame with that error
154708 + to be enqueued to error queue.
154709 + Errors not selected for this routine will cause a frame with that error
154710 + to be enqueued to the one of the other port queues.
154711 + By default all errors are defined to be enqueued to error queue.
154712 + Errors that were configured to be discarded (at initialization)
154713 + may not be selected here.
154714 +
154715 + May be used for Rx and offline parsing ports only
154716 +
154717 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
154718 +
154719 + @Return 0 on success; error code otherwise.
154720 +
154721 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
154722 + (szbs001: How is it possible to have one function that needs to be
154723 + called BEFORE FM_PORT_Init() implemented as an ioctl,
154724 + which will ALWAYS be called AFTER the FM_PORT_Init()
154725 + for that port!?!?!?!???!?!??!?!?)
154726 +*//***************************************************************************/
154727 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
154728 +
154729 +
154730 +/**************************************************************************//**
154731 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
154732 +
154733 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
154734 +
154735 + @{
154736 +*//***************************************************************************/
154737 +
154738 +/**************************************************************************//**
154739 + @Description A structure defining the KG scheme after the parser.
154740 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
154741 +
154742 + This is relevant only to change scheme selection mode - from
154743 + direct to indirect and vice versa, or when the scheme is selected directly,
154744 + to select the scheme id.
154745 +
154746 +*//***************************************************************************/
154747 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
154748 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
154749 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
154750 + 'scheme_id' selects the scheme after parser. */
154751 +} ioc_fm_pcd_kg_scheme_select_t;
154752 +
154753 +/**************************************************************************//**
154754 + @Description Scheme IDs structure
154755 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
154756 +*//***************************************************************************/
154757 +typedef struct ioc_fm_pcd_port_schemes_params_t {
154758 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
154759 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
154760 + port to be bound to */
154761 +} ioc_fm_pcd_port_schemes_params_t;
154762 +
154763 +/**************************************************************************//**
154764 + @Description A union for defining port protocol parameters for parser
154765 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
154766 +*//***************************************************************************/
154767 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
154768 + /* MPLS */
154769 + struct {
154770 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
154771 + interpreted as described in HW spec table. When the bit
154772 + is cleared, the parser will advance to MPLS next parse */
154773 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
154774 + } mpls_prs_options;
154775 +
154776 + /* VLAN */
154777 + struct {
154778 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
154779 + on VLAN TAG on top of 0x8100 and 0x88A8 */
154780 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
154781 + on VLAN TAG on top of 0x8100 and 0x88A8 */
154782 + } vlan_prs_options;
154783 +
154784 + /* PPP */
154785 + struct{
154786 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
154787 + } pppoe_prs_options;
154788 +
154789 + /* IPV6 */
154790 + struct {
154791 + bool routing_hdr_disable; /**< Disable routing header */
154792 + } ipv6_prs_options;
154793 +
154794 + /* UDP */
154795 + struct {
154796 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
154797 + } udp_prs_options;
154798 +
154799 + /* TCP */
154800 + struct {
154801 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
154802 + } tcp_prs_options;
154803 +} ioc_fm_pcd_hdr_prs_opts_u;
154804 +
154805 +/**************************************************************************//**
154806 + @Description A structure for defining each header for the parser
154807 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
154808 +*//***************************************************************************/
154809 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
154810 + ioc_net_header_type hdr; /**< Selected header */
154811 + bool err_disable; /**< TRUE to disable error indication */
154812 + bool soft_prs_enable; /**< Enable jump to SW parser when this
154813 + header is recognized by the HW parser. */
154814 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
154815 + attachments exists for the same header,
154816 + (in the main sw parser code) use this
154817 + index to distinguish between them. */
154818 + bool use_prs_opts; /**< TRUE to use parser options. */
154819 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
154820 + defining the parser options selected.*/
154821 +} ioc_fm_pcd_prs_additional_hdr_params_t;
154822 +
154823 +/**************************************************************************//**
154824 + @Description A structure for defining port PCD parameters
154825 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
154826 +*//***************************************************************************/
154827 +typedef struct ioc_fm_port_pcd_prs_params_t {
154828 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
154829 + port information into the parser result. This information
154830 + may be extracted by KeyGen and be used for frames
154831 + distribution when a per-port distinction is required,
154832 + it may also be used as a port logical id for analyzing
154833 + incoming frames. */
154834 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
154835 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
154836 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
154837 + uint8_t num_of_hdrs_with_additional_params;
154838 + /**< Normally 0, some headers may get special parameters */
154839 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
154840 + /**< 'num_of_hdrs_with_additional_params' structures
154841 + additional parameters for each header that requires them */
154842 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
154843 + indicate a VLAN tag (in addition to the TPID values
154844 + 0x8100 and 0x88A8). */
154845 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
154846 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
154847 + indicate a VLAN tag (in addition to the TPID values
154848 + 0x8100 and 0x88A8). */
154849 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
154850 +} ioc_fm_port_pcd_prs_params_t;
154851 +
154852 +/**************************************************************************//**
154853 + @Description A structure for defining coarse alassification parameters
154854 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
154855 +*//***************************************************************************/
154856 +typedef struct ioc_fm_port_pcd_cc_params_t {
154857 + void *cc_tree_id; /**< CC tree id */
154858 +} ioc_fm_port_pcd_cc_params_t;
154859 +
154860 +/**************************************************************************//**
154861 + @Description A structure for defining keygen parameters
154862 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
154863 +*//***************************************************************************/
154864 +typedef struct ioc_fm_port_pcd_kg_params_t {
154865 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
154866 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
154867 + /**< Array of 'num_of_schemes' schemes for the
154868 + port to be bound to */
154869 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
154870 + regardless of parser result */
154871 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
154872 + relevant only if direct=TRUE. */
154873 +} ioc_fm_port_pcd_kg_params_t;
154874 +
154875 +/**************************************************************************//**
154876 + @Description A structure for defining policer parameters
154877 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
154878 +*//***************************************************************************/
154879 +typedef struct ioc_fm_port_pcd_plcr_params_t {
154880 + void *plcr_profile_id; /**< Selected profile handle;
154881 + relevant in one of the following cases:
154882 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
154883 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
154884 + or if any flow uses a KG scheme where policer
154885 + profile is not generated (bypass_plcr_profile_generation selected) */
154886 +} ioc_fm_port_pcd_plcr_params_t;
154887 +
154888 +/**************************************************************************//**
154889 + @Description A structure for defining port PCD parameters
154890 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
154891 +*//***************************************************************************/
154892 +typedef struct ioc_fm_port_pcd_params_t {
154893 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
154894 + Describes the active PCD engines for this port. */
154895 + void *net_env_id; /**< HL Unused in PLCR only mode */
154896 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
154897 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
154898 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
154899 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
154900 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
154901 +#if (DPAA_VERSION >= 11)
154902 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
154903 +#endif /* (DPAA_VERSION >= 11) */
154904 +} ioc_fm_port_pcd_params_t;
154905 +
154906 +/**************************************************************************//**
154907 + @Description A structure for defining the Parser starting point
154908 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
154909 +*//***************************************************************************/
154910 +typedef struct ioc_fm_pcd_prs_start_t {
154911 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
154912 + start parsing */
154913 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
154914 + 'parsing_offset' */
154915 +} ioc_fm_pcd_prs_start_t;
154916 +
154917 +
154918 +/**************************************************************************//**
154919 + @Description FQID parameters structure
154920 +*//***************************************************************************/
154921 +typedef struct ioc_fm_port_pcd_fqids_params_t {
154922 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
154923 + uint8_t alignment; /**< Alignment required for this port */
154924 + uint32_t base_fqid; /**< output parameter - the base fqid */
154925 +} ioc_fm_port_pcd_fqids_params_t;
154926 +
154927 +
154928 +/**************************************************************************//**
154929 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
154930 +
154931 + @Description Allocates FQID's
154932 +
154933 + May be used for Rx and offline parsing ports only
154934 +
154935 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
154936 +
154937 + @Return 0 on success; error code otherwise.
154938 +*//***************************************************************************/
154939 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
154940 +
154941 +/**************************************************************************//**
154942 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
154943 +
154944 + @Description Frees previously-allocated FQIDs
154945 +
154946 + May be used for Rx and offline parsing ports only
154947 +
154948 + @Param[in] uint32_t Base FQID of previously allocated range.
154949 +
154950 + @Return 0 on success; error code otherwise.
154951 +*//***************************************************************************/
154952 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
154953 +
154954 +
154955 +/**************************************************************************//**
154956 + @Function FM_PORT_SetPCD
154957 +
154958 + @Description Calling this routine defines the port's PCD configuration.
154959 + It changes it from its default configuration which is PCD
154960 + disabled (BMI to BMI) and configures it according to the passed
154961 + parameters.
154962 +
154963 + May be used for Rx and offline parsing ports only
154964 +
154965 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
154966 + configuration.
154967 +
154968 + @Return 0 on success; error code otherwise.
154969 +*//***************************************************************************/
154970 +#if defined(CONFIG_COMPAT)
154971 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
154972 +#endif
154973 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
154974 +
154975 +/**************************************************************************//**
154976 + @Function FM_PORT_DeletePCD
154977 +
154978 + @Description Calling this routine releases the port's PCD configuration.
154979 + The port returns to its default configuration which is PCD
154980 + disabled (BMI to BMI) and all PCD configuration is removed.
154981 +
154982 + May be used for Rx and offline parsing ports which are
154983 + in PCD mode only
154984 +
154985 + @Return 0 on success; error code otherwise.
154986 +*//***************************************************************************/
154987 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
154988 +
154989 +/**************************************************************************//**
154990 + @Function FM_PORT_AttachPCD
154991 +
154992 + @Description This routine may be called after FM_PORT_DetachPCD was called,
154993 + to return to the originally configured PCD support flow.
154994 + The couple of routines are used to allow PCD configuration changes
154995 + that demand that PCD will not be used while changes take place.
154996 +
154997 + May be used for Rx and offline parsing ports which are
154998 + in PCD mode only
154999 +
155000 + @Return 0 on success; error code otherwise.
155001 +*//***************************************************************************/
155002 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
155003 +
155004 +/**************************************************************************//**
155005 + @Function FM_PORT_DetachPCD
155006 +
155007 + @Description Calling this routine detaches the port from its PCD functionality.
155008 + The port returns to its default flow which is BMI to BMI.
155009 +
155010 + May be used for Rx and offline parsing ports which are
155011 + in PCD mode only
155012 +
155013 + @Return 0 on success; error code otherwise.
155014 +*//***************************************************************************/
155015 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
155016 +
155017 +/**************************************************************************//**
155018 + @Function FM_PORT_PcdPlcrAllocProfiles
155019 +
155020 + @Description This routine may be called only for ports that use the Policer in
155021 + order to allocate private policer profiles.
155022 +
155023 + @Param[in] uint16_t The number of required policer profiles
155024 +
155025 + @Return 0 on success; error code otherwise.
155026 +
155027 + @Cautions Allowed before FM_PORT_SetPCD() only.
155028 +*//***************************************************************************/
155029 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
155030 +
155031 +/**************************************************************************//**
155032 + @Function FM_PORT_PcdPlcrFreeProfiles
155033 +
155034 + @Description This routine should be called for freeing private policer profiles.
155035 +
155036 + @Return 0 on success; error code otherwise.
155037 +
155038 + @Cautions Allowed before FM_PORT_SetPCD() only.
155039 +*//***************************************************************************/
155040 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
155041 +
155042 +/**************************************************************************//**
155043 + @Function FM_PORT_PcdKgModifyInitialScheme
155044 +
155045 + @Description This routine may be called only for ports that use the keygen in
155046 + order to change the initial scheme frame should be routed to.
155047 + The change may be of a scheme id (in case of direct mode),
155048 + from direct to indirect, or from indirect to direct - specifying the scheme id.
155049 +
155050 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
155051 + a scheme is direct/indirect, and if direct - scheme id.
155052 +
155053 + @Return 0 on success; error code otherwise.
155054 +*//***************************************************************************/
155055 +#if defined(CONFIG_COMPAT)
155056 +#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)
155057 +#endif
155058 +#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)
155059 +
155060 +/**************************************************************************//**
155061 + @Function FM_PORT_PcdPlcrModifyInitialProfile
155062 +
155063 + @Description This routine may be called for ports with flows
155064 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
155065 + to change the initial Policer profile frame should be routed to.
155066 + The change may be of a profile and/or absolute/direct mode selection.
155067 +
155068 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
155069 +
155070 + @Return 0 on success; error code otherwise.
155071 +*//***************************************************************************/
155072 +#if defined(CONFIG_COMPAT)
155073 +#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)
155074 +#endif
155075 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
155076 +
155077 +/**************************************************************************//**
155078 + @Function FM_PORT_PcdCcModifyTree
155079 +
155080 + @Description This routine may be called to change this port connection to
155081 + a pre-initializes coarse classification Tree.
155082 +
155083 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
155084 +
155085 + @Return 0 on success; error code otherwise.
155086 +
155087 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
155088 +*//***************************************************************************/
155089 +#if defined(CONFIG_COMPAT)
155090 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
155091 +#endif
155092 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
155093 +
155094 +/**************************************************************************//**
155095 + @Function FM_PORT_PcdKgBindSchemes
155096 +
155097 + @Description These routines may be called for modifying the binding of ports
155098 + to schemes. The scheme itself is not added,
155099 + just this specific port starts using it.
155100 +
155101 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
155102 +
155103 + @Return 0 on success; error code otherwise.
155104 +
155105 + @Cautions Allowed only following FM_PORT_SetPCD().
155106 +*//***************************************************************************/
155107 +#if defined(CONFIG_COMPAT)
155108 +#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)
155109 +#endif
155110 +#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)
155111 +
155112 +/**************************************************************************//**
155113 + @Function FM_PORT_PcdKgUnbindSchemes
155114 +
155115 + @Description These routines may be called for modifying the binding of ports
155116 + to schemes. The scheme itself is not removed or invalidated,
155117 + just this specific port stops using it.
155118 +
155119 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
155120 +
155121 + @Return 0 on success; error code otherwise.
155122 +
155123 + @Cautions Allowed only following FM_PORT_SetPCD().
155124 +*//***************************************************************************/
155125 +#if defined(CONFIG_COMPAT)
155126 +#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)
155127 +#endif
155128 +#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)
155129 +
155130 +typedef struct ioc_fm_port_mac_addr_params_t {
155131 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
155132 +} ioc_fm_port_mac_addr_params_t;
155133 +
155134 +/**************************************************************************//**
155135 + @Function FM_MAC_AddHashMacAddr
155136 +
155137 + @Description Add an Address to the hash table. This is for filter purpose only.
155138 +
155139 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
155140 +
155141 + @Return E_OK on success; Error code otherwise.
155142 +
155143 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
155144 + @Cautions Some address need to be filtered out in upper FM blocks.
155145 +*//***************************************************************************/
155146 +#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)
155147 +
155148 +/**************************************************************************//**
155149 + @Function FM_MAC_RemoveHashMacAddr
155150 +
155151 + @Description Delete an Address to the hash table. This is for filter purpose only.
155152 +
155153 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
155154 +
155155 + @Return E_OK on success; Error code otherwise.
155156 +
155157 + @Cautions Allowed only following FM_MAC_Init().
155158 +*//***************************************************************************/
155159 +#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)
155160 +
155161 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
155162 + uint8_t priority;
155163 + uint16_t pause_time;
155164 + uint16_t thresh_time;
155165 +} ioc_fm_port_tx_pause_frames_params_t;
155166 +
155167 +/**************************************************************************//**
155168 + @Function FM_MAC_SetTxPauseFrames
155169 +
155170 + @Description Enable/Disable transmission of Pause-Frames.
155171 + The routine changes the default configuration:
155172 + pause-time - [0xf000]
155173 + threshold-time - [0]
155174 +
155175 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
155176 +
155177 + @Return E_OK on success; Error code otherwise.
155178 +
155179 + @Cautions Allowed only following FM_MAC_Init().
155180 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
155181 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
155182 + in the 'priority' field.
155183 +*//***************************************************************************/
155184 +#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)
155185 +
155186 +typedef struct ioc_fm_port_mac_statistics_t {
155187 + /* RMON */
155188 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
155189 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
155190 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
155191 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
155192 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
155193 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
155194 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
155195 + /* */
155196 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
155197 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
155198 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
155199 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
155200 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
155201 + This count does not include range length errors */
155202 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
155203 + a valid FCS and otherwise well formed */
155204 + /* Pause */
155205 + uint64_t te_stat_pause; /**< Pause MAC Control received */
155206 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
155207 + /* MIB II */
155208 + uint64_t if_in_octets; /**< Total number of byte received. */
155209 + uint64_t if_in_pkts; /**< Total number of packets received.*/
155210 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
155211 + NOTE: this counter is not supported on dTSEC MAC */
155212 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
155213 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
155214 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
155215 + uint64_t if_in_errors; /**< Number of frames received with error:
155216 + - FIFO Overflow Error
155217 + - CRC Error
155218 + - Frame Too Long Error
155219 + - Alignment Error
155220 + - The dedicated Error Code (0xfe, not a code error) was received */
155221 + uint64_t if_out_octets; /**< Total number of byte sent. */
155222 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
155223 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
155224 + NOTE: this counter is not supported on dTSEC MAC */
155225 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
155226 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
155227 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
155228 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
155229 + - FIFO Overflow Error
155230 + - FIFO Underflow Error
155231 + - Other */
155232 +} ioc_fm_port_mac_statistics_t;
155233 +
155234 +/**************************************************************************//**
155235 + @Function FM_MAC_GetStatistics
155236 +
155237 + @Description get all MAC statistics counters
155238 +
155239 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
155240 +
155241 + @Return E_OK on success; Error code otherwise.
155242 +
155243 + @Cautions Allowed only following FM_Init().
155244 +*//***************************************************************************/
155245 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
155246 +
155247 +/**************************************************************************//**
155248 + @Function FM_PORT_ConfigBufferPrefixContent
155249 +
155250 + @Description Defines the structure, size and content of the application buffer.
155251 + The prefix will
155252 + In Tx ports, if 'passPrsResult', the application
155253 + should set a value to their offsets in the prefix of
155254 + the FM will save the first 'privDataSize', than,
155255 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
155256 + and timeStamp, and the packet itself (in this order), to the
155257 + application buffer, and to offset.
155258 + Calling this routine changes the buffer margins definitions
155259 + in the internal driver data base from its default
155260 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
155261 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
155262 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
155263 +
155264 + May be used for all ports
155265 +
155266 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
155267 +
155268 + @Return E_OK on success; Error code otherwise.
155269 +
155270 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
155271 +*//***************************************************************************/
155272 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
155273 +
155274 +#if (DPAA_VERSION >= 11)
155275 +typedef struct ioc_fm_port_vsp_alloc_params_t {
155276 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
155277 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
155278 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
155279 + if relevant function called for Rx port */
155280 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
155281 +}ioc_fm_port_vsp_alloc_params_t;
155282 +
155283 +/**************************************************************************//**
155284 + @Function FM_PORT_VSPAlloc
155285 +
155286 + @Description This routine allocated VSPs per port and forces the port to work
155287 + in VSP mode. Note that the port is initialized by default with the
155288 + physical-storage-profile only.
155289 +
155290 + @Param[in] h_FmPort A handle to a FM Port module.
155291 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
155292 +
155293 + @Return E_OK on success; Error code otherwise.
155294 +
155295 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
155296 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
155297 +*//***************************************************************************/
155298 +#if defined(CONFIG_COMPAT)
155299 +#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)
155300 +#endif
155301 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
155302 +#endif /* (DPAA_VERSION >= 11) */
155303 +
155304 +/**************************************************************************//**
155305 + @Function FM_PORT_GetBmiCounters
155306 +
155307 + @Description Read port's BMI stat counters and place them into
155308 + a designated structure of counters.
155309 +
155310 + @Param[in] h_FmPort A handle to a FM Port module.
155311 + @Param[out] p_BmiStats counters structure
155312 +
155313 + @Return E_OK on success; Error code otherwise.
155314 +
155315 + @Cautions Allowed only following FM_PORT_Init().
155316 +*//***************************************************************************/
155317 +
155318 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
155319 +
155320 +typedef struct ioc_fm_port_mac_frame_size_counters_t {
155321 +
155322 + e_CommMode type;
155323 + uint64_t count_pkts_64; /**< 64 byte frame counter */
155324 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
155325 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
155326 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
155327 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
155328 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
155329 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
155330 +} ioc_fm_port_mac_frame_size_counters_t;
155331 +
155332 +/**************************************************************************//**
155333 + @Function FM_MAC_GetFrameSizeCounters
155334 +
155335 + @Description get MAC statistics counters for different frame size
155336 +
155337 + @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters
155338 +
155339 + @Return E_OK on success; Error code otherwise.
155340 +
155341 + @Cautions Allowed only following FM_Init().
155342 +*//***************************************************************************/
155343 +#define FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(43), ioc_fm_port_mac_frame_size_counters_t)
155344 +
155345 +
155346 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
155347 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
155348 +
155349 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
155350 +/** @} */ /* end of lnx_ioctl_FM_grp group */
155351 +#endif /* __FM_PORT_IOCTLS_H */
155352 --- /dev/null
155353 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
155354 @@ -0,0 +1,208 @@
155355 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
155356 + * All rights reserved.
155357 + *
155358 + * Redistribution and use in source and binary forms, with or without
155359 + * modification, are permitted provided that the following conditions are met:
155360 + * * Redistributions of source code must retain the above copyright
155361 + * notice, this list of conditions and the following disclaimer.
155362 + * * Redistributions in binary form must reproduce the above copyright
155363 + * notice, this list of conditions and the following disclaimer in the
155364 + * documentation and/or other materials provided with the distribution.
155365 + * * Neither the name of Freescale Semiconductor nor the
155366 + * names of its contributors may be used to endorse or promote products
155367 + * derived from this software without specific prior written permission.
155368 + *
155369 + *
155370 + * ALTERNATIVELY, this software may be distributed under the terms of the
155371 + * GNU General Public License ("GPL") as published by the Free Software
155372 + * Foundation, either version 2 of that License or (at your option) any
155373 + * later version.
155374 + *
155375 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
155376 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155377 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155378 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
155379 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
155380 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
155381 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
155382 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
155383 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
155384 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155385 + */
155386 +
155387 +/**************************************************************************//**
155388 + @File fm_test_ioctls.h
155389 +
155390 + @Description FM Char device ioctls
155391 +*//***************************************************************************/
155392 +#ifndef __FM_TEST_IOCTLS_H
155393 +#define __FM_TEST_IOCTLS_H
155394 +
155395 +#include "ioctls.h"
155396 +
155397 +
155398 +/**************************************************************************//**
155399 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
155400 +
155401 + @Description FM-Test Linux ioctls definitions and enums
155402 +
155403 + @{
155404 +*//***************************************************************************/
155405 +
155406 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
155407 +
155408 +/**************************************************************************//**
155409 + @Collection TEST Parameters
155410 +*//***************************************************************************/
155411 +/**************************************************************************//**
155412 + @Description: Name of the FM-Test chardev
155413 +*//***************************************************************************/
155414 +#define DEV_FM_TEST_NAME "fm-test-port"
155415 +
155416 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
155417 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
155418 +
155419 +#define FMT_PORT_IOC_NUM(n) n
155420 +/* @} */
155421 +
155422 +/**************************************************************************//**
155423 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
155424 +
155425 + @Description TODO
155426 +
155427 + @{
155428 +*//***************************************************************************/
155429 +
155430 +/**************************************************************************//**
155431 + @Description TODO
155432 +*//***************************************************************************/
155433 +typedef uint8_t ioc_fmt_xxx_t;
155434 +
155435 +#define FM_PRS_MAX 32
155436 +#define FM_TIME_STAMP_MAX 8
155437 +
155438 +/**************************************************************************//**
155439 + @Description FM Port buffer content description
155440 +*//***************************************************************************/
155441 +typedef struct ioc_fmt_buff_context_t {
155442 + void *p_user_priv;
155443 + uint8_t fm_prs_res[FM_PRS_MAX];
155444 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
155445 +} ioc_fmt_buff_context_t;
155446 +
155447 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
155448 +typedef struct ioc_fmt_compat_buff_context_t {
155449 + compat_uptr_t p_user_priv;
155450 + uint8_t fm_prs_res[FM_PRS_MAX];
155451 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
155452 +} ioc_fmt_compat_buff_context_t;
155453 +#endif
155454 +
155455 +/**************************************************************************//**
155456 + @Description Buffer descriptor
155457 +*//***************************************************************************/
155458 +typedef struct ioc_fmt_buff_desc_t {
155459 + uint32_t qid;
155460 + void *p_data;
155461 + uint32_t size;
155462 + uint32_t status;
155463 + ioc_fmt_buff_context_t buff_context;
155464 +} ioc_fmt_buff_desc_t;
155465 +
155466 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
155467 +typedef struct ioc_fmt_compat_buff_desc_t {
155468 + uint32_t qid;
155469 + compat_uptr_t p_data;
155470 + uint32_t size;
155471 + uint32_t status;
155472 + ioc_fmt_compat_buff_context_t buff_context;
155473 +} ioc_fmt_compat_buff_desc_t;
155474 +#endif
155475 +
155476 +/**************************************************************************//**
155477 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
155478 +
155479 + @Description TODO
155480 + @{
155481 +*//***************************************************************************/
155482 +
155483 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
155484 +
155485 +
155486 +/**************************************************************************//**
155487 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
155488 +
155489 + @Description TODO
155490 +
155491 + @{
155492 +*//***************************************************************************/
155493 +
155494 +/**************************************************************************//**
155495 + @Description FM-Test FM port type
155496 +*//***************************************************************************/
155497 +typedef enum ioc_fmt_port_type {
155498 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
155499 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
155500 +} ioc_fmt_port_type;
155501 +
155502 +/**************************************************************************//**
155503 + @Description TODO
155504 +*//***************************************************************************/
155505 +typedef struct ioc_fmt_port_param_t {
155506 + uint8_t fm_id;
155507 + ioc_fmt_port_type fm_port_type;
155508 + uint8_t fm_port_id;
155509 + uint32_t num_tx_queues;
155510 +} ioc_fmt_port_param_t;
155511 +
155512 +
155513 +/**************************************************************************//**
155514 + @Function FMT_PORT_IOC_INIT
155515 +
155516 + @Description TODO
155517 +
155518 + @Param[in] ioc_fmt_port_param_t TODO
155519 +
155520 + @Cautions Allowed only after the FM equivalent port is already initialized.
155521 +*//***************************************************************************/
155522 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
155523 +
155524 +/**************************************************************************//**
155525 + @Function FMT_PORT_IOC_SET_DIAG_MODE
155526 +
155527 + @Description TODO
155528 +
155529 + @Param[in] ioc_diag_mode TODO
155530 +
155531 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
155532 +*//***************************************************************************/
155533 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
155534 +
155535 +/**************************************************************************//**
155536 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
155537 +
155538 + @Description Set IP header manipulations for this port.
155539 +
155540 + @Param[in] int 1 to enable; 0 to disable
155541 +
155542 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
155543 +*//***************************************************************************/
155544 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
155545 +
155546 +/**************************************************************************//**
155547 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
155548 +
155549 + @Description Set DPA in echo mode - all frame are sent back.
155550 +
155551 + @Param[in] int 1 to enable; 0 to disable
155552 +
155553 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
155554 +*//***************************************************************************/
155555 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
155556 +
155557 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
155558 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
155559 +/** @} */ /* end of lnx_ioctl_FMT_grp */
155560 +
155561 +
155562 +#endif /* __FM_TEST_IOCTLS_H */
155563 --- /dev/null
155564 +++ b/include/uapi/linux/fmd/integrations/Kbuild
155565 @@ -0,0 +1 @@
155566 +header-y += integration_ioctls.h
155567 --- /dev/null
155568 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
155569 @@ -0,0 +1,56 @@
155570 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
155571 + * All rights reserved.
155572 + *
155573 + * Redistribution and use in source and binary forms, with or without
155574 + * modification, are permitted provided that the following conditions are met:
155575 + * * Redistributions of source code must retain the above copyright
155576 + * notice, this list of conditions and the following disclaimer.
155577 + * * Redistributions in binary form must reproduce the above copyright
155578 + * notice, this list of conditions and the following disclaimer in the
155579 + * documentation and/or other materials provided with the distribution.
155580 + * * Neither the name of Freescale Semiconductor nor the
155581 + * names of its contributors may be used to endorse or promote products
155582 + * derived from this software without specific prior written permission.
155583 + *
155584 + *
155585 + * ALTERNATIVELY, this software may be distributed under the terms of the
155586 + * GNU General Public License ("GPL") as published by the Free Software
155587 + * Foundation, either version 2 of that License or (at your option) any
155588 + * later version.
155589 + *
155590 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
155591 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155592 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155593 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
155594 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
155595 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
155596 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
155597 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
155598 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
155599 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155600 + */
155601 +
155602 +/**************************************************************************//**
155603 + @File integration_ioctls.h
155604 +
155605 + @Description External header file for Integration unit routines.
155606 +*//***************************************************************************/
155607 +
155608 +#ifndef __INTG_IOCTLS_H
155609 +#define __INTG_IOCTLS_H
155610 +
155611 +
155612 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
155613 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
155614 +
155615 +/*#define FM_IOCTL_DBG*/
155616 +
155617 +#if defined(FM_IOCTL_DBG)
155618 + #define _fm_ioctl_dbg(format, arg...) \
155619 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
155620 + __func__, __LINE__, smp_processor_id(), ##arg)
155621 +#else
155622 +# define _fm_ioctl_dbg(arg...)
155623 +#endif
155624 +
155625 +#endif /* __INTG_IOCTLS_H */
155626 --- /dev/null
155627 +++ b/include/uapi/linux/fmd/ioctls.h
155628 @@ -0,0 +1,96 @@
155629 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
155630 + * All rights reserved.
155631 + *
155632 + * Redistribution and use in source and binary forms, with or without
155633 + * modification, are permitted provided that the following conditions are met:
155634 + * * Redistributions of source code must retain the above copyright
155635 + * notice, this list of conditions and the following disclaimer.
155636 + * * Redistributions in binary form must reproduce the above copyright
155637 + * notice, this list of conditions and the following disclaimer in the
155638 + * documentation and/or other materials provided with the distribution.
155639 + * * Neither the name of Freescale Semiconductor nor the
155640 + * names of its contributors may be used to endorse or promote products
155641 + * derived from this software without specific prior written permission.
155642 + *
155643 + *
155644 + * ALTERNATIVELY, this software may be distributed under the terms of the
155645 + * GNU General Public License ("GPL") as published by the Free Software
155646 + * Foundation, either version 2 of that License or (at your option) any
155647 + * later version.
155648 + *
155649 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
155650 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155651 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155652 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
155653 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
155654 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
155655 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
155656 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
155657 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
155658 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155659 + */
155660 +
155661 +/**************************************************************************//**
155662 + @File ioctls.h
155663 +
155664 + @Description Structures and definitions for Command Relay Ioctls
155665 +*//***************************************************************************/
155666 +
155667 +#ifndef __IOCTLS_H__
155668 +#define __IOCTLS_H__
155669 +
155670 +#include <asm/ioctl.h>
155671 +
155672 +#include "integration_ioctls.h"
155673 +
155674 +
155675 +/**************************************************************************//**
155676 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
155677 + @{
155678 +*//***************************************************************************/
155679 +
155680 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
155681 + the NCSW Linux module commands */
155682 +
155683 +
155684 +/**************************************************************************//**
155685 + @Description IOCTL Memory allocation types.
155686 +*//***************************************************************************/
155687 +typedef enum ioc_mem_type {
155688 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
155689 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
155690 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
155691 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
155692 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
155693 +} ioc_mem_type;
155694 +
155695 +/**************************************************************************//**
155696 + @Description Enumeration (bit flags) of communication modes (Transmit,
155697 + receive or both).
155698 +*//***************************************************************************/
155699 +typedef enum ioc_comm_mode {
155700 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
155701 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
155702 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
155703 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
155704 +} ioc_comm_mode;
155705 +
155706 +/**************************************************************************//**
155707 + @Description General Diagnostic Mode
155708 +*//***************************************************************************/
155709 +typedef enum ioc_diag_mode
155710 +{
155711 + e_IOC_DIAG_MODE_NONE = 0,
155712 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
155713 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
155714 + E.g. IO-pins, SerDes, etc. */
155715 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
155716 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
155717 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
155718 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
155719 +} ioc_diag_mode;
155720 +
155721 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
155722 +
155723 +
155724 +#endif /* __IOCTLS_H__ */
155725 --- /dev/null
155726 +++ b/include/uapi/linux/fmd/net_ioctls.h
155727 @@ -0,0 +1,430 @@
155728 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
155729 + * All rights reserved.
155730 + *
155731 + * Redistribution and use in source and binary forms, with or without
155732 + * modification, are permitted provided that the following conditions are met:
155733 + * * Redistributions of source code must retain the above copyright
155734 + * notice, this list of conditions and the following disclaimer.
155735 + * * Redistributions in binary form must reproduce the above copyright
155736 + * notice, this list of conditions and the following disclaimer in the
155737 + * documentation and/or other materials provided with the distribution.
155738 + * * Neither the name of Freescale Semiconductor nor the
155739 + * names of its contributors may be used to endorse or promote products
155740 + * derived from this software without specific prior written permission.
155741 + *
155742 + *
155743 + * ALTERNATIVELY, this software may be distributed under the terms of the
155744 + * GNU General Public License ("GPL") as published by the Free Software
155745 + * Foundation, either version 2 of that License or (at your option) any
155746 + * later version.
155747 + *
155748 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
155749 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155750 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155751 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
155752 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
155753 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
155754 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
155755 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
155756 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
155757 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155758 + */
155759 +
155760 +
155761 +/**************************************************************************//**
155762 + @File net_ioctls.h
155763 +
155764 + @Description This file contains common and general netcomm headers definitions.
155765 +*//***************************************************************************/
155766 +#ifndef __NET_IOCTLS_H
155767 +#define __NET_IOCTLS_H
155768 +
155769 +#include "ioctls.h"
155770 +
155771 +
155772 +typedef uint8_t ioc_header_field_ppp_t;
155773 +
155774 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
155775 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
155776 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
155777 +
155778 +
155779 +typedef uint8_t ioc_header_field_pppoe_t;
155780 +
155781 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
155782 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
155783 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
155784 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
155785 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
155786 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
155787 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
155788 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
155789 +
155790 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
155791 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
155792 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
155793 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
155794 +
155795 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
155796 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
155797 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
155798 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
155799 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
155800 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
155801 +
155802 +
155803 +typedef uint8_t ioc_header_field_eth_t;
155804 +
155805 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
155806 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
155807 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
155808 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
155809 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
155810 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
155811 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
155812 +
155813 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
155814 +
155815 +typedef uint16_t ioc_header_field_ip_t;
155816 +
155817 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
155818 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
155819 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
155820 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
155821 +
155822 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
155823 +
155824 +typedef uint16_t ioc_header_field_ipv4_t;
155825 +
155826 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
155827 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
155828 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
155829 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
155830 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
155831 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
155832 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
155833 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
155834 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
155835 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
155836 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
155837 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
155838 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
155839 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
155840 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
155841 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
155842 +
155843 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
155844 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
155845 +
155846 +
155847 +typedef uint8_t ioc_header_field_ipv6_t;
155848 +
155849 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
155850 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
155851 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
155852 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
155853 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
155854 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
155855 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
155856 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
155857 +
155858 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
155859 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
155860 +
155861 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
155862 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
155863 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
155864 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
155865 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
155866 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
155867 +
155868 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
155869 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
155870 +
155871 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
155872 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
155873 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
155874 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
155875 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
155876 +
155877 +
155878 +typedef uint16_t ioc_header_field_tcp_t;
155879 +
155880 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
155881 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
155882 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
155883 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
155884 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
155885 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
155886 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
155887 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
155888 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
155889 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
155890 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
155891 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
155892 +
155893 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
155894 +
155895 +
155896 +typedef uint8_t ioc_header_field_sctp_t;
155897 +
155898 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
155899 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
155900 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
155901 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
155902 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
155903 +
155904 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
155905 +
155906 +typedef uint8_t ioc_header_field_dccp_t;
155907 +
155908 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
155909 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
155910 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
155911 +
155912 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
155913 +
155914 +
155915 +typedef uint8_t ioc_header_field_udp_t;
155916 +
155917 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
155918 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
155919 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
155920 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
155921 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
155922 +
155923 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
155924 +
155925 +typedef uint8_t ioc_header_field_udp_lite_t;
155926 +
155927 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
155928 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
155929 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
155930 +
155931 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
155932 +
155933 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
155934 +
155935 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
155936 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
155937 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
155938 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
155939 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
155940 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
155941 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
155942 +
155943 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
155944 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
155945 +
155946 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
155947 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
155948 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
155949 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
155950 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
155951 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
155952 +
155953 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
155954 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
155955 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
155956 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
155957 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
155958 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
155959 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
155960 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
155961 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
155962 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
155963 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
155964 +
155965 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
155966 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
155967 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
155968 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
155969 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
155970 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
155971 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
155972 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
155973 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
155974 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
155975 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
155976 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
155977 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
155978 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
155979 +
155980 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
155981 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
155982 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
155983 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
155984 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
155985 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
155986 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
155987 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
155988 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
155989 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
155990 +
155991 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
155992 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
155993 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
155994 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
155995 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
155996 +
155997 +
155998 +typedef uint8_t ioc_header_field_vlan_t;
155999 +
156000 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
156001 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
156002 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
156003 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
156004 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
156005 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
156006 +
156007 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
156008 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
156009 + IOC_NET_HEADER_FIELD_VLAN_VID)
156010 +
156011 +
156012 +typedef uint8_t ioc_header_field_llc_t;
156013 +
156014 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
156015 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
156016 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
156017 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
156018 +
156019 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
156020 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
156021 +
156022 +
156023 +typedef uint8_t ioc_header_field_snap_t;
156024 +
156025 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
156026 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
156027 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
156028 +
156029 +
156030 +typedef uint8_t ioc_header_field_llc_snap_t;
156031 +
156032 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
156033 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
156034 +
156035 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
156036 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
156037 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
156038 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
156039 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
156040 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
156041 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
156042 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
156043 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
156044 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
156045 +
156046 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
156047 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
156048 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
156049 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
156050 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
156051 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
156052 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
156053 +
156054 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
156055 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
156056 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
156057 +
156058 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
156059 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
156060 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
156061 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
156062 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
156063 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
156064 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
156065 +
156066 +
156067 +typedef uint8_t ioc_header_field_gre_t;
156068 +
156069 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
156070 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
156071 +
156072 +
156073 +typedef uint8_t ioc_header_field_minencap_t;
156074 +
156075 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
156076 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
156077 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
156078 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
156079 +
156080 +
156081 +typedef uint8_t ioc_header_field_ipsec_ah_t;
156082 +
156083 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
156084 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
156085 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
156086 +
156087 +
156088 +typedef uint8_t ioc_header_field_ipsec_esp_t;
156089 +
156090 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
156091 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
156092 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
156093 +
156094 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
156095 +
156096 +
156097 +typedef uint8_t ioc_header_field_mpls_t;
156098 +
156099 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
156100 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
156101 +
156102 +
156103 +typedef uint8_t ioc_header_field_macsec_t;
156104 +
156105 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
156106 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
156107 +
156108 +
156109 +typedef enum {
156110 + e_IOC_NET_HEADER_TYPE_NONE = 0,
156111 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
156112 + e_IOC_NET_HEADER_TYPE_ETH,
156113 + e_IOC_NET_HEADER_TYPE_VLAN,
156114 + e_IOC_NET_HEADER_TYPE_IPv4,
156115 + e_IOC_NET_HEADER_TYPE_IPv6,
156116 + e_IOC_NET_HEADER_TYPE_IP,
156117 + e_IOC_NET_HEADER_TYPE_TCP,
156118 + e_IOC_NET_HEADER_TYPE_UDP,
156119 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
156120 + e_IOC_NET_HEADER_TYPE_IPHC,
156121 + e_IOC_NET_HEADER_TYPE_SCTP,
156122 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
156123 + e_IOC_NET_HEADER_TYPE_PPPoE,
156124 + e_IOC_NET_HEADER_TYPE_PPP,
156125 + e_IOC_NET_HEADER_TYPE_PPPMUX,
156126 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
156127 + e_IOC_NET_HEADER_TYPE_L2TPv2,
156128 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
156129 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
156130 + e_IOC_NET_HEADER_TYPE_LLC,
156131 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
156132 + e_IOC_NET_HEADER_TYPE_NLPID,
156133 + e_IOC_NET_HEADER_TYPE_SNAP,
156134 + e_IOC_NET_HEADER_TYPE_MPLS,
156135 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
156136 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
156137 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
156138 + e_IOC_NET_HEADER_TYPE_MACSEC,
156139 + e_IOC_NET_HEADER_TYPE_GRE,
156140 + e_IOC_NET_HEADER_TYPE_MINENCAP,
156141 + e_IOC_NET_HEADER_TYPE_DCCP,
156142 + e_IOC_NET_HEADER_TYPE_ICMP,
156143 + e_IOC_NET_HEADER_TYPE_IGMP,
156144 + e_IOC_NET_HEADER_TYPE_ARP,
156145 + e_IOC_NET_HEADER_TYPE_CAPWAP,
156146 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
156147 + e_IOC_NET_HEADER_TYPE_RFC2684,
156148 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
156149 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
156150 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
156151 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
156152 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
156153 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
156154 +} ioc_net_header_type;
156155 +
156156 +
156157 +#endif /* __NET_IOCTLS_H */
156158 --- a/net/sched/sch_generic.c
156159 +++ b/net/sched/sch_generic.c
156160 @@ -313,6 +313,13 @@ static void dev_watchdog(unsigned long a
156161 txq->trans_timeout++;
156162 break;
156163 }
156164 +
156165 + /* Devices with HW_ACCEL_MQ have multiple txqs
156166 + * but update only the first one's transmission
156167 + * timestamp so avoid checking the rest.
156168 + */
156169 + if (dev->features & NETIF_F_HW_ACCEL_MQ)
156170 + break;
156171 }
156172
156173 if (some_queue_timedout) {